我试图转换程序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;
}
}
提前致谢。
答案 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;
}