png_read_image访问冲突

png_read_image access violation?

本文关键字:访问冲突 image read png      更新时间:2023-10-16

我在调用png_read_image时不断收到Access violation writing location 0x....错误。这是我的代码

unsigned int bytesPerRow = png_get_rowbytes(_pngPtr, _pngInfoPtr);
_pixels = new unsigned char[bytesPerRow * _height];
png_read_image(_pngPtr, &_pixels);

请注意,png_read_info以前已被成功调用。我不明白我做错了什么。文档中没有任何关于该函数的有趣内容,所以它不应该太复杂。

png_read_image需要一个行指针数组,而不是指向原始数据缓冲区的指针。换句话说,每行必须有一个这样的指针。

现在,您仍然可以使用相同的_pixels作为保存数据的缓冲区,但必须提供一个_row_pointers数组,该数组指示png_read_image行在该缓冲区中的位置。假设您想在_pixels缓冲区内按行顺序存储数据,则每一行都将从上一行的bytesPerRow地址开始,或从_pixels缓冲区开始的i*bytesPerRow地址开始。

因此,您可以使用创建行指针数组

_row_pointers = new png_bytep[_height];
for (int i=0; i<_height; i++)
{
  _row_pointers[i] = _pixels + i*bytesPerRow;
}
png_read_image(_pngPtr, _row_pointers);

其中_pixels已被分配为连续内存块,就像您对_pixels = new unsigned char[bytesPerRow * _height]; 所做的那样

调用png_set_something()后,再调用png_read_update_info(),然后调用bytesPerRow=png_get_rowbytes()。

如果您在png_get_IHDR()之后立即调用png_get_rowbytes(),然后在此之后设置任何转换,则您的bytesPerRow可能太小,并且会发生访问冲突。

2017年7月3日编辑:我刚刚将此修订版推送到libpng文档(libpng.3,libpng-manual.txt):

    rowbytes       - number of bytes needed to hold a row
+                     This value, the bit_depth, color_type,
+                     and the number of channels can change
+                     if you use transforms such as
+                     png_set_expand(). See
+                     png_read_update_info(), below.