我试图转换程序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;
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
如果我正在读取正确的代码,那么它所做的一切(除了有效性检查)是对文件中的每个字节进行异或运算(即翻转每个字节的第五个最低位).在Perl中,您可以使用以下方法实现:
local $/ = \(2**16); # ignore line breaks, read in 64 kiB chunks
while (<>) {
$_ ^= "\xEF" x length;
print;
}
Run Code Online (Sandbox Code Playgroud)
有效性检查只是检查输出实际上是一个有效的JPEG文件 - 具体来说,输出文件的第7到第10个字节包含魔术字"JFIF"("\xa5\xa9\xa6\xa9"当与0xEF进行异或时变为).一般情况下,除非您希望经常在不是CNG文件的文件上运行此代码,否则我不会理会它,因为之后更容易检查输出的有效性.(此外,如果解码后的文件实际上是Exif JPEG图像,那么检查将会失败,而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;
}
Run Code Online (Sandbox Code Playgroud)
PS.如果这段代码运行得太慢,我建议两种可能的改进: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;
}
Run Code Online (Sandbox Code Playgroud)