Menu

Problems using jpeg_mem_dest

Anonymous
2012-02-01
2012-10-03
  • Anonymous

    Anonymous - 2012-02-01

    Hi,
    I use libjpeg-turbo in my project and noticed some problems with using
    jpeg_mem_dest. Am I doing something wrong here? THX.

    Small image 640x480 compression in loop as examples used in 4 different ways.

    example 1: works but leaks

    while( 1 )
    {
        jpeg_compress_struct m_sCompress = {0};
        jpeg_error_mgr m_sError = {0};
    
        m_sCompress.err = jpeg_std_error(&m_sError);
    
        m_sCompress.image_width = pBMPInfoHeader->biWidth;
        m_sCompress.image_height = pBMPInfoHeader->biHeight;
        m_sCompress.input_components = pBMPInfoHeader->biBitCount / 8;
        m_sCompress.in_color_space = JCS_EXT_BGR;
    
        unsigned char* pCompressed = 0;
        unsigned long lSize = 0;
    
        jpeg_mem_dest( &m_sCompress, &pCompressed, &lSize );
    
        jpeg_set_defaults( &m_sCompress );
    
        jpeg_set_quality( &m_sCompress, 100, FALSE );
    
        jpeg_start_compress( &m_sCompress, TRUE );
    
        JSAMPROW pRow[1];
        DWORD dwRowSize = img_size( m_sCompress.image_width, 1, m_sCompress.input_components, 4 );
    
        while (m_sCompress.next_scanline < m_sCompress.image_height) 
        {
            pRow[0] = & pData[ ( m_sCompress.image_height - m_sCompress.next_scanline - 1 ) * dwRowSize];
    
            jpeg_write_scanlines(&m_sCompress, pRow, 1);
        }
    
        jpeg_finish_compress(&m_sCompress);
    
            SaveCompressed( pCompressed, lSize);
    
        jpeg_destroy_compress(&m_sCompress);
    } //while(1)
    

    example 2: works but leaks

    jpeg_compress_struct m_sCompress = {0};
    jpeg_error_mgr m_sError = {0};
    
    m_sCompress.err = jpeg_std_error(&m_sError);
    
    m_sCompress.image_width = pBMPInfoHeader->biWidth;
    m_sCompress.image_height = pBMPInfoHeader->biHeight;
    m_sCompress.input_components = pBMPInfoHeader->biBitCount / 8;
    m_sCompress.in_color_space = JCS_EXT_BGR;
    
    unsigned char* pCompressed = 0;
    unsigned long lSize = 0;
    
    while( 1 )
    {
        jpeg_mem_dest( &m_sCompress, &pCompressed, &lSize );
    
        jpeg_set_defaults( &m_sCompress );
    
        jpeg_set_quality( &m_sCompress, 100, FALSE );
    
        jpeg_start_compress( &m_sCompress, TRUE );
    
        JSAMPROW pRow[1];
        DWORD dwRowSize = img_size( m_sCompress.image_width, 1, m_sCompress.input_components, 4 );
    
        while (m_sCompress.next_scanline < m_sCompress.image_height) 
        {
            pRow[0] = & pData[ ( m_sCompress.image_height - m_sCompress.next_scanline - 1 ) * dwRowSize];
    
            jpeg_write_scanlines(&m_sCompress, pRow, 1);
        }
    
        jpeg_finish_compress(&m_sCompress);
    
            SaveCompressed( pCompressed, lSize);
    } //while(1)
    
    jpeg_destroy_compress(&m_sCompress);
    

    example 3: works like append -> BAD

    jpeg_compress_struct m_sCompress = {0};
    jpeg_error_mgr m_sError = {0};
    
    m_sCompress.err = jpeg_std_error(&m_sError);
    
    m_sCompress.image_width = pBMPInfoHeader->biWidth;
    m_sCompress.image_height = pBMPInfoHeader->biHeight;
    m_sCompress.input_components = pBMPInfoHeader->biBitCount / 8;
    m_sCompress.in_color_space = JCS_EXT_BGR;
    
    unsigned char* pCompressed = 0;
    unsigned long lSize = 0;
    
    jpeg_mem_dest( &m_sCompress, &pCompressed, &lSize );
    
    jpeg_set_defaults( &m_sCompress );
    
    jpeg_set_quality( &m_sCompress, 100, FALSE );
    
    while( 1 )
    {
        jpeg_start_compress( &m_sCompress, TRUE );
    
        JSAMPROW pRow[1];
        DWORD dwRowSize = img_size( m_sCompress.image_width, 1, m_sCompress.input_components, 4 );
    
        while (m_sCompress.next_scanline < m_sCompress.image_height) 
        {
            pRow[0] = & pData[ ( m_sCompress.image_height - m_sCompress.next_scanline - 1 ) * dwRowSize];
    
            jpeg_write_scanlines(&m_sCompress, pRow, 1);
        }
    
        jpeg_finish_compress(&m_sCompress);
    
            SaveCompressed( pCompressed, lSize);
    } //while(1)
    
    jpeg_destroy_compress(&m_sCompress);
    

    example 4: seems OK, no leak

    jpeg_compress_struct m_sCompress = {0};
    jpeg_error_mgr m_sError = {0};
    
    m_sCompress.err = jpeg_std_error(&m_sError);
    
    m_sCompress.image_width = pBMPInfoHeader->biWidth;
    m_sCompress.image_height = pBMPInfoHeader->biHeight;
    m_sCompress.input_components = pBMPInfoHeader->biBitCount / 8;
    m_sCompress.in_color_space = JCS_EXT_BGR;
    
    unsigned char* pCompressed = new BYTE[1000000];
    unsigned long lSize = 1000000;
    
    while( 1 )
    {
        lSize = 1000000;
        jpeg_mem_dest( &m_sCompress, &pCompressed, &lSize );
    
        jpeg_set_defaults( &m_sCompress );
    
        jpeg_set_quality( &m_sCompress, 100, FALSE );
    
        jpeg_start_compress( &m_sCompress, TRUE );
    
        JSAMPROW pRow[1];
        DWORD dwRowSize = img_size( m_sCompress.image_width, 1, m_sCompress.input_components, 4 );
    
        while (m_sCompress.next_scanline < m_sCompress.image_height) 
        {
            pRow[0] = & pData[ ( m_sCompress.image_height - m_sCompress.next_scanline - 1 ) * dwRowSize];
    
            jpeg_write_scanlines(&m_sCompress, pRow, 1);
        }
    
        jpeg_finish_compress(&m_sCompress);
    
            SaveCompressed( pCompressed, lSize);
    } //while(1)
    
    jpeg_destroy_compress(&m_sCompress);
    
     
  • DRC

    DRC - 2012-02-03

    We borrow tj_mem_dest() from jpeg-8 and don't make any local modifications to
    it, so I suspect this is not a library error, but I don't have time to pore
    through your code and figure out what it might be. valgrind is your friend.

     
  • Anonymous

    Anonymous - 2012-03-02

    I case that someone is interested, my working solution is:
    per frame:

    ...
    //reset output memdest
    m_sCompress.dest->free_in_buffer += m_sCompress.dest->next_output_byte - m_pCompressed;
    m_sCompress.dest->next_output_byte = m_pCompressed;
    
    //start frame compression
    jpeg_start_compress( &m_sCompress, TRUE );
    ...
    

    m_pCompressed was initially set only once during initialization

    ...
    m_pCompressed = NULL;
    m_lSize = 0;
    jpeg_mem_dest( &m_sCompress, &m_pCompressed, &m_lSize );
    ...