检测是否PNG文件在Objective C的破坏(Detect if PNG file is cor

2019-06-24 08:57发布

我使用的NSURLRequest下载JPG和PNG格式。 这工作正常,但有时文件已损坏。 我已经看到了追赶的错误:腐败JPEG数据:数据段的提前结束 ,并已此工作的JPG文件。 有谁知道的方式做了PNG图像一样吗? 即通过编程检查PNG数据是有效的?

Answer 1:

PNG格式有一些内置的检查。 每一“块”有CRC32检查,但检查你需要阅读完整的文件。

一个更基本的检查(并非万无一失,当然)将读取的启动和文件的结尾。

前8个字节应始终是以下(十进制)值{ 137, 80, 78, 71, 13, 10, 26, 10 } REF )。 具体地,第二字节到第四对应于ASCII字符串“PNG”。

在十六进制:

89 50 4e 47 0d 0a 1a 0a
.. P  N  G  ...........

您还可以查看过去的12个字节的文件(IEND块)的。 中间的4个字节应该对应于ASCII字符串“IEND”。 更具体地,最后的12个字节应(在六):

00 00 00 00 49 45 4e 44 ae 42 60 82
........... I  E  N  D  ...........

(严格来说,它不是一个真正强制性的PNG文件与那些12个字节结束时,IEND块本身信号的PNG流的末等文件原则上可以有额外的尾随字节,这将是由PNG读者忽略。在实践中,这是极不可能的)。



Answer 2:

就像在追赶错误:腐败JPEG数据:数据段的过早结束这里是PNG代码片段:

- (BOOL)dataIsValidPNG:(NSData *)data
{
    if (!data || data.length < 12)
    {
        return NO;
    }

    NSInteger totalBytes = data.length;
    const char *bytes = (const char *)[data bytes];

    return (bytes[0] == (char)0x89 && // PNG
            bytes[1] == (char)0x50 &&
            bytes[2] == (char)0x4e &&
            bytes[3] == (char)0x47 &&
            bytes[4] == (char)0x0d &&
            bytes[5] == (char)0x0a &&
            bytes[6] == (char)0x1a &&
            bytes[7] == (char)0x0a &&

            bytes[totalBytes - 12] == (char)0x00 && // IEND
            bytes[totalBytes - 11] == (char)0x00 &&
            bytes[totalBytes - 10] == (char)0x00 &&
            bytes[totalBytes - 9] == (char)0x00 &&
            bytes[totalBytes - 8] == (char)0x49 &&
            bytes[totalBytes - 7] == (char)0x45 &&
            bytes[totalBytes - 6] == (char)0x4e &&
            bytes[totalBytes - 5] == (char)0x44 &&
            bytes[totalBytes - 4] == (char)0xae &&
            bytes[totalBytes - 3] == (char)0x42 &&
            bytes[totalBytes - 2] == (char)0x60 &&
            bytes[totalBytes - 1] == (char)0x82);
}


Answer 3:

dataIsValidPNG的更好的版本:

BOOL dataIsValidPNG(NSData *data) {

    if (!data) {
        return NO;
    }

    const NSInteger totalBytes = data.length;
    const char *bytes = (const char *)[data bytes];
    const char start[] = { '\x89',  'P',  'N',  'G', '\r', '\n', '\x1a', '\n' };
    const char end[]   = {   '\0', '\0', '\0', '\0',  'I',  'E',    'N',  'D', '\xAE', 'B', '`', '\x82' };

    if (totalBytes < (sizeof(start) + sizeof(end))) {
        return NO;
    }

    return (memcmp(bytes, start, sizeof(start)) == 0) &&
           (memcmp(bytes + (totalBytes - sizeof(end)), end, sizeof(end)) == 0);
}


文章来源: Detect if PNG file is corrupted in Objective C