将C函数转换为Perl

时间:2012-12-24 19:55:52

标签: perl binaryfiles

我试图转换程序cng2jpg.c中提到的C函数convertCNGFileToJPGFile时遇到困难

我一直在尝试在Perl中编写相同的内容,但是没有足够的知识来处理hex,pack和unpack函数。

如果有人可以在Perl中编写类似的代码,我将非常感激。如下所述。

while ((bytesRead = fread(buffer, 1, kBufferSize, inputFile))) {
    if (!isValidCNG) {
        if (bytesRead < 11 || strncmp("\xa5\xa9\xa6\xa9", (char *)(buffer + 6), 4)) {
            fprintf(stderr, "%s does not appear to be a valid CNG file\n", inputFileName);
            return 0;
        }
        isValidCNG = 1;
    }
    for (size_t i = 0; i < bytesRead; i++)
        buffer[i] ^= 0xEF;
    size_t bytesWritten = fwrite(buffer, 1, bytesRead, outputFile);
    if (bytesWritten < bytesRead) {
        fprintf(stderr, "Error writing %s\n", outputFileName);
        return 0;
    }
}

提前致谢。

1 个答案:

答案 0 :(得分:5)

如果我正在读取正确的代码,那么它所做的一切(除了有效性检查)是对文件中的每个字节进行异或运算(即翻转每个字节的第五个最低位)。在Perl中,您可以使用以下方法实现:

local $/ = \(2**16);  # ignore line breaks, read in 64 kiB chunks
while (<>) {
    $_ ^= "\xEF" x length;
    print;
}

有效性检查只是检查输出实际上是一个有效的JPEG文件 - 具体来说,输出文件的第7到第10个字节包含魔术字"JFIF"(当XOR时变为"\xa5\xa9\xa6\xa9"用0xEF)。一般情况下,除非您希望经常在不是CNG文件的文件上运行此代码,否则我不会理会它,因为之后更容易检查输出的有效性。 (此外,如果解码后的文件实际上是Exif JPEG图像,则检查将失败,该图像具有神奇的单词"Exif"。)

如果您 想要包含支票,那么应该这样做:

local $/ = \(2**16);  # ignore line breaks, read in 64 kiB chunks
while (<>) {
    $_ ^= "\xEF" x length;
    die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;        
    print;
}

聚苯乙烯。如果这段代码运行得太慢,我建议两种可能的改进:1)使用更大的缓冲区,b)预先分配0xEF字节的掩码,而不是每次都重建它:

local $/ = \(2**20);  # ignore line breaks, read in 1 MiB chunks
my $mask = "\xEF" x $$/;
while (<>) {
    $_ ^= substr($mask, 0, length);
    die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;        
    print;
}