# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com) # The second word of TIFF files is the TIFF version number, 42, which has # never changed. The TIFF specification recommends testing for it. 0 string MM\x00\x2a TIFF image data, big-endian, >4 belong 0 invalid >4 belong <0 invalid # First image directory must begin on an even byte boundary >4 belong &1 invalid >4 belong >10000000 invalid >4 belong x offset of first image directory: %d 0 string II\x2a\x00 TIFF image data, little-endian >4 lelong 0 invalid >4 lelong <0 invalid >4 lelong &1 invalid >4 lelong >10000000 invalid >4 lelong x offset of first image directory: %d # PNG [Portable Network Graphics, or "PNG's Not GIF"] images # (Greg Roelofs, newt@uchicago.edu) # (Albert Cahalan, acahalan@cs.uml.edu) # # 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ... # 0 string \x89PNG\x0d\x0a\x1a\x0a PNG image >16 belong <1 invalid >16 belong >10000 invalid >20 belong <1 invalid >20 belong >10000 invalid >16 belong x \b, %d x >20 belong x %d, >24 byte x %d-bit >25 byte 0 grayscale, >25 byte 2 \b/color RGB, >25 byte 3 colormap, >25 byte 4 gray+alpha, >25 byte 6 \b/color RGBA, #>26 byte 0 deflate/32K, >28 byte 0 non-interlaced >28 byte 1 interlaced # GIF 0 string GIF8 GIF image data >4 string 7a \b, version "8%s", >4 string 9a \b, version "8%s", >6 leshort >0 %d x >8 leshort >0 %d #>10 byte &0x80 color mapped, #>10 byte&0x07 =0x00 2 colors #>10 byte&0x07 =0x01 4 colors #>10 byte&0x07 =0x02 8 colors #>10 byte&0x07 =0x03 16 colors #>10 byte&0x07 =0x04 32 colors #>10 byte&0x07 =0x05 64 colors #>10 byte&0x07 =0x06 128 colors #>10 byte&0x07 =0x07 256 colors # PC bitmaps (OS/2, Windows BMP files) (Greg Roelofs, newt@uchicago.edu) 0 string BM >14 leshort 12 PC bitmap, OS/2 1.x format >>18 lelong <1 invalid >>18 lelong >1000000 invalid >>18 leshort x \b, %d x >>20 lelong <1 invalid >>20 lelong >1000000 invalid >>20 leshort x %d >14 leshort 64 PC bitmap, OS/2 2.x format >>18 lelong <1 invalid >>18 lelong >1000000 invalid >>18 leshort x \b, %d x >>20 lelong <1 invalid >>20 lelong >1000000 invalid >>20 leshort x %d >14 leshort 40 PC bitmap, Windows 3.x format >>18 lelong <1 invalid >>18 lelong >1000000 invalid >>18 lelong x \b, %d x >>22 lelong <1 invalid >>22 lelong >1000000 invalid >>22 lelong x %d x >>28 lelong <1 invalid >>28 lelong >1000000 invalid >>28 leshort x %d >14 leshort 128 PC bitmap, Windows NT/2000 format >>18 lelong >1000000 invalid >>18 lelong <1 invalid >>18 lelong x \b, %d x >>22 lelong <1 invalid >>22 lelong >1000000 invalid >>22 lelong x %d x >>28 lelong <1 invalid >>28 lelong >1000000 invalid >>28 leshort x %d #------------------------------------------------------------------------------ # JPEG images # SunOS 5.5.1 had # # 0 string \377\330\377\340 JPEG file # 0 string \377\330\377\356 JPG file # # both of which turn into "JPEG image data" here. # 0 belong 0xffd8ffe0 JPEG image data, JFIF standard >6 string !JFIF invalid # The following added by Erik Rossen <rossen@freesurf.ch> 1999-09-06 # in a vain attempt to add image size reporting for JFIF. Note that these # tests are not fool-proof since some perfectly valid JPEGs are currently # impossible to specify in magic(4) format. # First, a little JFIF version info: >11 byte x \b %d. >12 byte x \b%02d # Next, the resolution or aspect ratio of the image: #>>13 byte 0 \b, aspect ratio #>>13 byte 1 \b, resolution (DPI) #>>13 byte 2 \b, resolution (DPCM) #>>4 beshort x \b, segment length %d # Next, show thumbnail info, if it exists: >18 byte !0 \b, thumbnail %dx >>19 byte x \b%d 0 belong 0xffd8ffe1 JPEG image data, EXIF standard # EXIF moved down here to avoid reporting a bogus version number, # and EXIF version number printing added. # - Patrik R=E5dman <patrik+file-magic@iki.fi> >6 string !Exif invalid # Look for EXIF IFD offset in IFD 0, and then look for EXIF version tag in EXIF IFD. # All possible combinations of entries have to be enumerated, since no looping # is possible. And both endians are possible... # The combinations included below are from real-world JPEGs. # Little-endian >12 string II # IFD 0 Entry #5: >>70 leshort 0x8769 # EXIF IFD Entry #1: >>>(78.l+14) leshort 0x9000 >>>>(78.l+23) byte x %c >>>>(78.l+24) byte x \b.%c >>>>(78.l+25) byte !0x30 \b%c # IFD 0 Entry #9: >>118 leshort 0x8769 # EXIF IFD Entry #3: >>>(126.l+38) leshort 0x9000 >>>>(126.l+47) byte x %c >>>>(126.l+48) byte x \b.%c >>>>(126.l+49) byte !0x30 \b%c # IFD 0 Entry #10 >>130 leshort 0x8769 # EXIF IFD Entry #3: >>>(138.l+38) leshort 0x9000 >>>>(138.l+47) byte x %c >>>>(138.l+48) byte x \b.%c >>>>(138.l+49) byte !0x30 \b%c # EXIF IFD Entry #4: >>>(138.l+50) leshort 0x9000 >>>>(138.l+59) byte x %c >>>>(138.l+60) byte x \b.%c >>>>(138.l+61) byte !0x30 \b%c # EXIF IFD Entry #5: >>>(138.l+62) leshort 0x9000 >>>>(138.l+71) byte x %c >>>>(138.l+72) byte x \b.%c >>>>(138.l+73) byte !0x30 \b%c # IFD 0 Entry #11 >>142 leshort 0x8769 # EXIF IFD Entry #3: >>>(150.l+38) leshort 0x9000 >>>>(150.l+47) byte x %c >>>>(150.l+48) byte x \b.%c >>>>(150.l+49) byte !0x30 \b%c # EXIF IFD Entry #4: >>>(150.l+50) leshort 0x9000 >>>>(150.l+59) byte x %c >>>>(150.l+60) byte x \b.%c >>>>(150.l+61) byte !0x30 \b%c # EXIF IFD Entry #5: >>>(150.l+62) leshort 0x9000 >>>>(150.l+71) byte x %c >>>>(150.l+72) byte x \b.%c >>>>(150.l+73) byte !0x30 \b%c # Big-endian >12 string MM # IFD 0 Entry #9: >>118 beshort 0x8769 # EXIF IFD Entry #1: >>>(126.L+14) beshort 0x9000 >>>>(126.L+23) byte x %c >>>>(126.L+24) byte x \b.%c >>>>(126.L+25) byte !0x30 \b%c # EXIF IFD Entry #3: >>>(126.L+38) beshort 0x9000 >>>>(126.L+47) byte x %c >>>>(126.L+48) byte x \b.%c >>>>(126.L+49) byte !0x30 \b%c # IFD 0 Entry #10 >>130 beshort 0x8769 # EXIF IFD Entry #3: >>>(138.L+38) beshort 0x9000 >>>>(138.L+47) byte x %c >>>>(138.L+48) byte x \b.%c >>>>(138.L+49) byte !0x30 \b%c # EXIF IFD Entry #5: >>>(138.L+62) beshort 0x9000 >>>>(138.L+71) byte x %c >>>>(138.L+72) byte x \b.%c >>>>(138.L+73) byte !0x30 \b%c # IFD 0 Entry #11 >>142 beshort 0x8769 # EXIF IFD Entry #4: >>>(150.L+50) beshort 0x9000 >>>>(150.L+59) byte x %c >>>>(150.L+60) byte x \b.%c >>>>(150.L+61) byte !0x30 \b%c # Here things get sticky. We can do ONE MORE marker segment with # indirect addressing, and that's all. It would be great if we could # do pointer arithemetic like in an assembler language. Christos? # And if there was some sort of looping construct to do searches, plus a few # named accumulators, it would be even more effective... # At least we can show a comment if no other segments got inserted before: >(4.S+5) byte 0xFE >>(4.S+8) string >\0 \b, comment: "%s" # FIXME: When we can do non-byte counted strings, we can use that to get # the string's count, and fix Debian bug #283760 #>(4.S+5) byte 0xFE \b, comment #>>(4.S+6) beshort x \b length=%d #>>(4.S+8) string >\0 \b, "%s" # Or, we can show the encoding type (I've included only the three most common) # and image dimensions if we are lucky and the SOFn (image segment) is here: >(4.S+5) byte 0xC0 \b, baseline >>(4.S+6) byte x \b, precision %d >>(4.S+7) beshort x \b, %dx >>(4.S+9) beshort x \b%d >(4.S+5) byte 0xC1 \b, extended sequential >>(4.S+6) byte x \b, precision %d >>(4.S+7) beshort x \b, %dx >>(4.S+9) beshort x \b%d >(4.S+5) byte 0xC2 \b, progressive >>(4.S+6) byte x \b, precision %d >>(4.S+7) beshort x \b, %dx >>(4.S+9) beshort x \b%d # I've commented-out quantisation table reporting. I doubt anyone cares yet. #>(4.S+5) byte 0xDB \b, quantisation table #>>(4.S+6) beshort x \b length=%d #>14 beshort x \b, %d x #>16 beshort x \b %d 0 string M88888888888888888888888888 Binwalk logo, ASCII art (Toph){offset-adjust:-50} >27 string !8888888888\n invalid