2010-09-06 336 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標記。