【问题标题】:png_read_image access violation?png_read_image 访问冲突?
【发布时间】:2015-04-23 11:18:14
【问题描述】:

我在调用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 之前已成功调用过。 我无法弄清楚我做错了什么。文档没有说明该函数有什么有趣的地方,所以它不应该太复杂。

【问题讨论】:

  • 因为&_pixels是指针的地址,即指向指针的指针,所以它相当于一个png_bytep row_pointers[1](只有1个指针)而不是预期的png_bytep row_pointers[height] .

标签: c++ png libpng


【解决方案1】:

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

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

因此,您可以使用以下方法创建行指针数组:

_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]; 所做的那样

【讨论】:

  • 你能解释一下那行吗? _row_pointer[i] = _pixels + i*bytesPerRow;
  • 我看到了你的编辑。还是那条线:_pixels 与这些有什么关系?在那之前,_pixels 是一个未初始化的字节指针。
  • 更正:_pixels 是指向未分配字节数组的指针。
  • @Pilpel 希望这个最新的更新能澄清你关于_pixels的问题
【解决方案2】:

调用 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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-06
    • 2013-02-26
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    相关资源
    最近更新 更多