libjpeg的問題


游戲項目是基於cocos2d-x開發的,但線上發現一個bug就是玩家在設置完自定義頭像后直接閃退。凡是在設置該玩家頭像的地方,游戲就直接閃退。最終定位到的問題是圖片數據源有問題,我的機器是win7,圖片能預覽,但同事xp系統該圖片是無法預覽的,默認的系統自帶的圖片查看工具也無法顯示圖片。

把圖片拉到sublime text中,查看文件二進制,發現它並非一個完整的jpeg格式

image

沒有jpeg格式的結束標識0xff  0xd9

 

我在windows下調試代碼,發現是在CCImageCommon_cpp.h中的_initWithJpgData方法調用jpeg_finish_decompress函數時程序直接退出了

bool CCImage::_initWithJpgData(void * data, int nSize, bool bNeedDecode /*= false*/)
{
    int nRandomBytes = 0;
    if (bNeedDecode) nRandomBytes = RANDOM_BYTES;

    if (bNeedDecode)
    {
        data = (unsigned char *)data + nRandomBytes;
        nSize = nSize - nRandomBytes;
    }

    /* these are standard libjpeg structures for reading(decompression) */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    /* libjpeg data structure for storing one row, that is, scanline of an image */
    JSAMPROW row_pointer[1] = {0};
    unsigned long location = 0;
    unsigned int i = 0;

    bool bRet = false;
    do 
    {
        /* here we set up the standard libjpeg error handler */
        cinfo.err = jpeg_std_error( &jerr );

        /* setup decompression process and source, then read JPEG header */
        jpeg_create_decompress( &cinfo );

        jpeg_mem_src( &cinfo, (unsigned char *) data, nSize );

        /* reading the image header which contains image information */
        jpeg_read_header( &cinfo, true );

        // we only support RGB or grayscale
        if (cinfo.jpeg_color_space != JCS_RGB)
        {
            if (cinfo.jpeg_color_space == JCS_GRAYSCALE || cinfo.jpeg_color_space == JCS_YCbCr)
            {
                cinfo.out_color_space = JCS_RGB;
            }
        }
        else
        {
            break;
        }

        /* Start decompression jpeg here */
        jpeg_start_decompress( &cinfo );

        /* init image info */
        m_nWidth  = (short)(cinfo.image_width);
        m_nHeight = (short)(cinfo.image_height);
        m_bHasAlpha = false;
        m_bPreMulti = false;
        m_nBitsPerComponent = 8;
        row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.output_components];
        CC_BREAK_IF(! row_pointer[0]);

        m_pData = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components];
        CC_BREAK_IF(! m_pData);

        /* now actually read the jpeg into the raw buffer */
        /* read one scan line at a time */
        while( cinfo.output_scanline < cinfo.image_height )
        {
            jpeg_read_scanlines( &cinfo, row_pointer, 1 );
            for( i=0; i<cinfo.image_width*cinfo.output_components;i++)
            {
                m_pData[location++] = row_pointer[0][i];
            }
        }

        jpeg_finish_decompress( &cinfo );
        jpeg_destroy_decompress( &cinfo );
        /* wrap up decompression, destroy objects, free pointers and close open files */       
        bRet = true;
    } while (0);

    CC_SAFE_DELETE_ARRAY(row_pointer[0]);
    return bRet;
}

后面我用jpegtran(https://github.com/imagemin/jpegtran-bin)工具復制有問題的圖片時, 也提示錯誤了

image

 

參考文章:

[1] 小議libjpeg解壓損壞文件時的錯誤處理

[2] JPEG File Layout and Format

解決方案可以參考這篇文章:libjpeg解壓損壞文件時的錯誤處理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM