【问题标题】:PNG chunk reader, invalid lengthPNG块读取器,无效长度
【发布时间】:2012-05-13 14:47:16
【问题描述】:

我目前正在编写自己的 png 阅读器,我正在阅读单个块,它似乎正确读取了前 2 个块,但是当涉及到 IDAT 块的大小很可笑。

bool LoadImage(char * path, Image * target)
{
std::ifstream file;

file.open("Lenna.png", std::ios::in | std::ios::binary);
if(!file.is_open())
    return -false;

std::cout << "Opened file : Lenna.png" <<  std::endl;
struct stat filestatus;
if (stat("Lenna.png", &filestatus) != 0)
    return false;

unsigned int fileSize = filestatus.st_size;
unsigned int bytesRead = 8;
file.seekg(8, std::ios::beg);

while(bytesRead < fileSize)
{
    //Read the length, type, then the data and at last the crc(Cyclic redundancy crap, whatever that may be)
    char length [4];
    file.read(length, 4);
    //Reverse the 4 bytes due to network type writing.
    unsigned int dataLength = (length[0] << 24) | (length[1] << 16) | (length[2] << 8) | length[3];
    char type [4];
    file.read(type, 4);
    char * data = new char[dataLength];
    file.read(data, dataLength);
    char crc [4];
    file.read(crc, 4);
    bytesRead += 12 + dataLength;
}

return true;
}

使用调试器将前 2 个块读取为

类型:IDHR
长度:13 字节

类型:sRGB
长度:1 字节

类型:IDAT
长度:4294967201 字节

这大约是 2.3 GB 的数据,而 png 是 462 kb。任何想法为什么会出错?

源图片:http://i.cubeupload.com/sCHXFV.png

【问题讨论】:

  • 文件中对应字节的值是多少?
  • 这里是十六进制编辑器中初始值的屏幕截图。 i.cubeupload.com/YiruKg.png
  • 请将该十六进制转储的文本内容粘贴到您的问题中。
  • 很抱歉,当我尝试粘贴十六进制代码时,它会不断将它们转换为 ascii,但我确实上传了实际的源图像。
  • 有什么理由不使用现有的 png 库?

标签: c++ png corrupt


【解决方案1】:

问题在于字节顺序的反转和左移。移位运算结果的符号与被移位值的符号相同。因此,转移已签名的 char 的行为会与您的预期不同。

要解决此问题,请将 length 数组的类型更改为 unsigned char

【讨论】:

    【解决方案2】:

    您需要声明长度unsigned char,因此字节值 >= 128 的符号扩展不会字节。这就是你最终得到 0xffffffa1 的方式,你对负值进行了或运算。

    【讨论】:

      猜你喜欢
      • 2014-04-20
      • 2019-07-17
      • 1970-01-01
      • 2021-12-09
      • 2018-02-04
      • 1970-01-01
      • 2012-11-24
      • 2020-03-05
      • 1970-01-01
      相关资源
      最近更新 更多