2010-09-06 338 views
1

我正在使用shell脚本将MPO立体3D图像转换为标准JPEG图像。 MPO文件只是两个JPEG图像连接在一起。因此,您可以通过查找第二个JPEG的幻数标头(0xFFD8FFE1)的字节偏移来分割JPEG文件。我使用hexdump/xxd,grep,head和tail手动完成了这项工作。在二进制分隔符上分割一个二进制文件?

这里的问题是grep:我可以用什么来直接搜索一个特定的幻数的二进制文件,并得到一个字节偏移?或者我应该不使用shell脚本?谢谢。

+0

根据记录,这些文件是由富士FinePix REAL 3D W3相机生产。 – drinian 2010-09-07 14:09:54

+1

另外,看起来左镜头图像首先出现在MPO文件中。 – drinian 2010-09-26 10:45:19

回答

0

我认为一个非常简单的家庭酿造方法将是你最好的选择。这样做的代码将非常小,具体取决于二进制文件格式的所有特殊情况。

  1. 使用mmap可以方便地查看内存中的文件。
  2. 开始扫描,并将字节偏移保存在一个变量中,比如start
  3. 扫描直到到达分隔符,保存结束偏移量,例如end
  4. 创建一个新的文件
  5. 内存映射的新文件
  6. 复制字节范围从startend到新文件。
  7. 关闭新文件并重新开始扫描。
7

为此,您可以使用BBE(http://bbe-.sourceforge.net/),这是一个sed像程序二进制文件:

为了提取第一JPEG用途:

bbe -b '/\xFF\xD8\xFF\xE1/:' -e 'D 2' -o first_jpeg mpo_file 

而对于第二个:

bbe -b '/\xFF\xD8\xFF\xE1/:' -e 'D 1' -o second_jpeg mpo_file 

请注意,如果JPEG的幻数出现在MPO文件的其他位置,这将不起作用。

+0

感谢您将bbe引入我的注意!顺便说一句,你的Sourceforge链接被破坏,而bbe.sf.net是一个不同的项目。 – drinian 2010-09-07 14:09:11

3

我认为巴特是你最大的问题..如果这个二进制序列在这个过程中重复,你会得到部分JPEG。

我做了一个快速测试通过连接一些JPEG文件,然后使用awk提取它们(请注意,神奇的数字在我的文件,结束了在取0xE0而不是0xE1):

# for i in *.jpg ; do cat $i ; done > test.mpo 
    # awk 'BEGIN {RS="\xFF\xD8\xFF\xE0"; FILENUM=-1} {FILENUM++; if (FILENUM == 0) {next}; FILENAME="image0"FILENUM".jpg"; printf "%s",RS$0 > FILENAME;}' test.mpo 
    # file image0*.jpg 
    image01.jpg: JPEG image data, JFIF standard 1.01 
    image010.jpg: JPEG image data, JFIF standard 1.01 
    image011.jpg: JPEG image data, JFIF standard 1.01 

这似乎工作确定为我,但上述问题仍然没有处理和非常真实。

+0

我猜想0xE1中的幻数表示它是序列中的第二个图像,并且您永远不会有超过2个图像。根据需要调整。 =) – phreakocious 2010-09-07 03:16:58

+0

我不确定,因为我也在文件的开头看到0xE1。 – drinian 2010-09-07 11:54:51

+0

我给你的答案检查是因为awk在每个Unix系统上都可用(它提醒我需要了解更多信息:)。我的shell脚本目前正在对image03.jpg或缺少image02.jpg和中止做一些基本检查,这有助于处理幻数问题。我也可以做一些检查EXIF标题。不幸的是,我只知道一个程序可以在本地读取这些文件 - 富士Windows应用程序 - 尽管维基百科声称Digikam支持MPO。将不得不看他们的来源,和我的相机的文件。现在,这很好。 – drinian 2010-09-07 14:05:12

0

FFE1不是某个jpeg“幻数”的一部分,它是APP1标记。并不能保证在SOI标记FFD8之后。此外,您应该小心,某些jpeg图像将缩略图jpeg嵌入到EXIF块中。这很可能也会包含APP1标记。