代码之家  ›  专栏  ›  技术社区  ›  McLovin

png_read_image访问冲突?

  •  2
  • McLovin  · 技术社区  · 10 年前

    我一直在 Access violation writing location 0x.... 调用时出错 png_read_image 。这是我的代码

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

    请注意 png_read_info 已成功调用。 我想不出我做错了什么。文档中没有提到该函数的任何有趣之处,因此它不应该太复杂。

    2 回复  |  直到 10 年前
        1
  •  2
  •   SleuthEye    10 年前

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

    现在你仍然可以使用相同的 _pixels 作为保存数据的缓冲区,但必须提供 _row_pointers 指令的数组 png_read_image(读取图像) 其中行在该缓冲区中。假设您希望按行顺序存储数据 _像素 缓冲区,每行将从 bytesPerRow 与前一个不同,或 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 = new unsigned char[bytesPerRow * _height];

        2
  •  1
  •   Glenn Randers-Pehrson    7 年前

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