【问题标题】:libpng error invalid chunk type when loading png from memory从内存加载 png 时,libpng 错误无效的块类型
【发布时间】:2014-04-29 23:15:15
【问题描述】:

我正在尝试从内存缓冲区加载 PNG,以便无需先将其保存为文件即可访问 ImageData。

内存缓冲区包含一个有效的 png 文件,当使用 fwrite 将其保存为磁盘上的文件时,我得到以下图像:https://dl.dropboxusercontent.com/u/13077624/test.png

这表示 Kinect 传感器接收到的深度图像,对于那些想知道的人。

这是给出错误的代码:

struct mem_encode
{
    char *buffer;
    png_uint_32 size;
    png_uint_32 current_pos;
};

void handle_data(const boost::system::error_code& error,
    size_t bytes_transferred)
{
    if (!error)
    {
        cout<<"Saving as file: "<<determinePathExtension(PNGFrame,"png");
        FILE* fp=fopen("test.png","wb");
        fwrite(data_,bytes_transferred,1,fp);
        fclose(fp);
        //get PNG file info struct (memory is allocated by libpng)
        png_structp png_ptr = NULL;
        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (!png_ptr) {

             std::cerr << "ERROR: Couldn't initialize png read struct" << std::endl;
             cin.get();
            return; //Do your own error recovery/handling here
        }
        // get PNG image data info struct (memory is allocated by libpng)
        png_infop info_ptr = NULL;
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr) {
         std::cerr << "ERROR: Couldn't initialize png info struct" << std::endl;
         cin.get();
         png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
         return; //Do your own error recovery/handling here
        }

        struct mem_encode pngdata;
        pngdata.buffer=data_;

        pngdata.size=(png_uint_32)bytes_transferred;
        pngdata.current_pos=0;
        png_set_read_fn(png_ptr,&pngdata, ReadData);
        //Start reading the png header
        png_set_sig_bytes(png_ptr, 8);
        png_read_info(png_ptr,info_ptr);
        //... Program crashes here
    }
    else
    {
        cout<<error.message()<<" Bytes received: "<<bytes_transferred<<endl;
        delete this;
    }
}


static void ReadData(png_structp png_ptr, png_bytep outBytes,
    png_size_t byteCountToRead){
        struct mem_encode* p=(struct mem_encode*)png_get_io_ptr(png_ptr);
        size_t nsize=p->size + byteCountToRead;

        if(byteCountToRead>(p->size-p->current_pos)) png_error(png_ptr,"read error in read_data_memory (loadpng)");

        /* copy new bytes */
        memcpy(outBytes,p->buffer + p->size,byteCountToRead);
        p->current_pos+=byteCountToRead;
}

调用该方法导致程序崩溃并出现以下错误:

libpng error: [00][00][00][00]: invalid chunk type

data_ 表示存储 PNG 图像的数据缓冲区,是一个 char *。 任何帮助将不胜感激。

我使用的来源:

这可能是由于网络字节翻译不当造成的吗?

【问题讨论】:

    标签: c++ buffer libpng


    【解决方案1】:

    我想你忘了阅读 PNG 签名字节。使用

    if (png_sig_cmp(data, 0, 8)
       png_error(png_ptr, "it's not a PNG file");
    

    那么你的

    png_set_sig_bytes(png_ptr,8);
    

    让 libpng 知道您已经阅读了签名。

    或者,您可以使用 png_set_sig_bytes(png_ptr, 0); 和 让 libpng 为你做检查。

    【讨论】:

    • 其实我自己也是这么想的,但是没用。但它确实返回了 0,因此数据缓冲区包含一个有效的 PNG。我目前已经放弃了 PNG 解压缩并返回到 JPEG 解压缩。解决这个问题会很好,但它不再是首要任务。
    【解决方案2】:

    你确定你的ReadData 函数是正确的吗?为什么要从地址p-&gt;buffer + p-&gt;size 开始memcpy - 这不是缓冲区的结尾吗? nsize 是做什么的?

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 2016-02-24
      • 2017-11-17
      相关资源
      最近更新 更多