zoukankan      html  css  js  c++  java
  • 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解压损坏文件时的错误处理

  • 相关阅读:
    CF961E Tufurama 主席树
    [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
    [BZOJ5294][BJOI2018]二进制(线段树)
    [BZOJ5293][BJOI2018]求和(倍增)
    [BZOJ5306][HAOI2018]染色(容斥+FFT)
    [BZOJ5303][HAOI2018]反色游戏(Tarjan)
    [CF1053C]Putting Boxes Together(线段树)
    整体二分
    JSOI2018R2题解
    LCT维护子树信息
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/3998425.html
Copyright © 2011-2022 走看看