libpng错误:PNG无符号整数超出范围

Coo*_*eak 6 c++ libpng

当我尝试从内存中读取PNG时,我遇到了这个时髦的错误:

libpng error:: PNG unsigned integer out of range
Run Code Online (Sandbox Code Playgroud)

此错误是由

png_read_info(png_ptr,info_ptr);
Run Code Online (Sandbox Code Playgroud)

哪个使用以下处理程序

static void ReadDataFromBuffer(png_structp png_ptr, png_bytep outBytes,
    png_size_t byteCountToRead){
        PNGDataPtr dataptr=(PNGDataPtr)png_get_io_ptr(png_ptr);
        png_uint_32 i;
        cout<<byteCountToRead<<endl;
        cout<<&outBytes<<endl;
        cout<<dataptr->len<<endl;
        cout<<dataptr->p<<endl;

        if(byteCountToRead>dataptr->len){
            png_error(png_ptr,"EOF");
            return;
        }

        for(i=0;i<byteCountToRead;i++){

            outBytes[i]=dataptr->p[i];
        }
        dataptr->p+=byteCountToRead;
        dataptr->len-=byteCountToRead;
        png_uint_32 a = png_get_uint_32(outBytes);
        cout<<a<<" "<<PNG_UINT_31_MAX<<endl;

}
Run Code Online (Sandbox Code Playgroud)

通过一些密集的搜索,我发现错误由pgnrutil.c中的以下代码调用:

png_uint_32 /* PRIVATE */
png_get_uint_31(png_structp png_ptr, png_bytep buf)
{
    png_uint_32 i = png_get_uint_32(buf);
    if (i > PNG_UINT_31_MAX)
    png_error(png_ptr, "PNG unsigned integer out of range.\n");
    return (i);
}
Run Code Online (Sandbox Code Playgroud)

所以我检查了png_get_uint_32(outBytes)的值,​​确实高于PNG_UINT_31_MAX,230374511.

我该如何解决?

编辑:

关于PNGDataPtr的一些说明:

typedef struct{
    png_bytep p;
    png_uint_32 len;
} PNGData,*PNGDataPtr;
Run Code Online (Sandbox Code Playgroud)

打电话的时候

png_set_read_fn(png_ptr,(png_voidp) &pngdata, ReadDataFromBuffer);
Run Code Online (Sandbox Code Playgroud)

pngdata表示一个PNGData对象,它有一个指向我的databuffer的指针,它包含内存中的整个PNG,len包含整个PNG的大小,介于40到80KB之间

编辑:这是我使用fwrite保存收到的数据缓冲区时获得的png的链接:https://www.dropbox.com/s/m5enp9jljglhs5c/test.png

Gle*_*son 5

之前我写道:您可能已经混淆了您的字节序条件......

编辑:
当您应该跳过前 8 个字节时,您正在阅读 PNG 签名。你的报告有一个错字:这个数字实际上是 2303741511(你在你的问题中省略了一个“1”)它是字节串“\211 PN G”

代码中此问题的解决方法是使用

png_set_sig_bytes(png_ptr,0)
Run Code Online (Sandbox Code Playgroud)

通知 libpng 您的数据指针指向 8 字节签名的开头,读者需要跳过它们。