2011-03-23 3 views
5

저는 테스트를 거친 몇 가지 JPEG 이미지가 있습니다. 지금까지 내가 본 0 번째 바이트와 첫 번째 바이트는 항상 0xFF0xD8입니다.JPEG 이미지의 두 번째 및 세 번째 바이트는 항상 APP0 또는 APP1 마커입니까?

두 번째와 세 번째가 통상 EXIF ​​세그먼트를 나타내는 JFIF 세그먼트 또는 JFIF 확장 세그먼트 또는 0xFF0xE1 (APP1) 중 어느 하나를 지시하고 0xFF0xE0 (APP0).

내 질문 : 항상이 경우입니까? 두 번째 및 세 번째 바이트는 항상 APP0 또는 APP1입니까?

+1

이것은 언어에 상관되지 않는 질문이므로 * javascript * 및 * c * 태그가 필요하지 않습니다. –

+0

감사합니다 Andy ... 이것이 JavaScript에서 수행되고 있다는 자랑거리입니다. – KeatsKelleher

+0

heh, 걱정하지 마세요. * FileSystemObject *를 사용하여 처음 몇 바이트에서 zip 파일을 만들었습니다. 전체 JPEG 파일을 만들기위한 소품 :-) –

답변

9

No. 이 마커가없는 JPEG 또는 다른 APP 마커가있는 여러 카메라 당신이 의지 할 수있는 유일한 것은 SOI 시퀀스, FF D8입니다. EOI조차도 모든 카메라에서 생성되지 않습니다. 또한 JPEG가 내장 된 JPEG가 있음을 알아 두십시오. 이미지 내에 중첩 된 SOI/EOI를 가질 수 있습니다.

원시 카메라 이미지에 포함 된 JPEG 데이터를 처리해야하는 경우 여러 모델에서 JPEG 형식의 데이터가 생성됩니다. JPEG 형식의 데이터가 생성됩니다. 특히 데이터의 경우 FF 바이트와 관련하여 jpeg 사양과 약간의 차이가있을 수 있습니다. 언뜻보기에 jpeg 데이터 (예 : Sony의 "암호화 된"원시 형식 중 일부)처럼 보이는 독점 데이터를 생성하는 카메라가 있습니다.

+1

사이드 노트 : 샘플 JPEG의 99 % 이상 (다양한 카메라에서 가져옴)에 * APP0/APP1이 있습니다 - 언급하지 않은 예외는 공통적이며 일반 파서에서 다루지 않아도됩니다. – Erik

+2

한 번에 하나의 세그먼트를 읽도록 프로그램 할 수있을 때 데이터를 예상하기 위해 파서에 하드 코딩해야하는 이유가 정말로 없습니다. 헤더를 기반으로 처리합니다. – mgiuca

1

처음 두 바이트는 JPEG SOI 마커이므로 항상 존재합니다.

두 번째 및 세 번째 바이트는 모든 JPEG에없는 메타 데이터를 저장하는 것으로 보입니다.

Further Reading.

+0

오른쪽, SOI 마커가 항상있을 것입니다 ...이 질문은 APP0 및 APP1 마커에 관한 것입니다. 모든 경우에 나는 그들이 다음에 오는 것을 보았습니다. 나는 이것이 반드시 필요한 경우인지 또는 단지 대개의 경우인지 궁금합니다. – KeatsKelleher

+0

@akellehe 답변을 업데이트했습니다. 어떤 이미지를 시도 했습니까? 한 세트 또는 여러 소스에서 모두? – alex

+0

다른 버전의 Exif 표준 (JFIF도 있음)을 사용하여 검증 된 여러 출처의 출처입니다. 여기에 있습니다 : http://exif.org/samples.html – KeatsKelleher

2

아니요, 확실히 그런 식일 필요는 없습니다. 독서 Wikipedia.

내가 알 수있는 한 APPn 세그먼트는 응용 프로그램이 이미지 파일에 임의의 데이터를 포함시키는 방법 일뿐입니다. 분명히 응용 프로그램은 일반적으로이 기능을 활용하여 헤더에 0xFF 0xEO 또는 0xFF 0xE1 바이트를 기록하지만 응용 프로그램에서는 이 아니고이 아닌 경우 이미지 데이터를 계속 사용하는 것이 좋습니다. 처음 두 바이트 (0xFF 및 0xD8) 이며 SOI (이미지 시작) 마커입니다.

1

일반적으로 JPEG를 이해하는 것은 모든 세그먼트 유형이 헤더를 따를 수 있다는 것입니다.

0

JFIF 파일의 경우 JFIF 헤더 은 FFD8 직후에이어야합니다. JFIF 헤더는 APP0 마커에 포함됩니다. 사양은 패딩에 대해서는 아무 말도하지 않습니다.

JFIF 헤더가 없으면 우리는 어떤 색 형식이 사용되는지를 추측 할 수 있습니다.

0

이론상으로 그렇습니다. JFIF spec(pdf)에 따르면 APP0 섹션이 먼저 파일에 있어야합니다. 그리고 Exif spec(pdf)은 APP1 섹션에도 동일하게 적용됩니다.

하지만 APPN 섹션의 순서 (또는 심지어 존재 여부)는 고려하지 않아야합니다. 저기 미친 JPEG 작가가 있습니다. SOI로 시작하여 섹션을 읽어보십시오.

1

아니요 일부 마커를 제거하는 프로그램이 있습니다. ImageOptim은 그런 프로그램입니다. 마커 중 일부만 필요합니다. 이 프로그램은 또한 호프만 테이블을 최적화합니다.

1

상황이 복잡합니다. 현재 자바 스크립트 파일 식별자를 작성하고 있기 때문에 JPEG 용 자바 스크립트 객체를 사용하여 답변하려고 노력할 것입니다. 특히 질문에 "javascript"태그가 있기 때문에 .

기본 답변은 이미 제공되었지만 (허용됨) 다른 앱 마커 (폴백 포함)를 확인하는 방법에 대해 자세히 설명되어 있습니다.

지금까지 JFIF, EXIF, Adobe, Canon 및 Samsung (그러나 우리는 미래에 대해 모른다)을위한 특별한 APP0가 있습니다. 따라서 js 객체의 논리는 다음과 같습니다.

SPECS [x] .regex 중 하나가 일치하면 첫 번째 승리가됩니다. 그러나 일치하는 것이 없으면 상위 개체 (FFd8 만)가 승리합니다.

사양 개체는 PRONOM 식별자 따라 제공합니다 - 당신이 그렇게

'http://apps.nationalarchives.gov.uk/pronom/fmt/'.concat (PUID) [공식] 'http://apps.nationalarchives.gov.uk/pronom/x-fmt/'.concat (xPUID) [실험]

처럼 그들을 볼 수 있습니다
_FFD8: { 
    SPECS: [ 
     { 
      PUID: 112, 
      regex: /^FFD8FFE8(.{2})53504946460001/, 
      desc: 'jpeg: Still Picture Interchange Format file (SPIF)', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       version: '1.00' 
      } 
     }, 
     { 
      PUID: 44, 
      regex: /^FFD8FFE0(.{2})4A464946000102/, 
      desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.02', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       version: '1.02', 
      } 
     }, 
     { 
      PUID: 43, 
      regex: /^FFD8FFE0(.{2})4A464946000101/, 
      desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.01', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       version: '1.01', 
      } 
     }, 
     { 
      PUID: 42, 
      regex: /^FFD8FFE0(.{2})4A464946000100/, 
      desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.00', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       version: '1.00', 
      } 
     },   
     { 
      PUID: 41, 
      xPUID: 398, 
      regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323030/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.0', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'little', 
       version: '2.0', 
      } 
     }, 
     { 
      PUID: 41, 
      xPUID: 398, 
      regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323030/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.0', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'big', 
       version: '2.0', 
      } 
     },    
     { 
      PUID: 41, 
      xPUID: 390, 
      regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323130/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.1', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'little', 
       version: '2.1', 
      } 
     }, 
     { 
      PUID: 41, 
      xPUID: 390, 
      regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323130/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.1', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'big', 
       version: '2.1', 
      } 
     },   
     { 
      PUID: 41, 
      xPUID: 391, 
      regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323230/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.2', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'little', 
       version: '2.2', 
      } 
     }, 
     { 
      PUID: 41, 
      xPUID: 391, 
      regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323230/, 
      desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.2', 
      regexCapture: [ 
       { key: 'recordedSignature' }, 
       { key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } } 
      ], 
      valueCapture: { 
       endian: 'big', 
       version: '2.2', 
      } 
     }, 
     // specific JPEG (all begin with FFD8FF, map them to PUID 41) 
     { 
      PUID: 41, 
      regex: /^FFD8FFED/, 
      desc: 'jpeg: JPG Image File, Adobe JPEG, Photoshop CMYK buffer' 
     }, 
     { 
      PUID: 41, 
      regex: /^FFD8FFE2/, 
      desc: 'jpeg: JPG Image File, Canon JPEG, Canon EOS-1D' 
     }, 
     { 
      PUID: 41, 
      regex: /^FFD8FFE3/, 
      desc: 'jpeg: JPG Image File, Samsung JPEG, e.g. Samsung D500' 
     }, 
     { 
      PUID: 41, 
      regex: /^FFD8FFDB/, 
      desc: 'jpeg: JPG Image File, Samsung JPEG, e.g. Samsung D807' 
     } 
    ], 
    ext: ['JPG', 'JPE', 'JPEG', 'SPF', 'SPIFF'], 
    signature: [ 255, 216 ], 
    desc: 'jpeg: JPEG File Interchange Format file, App0 marker not known', 
    mime: 'image/jpeg', 
    specifications: [ 
     { text:'Specification for the JFIF file format', href:'http://www.w3.org/Graphics/JPEG/jfif3.pdf', type:'W3', format:'pdf' }, 
     { text:'The JPEG compression specification', href:'http://www.w3.org/Graphics/JPEG/itu-t81.pdf', type:'W3', format:'pdf' }, 
     { text:'Exchangeable image file format for digital still cameras', href:'http://home.jeita.or.jp/tsc/std-pdf/CP3451C.pdf', type:'vendor', format:'pdf' } 
    ], 
    references: [ 
     { text:'JPEG JFIF W3 Info', href:'http://www.w3.org/Graphics/JPEG/', type:'W3', format:'html' }, 
     { text:'JPEG.org', href:'http://www.jpeg.org/', type:'info', format:'html' }, 
     { text:'JPEG Exif App markers', href:'http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html', type:'info', format:'html'} 
    ] 
} 
+0

좋은 답변입니다. 전체 파일 서명/매직 바이트 주제는 정말 모호합니다. 저 슨리스트는 어디서 났어? 내가 게시 한 링크에는 표시되지 않습니다. –

관련 문제