From: Duane H. H. <dh...@an...> - 2002-08-03 19:53:22
|
I just joined the list, and found the following in the archives. >> Is it possible to use libexif to access the exif information embedded in tiff >> files? I`ve figured out that the offset to the exif info is stored in tiff >> tag 0x8769, but I`m still figuring out how to get libexif to read that >> information, so any hints would be greatly appreciated. >> >> Thanks, >> >> Paul Nolan, CEO Idruna Software Inc. >> http://www.idruna.com It *is* possible, and actually fairly easy. I'd love to see "libexif" support it, and I can offer a few words which may help. See below. <ASIDE> It's important to state up front that I'm not an "expert" in image file formats; nonetheless, ever since I bought my Nikon 990 about a year and a half ago, I've been dragging down every (open-source) software distribution I could find that claims to deal with EXIF, and poring over the TIFF, JPEG and EXIF specs trying to understand the incestuous relation between them. I do have software (in addition to "libexif") that allows me to manipulate Exif/Jpeg images (preserving the Exif information) but none of the distributions so far seem to recognize that the EXIF spec also covers the uncompressed TIFF format files produced by some cameras at the highest quality setting...probably because few of us are eager to chew up nearly 10MB/pix on our flash cards (or whatever). The point of this lengthy aside is that it would be *very* nice if "libexif" included support for reading (and *writing*) the Exif information in TIFF files, and *then* distributions like PHP, ImageMagick, etc. used this common interface. What follows is my current understanding of how to access Exif information in TIFF files. I've used this to locally modify the "epinfo" program included in the "photopc" distribution (Crosser/Bowen) to access Exif information in TIFF files from my camera. A knowledgeable "libexif" developer should be able to munge "libexif" in a very short time. </ASIDE> Here's the deal. The existing routines in "libexif" should read TIFF files jes' fine...you just have to start sooner. It may be necessary to recognize additional TIFF tags (I'm not up to speed on "libexif" yet). I'm not entirely sure how to explain this, so please bear with me. When reading an EXIF/Jpeg file, you read a JPEG SOI (2 bytes), followed by an APP1 header (10 bytes). The APP1 begins with a TIFF header, followed by two IFDS. The first IFD contains an entry which points to an EXIF IFD. If the file is TIFF format, the first 12 bytes aren't there. The file starts with the TIFF header, including the offset to the first IFD (which usually follows immediately, but might not). Reading the IFDs is exactly the same. The TIFF IFD0 will contain some TIFF markers (e.g. ImageWidth, ImageLength, Compression, etc.) which won't be found in the JPEG IFD0, but that's not a problem if the reader is prepared to recognize all valid TIFF markers. At the same time, The EXIF IFD in the TIFF file will not include markers for information already included in IFD0 (e.g PixelXdimension won't be given because the information has already been included as ImageWidth). This won't be a problem for the library, but will need to be handled at the application level for programs (like ImageMagick) that want to do image format conversions. That's it. Just recognize that the file starts with the TIFF header and proceed normally. There are additional TIFF tags which should be recognized as described in the EXIF spec (2.6.4 "TIFF Rev 6.0 Attribute Information", page 21). The actual format is described in the spec starting on page 11, section 2.5.2 "Basic Structure of Uncompressed RGB data". The following page includes a nice figure showing the structure of an entire file. For completeness, there is one other item which should be dealt with. One tag included in TIFF files is the 'Compression' tag. The TIFF6 spec permits 3 values for this ('1' for uncompressed, 2 for "Modifed Huffman RLE compression", and 32773 for "Packbits RLE compression"). The JPEG spec include a value ('6') for "JPEG compressed thumbnail" (no tag for main image), and the TIFF_EP spec includes a value ('7') for JPEG (baseline) compressed primary image (that's a TIFF file with the image data in JPEG compressed format). There's some confusion in my mind about what "libexif" intends to support, and how it should interface with "libtiff" and "libjepg", so if I'm boring you with details, sorry (I think what I'd really like to see is a "libjpextif" that handles every TIFF, JPEG and EXIF tag ever invented). At the risk of boring you further, and requiring that this message be divided into several volumes, I'm going to include some output from a small program I've been using to try to understand the structure of jpeg/tiff/exif files of various sorts. If you are able to interpret them, they may make the difference between reading Exif from a jpeg format file and from a tiff format file clearer. First, here's the start of an EXIF/JPEG file: (The lines are longer than 80 characters, so beware of line wrap.) @0000000=00000000: JPEG SOI 0xffd8 @0000002=0x000002: <JPEG_APP1> length 14405, "Exif" @0000012=0x00000c: TIFF(II) 0x4949 0x42 (ifd offset = 0000008=0x0008) @0000020=0x000014: <IFD0 > 11 entries (at offset 0000022=0x000016) @0000022=0x000016: <0x010e= 270> [ImageDescription ] 0x2=ASCII 11 @158 @0000034=0x000022: <0x010f= 271> [Make ] 0x2=ASCII 6 @190 @0000046=0x00002e: <0x0110= 272> [Model ] 0x2=ASCII 5 @214 @0000058=0x00003a: <0x0112= 274> [Orientation ] 0x3=SHORT 1 =1 @0000070=0x000046: <0x011a= 282> [XResolution ] 0x5=RATIONAL 1 @228 @0000082=0x000052: <0x011b= 283> [YResolution ] 0x5=RATIONAL 1 @236 @0000094=0x00005e: <0x0128= 296> [ResolutionUnit ] 0x3=SHORT 1 =2 @0000106=0x00006a: <0x0131= 305> [Software ] 0x2=ASCII 9 @244 @0000118=0x000076: <0x0132= 306> [DateTime ] 0x2=ASCII 20 @276 @0000130=0x000082: <0x0213= 531> [YcbCrPositioning ] 0x3=SHORT 1 =2 @0000142=0x00008e: <0x8769=34665> [Exif IFD Pointer ] 0x4=LONG 1 =284 @0000158=0x00009e: ============= VALUES, IFD0 ============ @0000158=0x00009e: ImageDescription: @0000190=0x0000be: Make: NIKON @0000214=0x0000d6: Model: E990 @0000228=0x0000e4: XResolution: 300/1 @0000236=0x0000ec: YResolution: 300/1 @0000244=0x0000f4: Software: E990v1.0 @0000276=0x000114: DateTime: 2002:06:20 12:13:26 @00296=0x0128: <EXIF IFD > 24 entries (at offset 284) @00298=0x012a: <0x829a=33434> [ExposureTime ] 0x5=RATIONAL 1 @590 @00310=0x0136: <0x829d=33437> [FNumber ] 0x5=RATIONAL 1 @598 . . . etc. Now a similar portion of an EXIF/TIFF file @0000000=00000000: TIFF(II) 0x4949 0x42 (ifd offset = 0000008=0x0008) @0000008=0x000008: <IFD0 > 19 entries (at offset 0000010=0x00000a) @0000010=0x00000a: <0x0100= 256> [ImageWidth ] 0x4=LONG 1 =2048 @0000022=0x000016: <0x0101= 257> [ImageLength ] 0x4=LONG 1 =1536 @0000034=0x000022: <0x0102= 258> [BitsPerSample ] 0x3=SHORT 3 @242 @0000046=0x00002e: <0x0103= 259> [Compression ] 0x3=SHORT 1 =1 @0000058=0x00003a: <0x0106= 262> [PhotometricInterpretation] 0x3=SHORT 1 =2 @0000070=0x000046: <0x010e= 270> [ImageDescription ] 0x2=ASCII 11 @248 @0000082=0x000052: <0x010f= 271> [Make ] 0x2=ASCII 6 @280 @0000094=0x00005e: <0x0110= 272> [Model ] 0x2=ASCII 5 @304 @0000106=0x00006a: <0x0111= 273> [StripOffsets ] 0x4=LONG 192 @1322 @0000118=0x000076: <0x0112= 274> [Orientation ] 0x3=SHORT 1 =1 @0000130=0x000082: <0x0115= 277> [SamplesPerPixel ] 0x3=SHORT 1 =3 @0000142=0x00008e: <0x0116= 278> [RowsPerStrip ] 0x4=LONG 1 =8 @0000154=0x00009a: <0x0117= 279> [StripByteCounts ] 0x4=LONG 192 @2090 @0000166=0x0000a6: <0x011a= 282> [XResolution ] 0x5=RATIONAL 1 @318 @0000178=0x0000b2: <0x011b= 283> [YResolution ] 0x5=RATIONAL 1 @326 @0000190=0x0000be: <0x0128= 296> [ResolutionUnit ] 0x3=SHORT 1 =2 @0000202=0x0000ca: <0x0131= 305> [Software ] 0x2=ASCII 9 @334 @0000214=0x0000d6: <0x0132= 306> [DateTime ] 0x2=ASCII 20 @366 @0000226=0x0000e2: <0x8769=34665> [Exif IFD Pointer ] 0x4=LONG 1 =386 @0000242=0x0000f2: ============= VALUES, IFD0 ============ @0000242=0x0000f2: BitsPerSample: 8,8,8 @0000248=0x0000f8: ImageDescription: @0000280=0x000118: Make: NIKON @0000304=0x000130: Model: E990 @0001322=0x00052a: StripOffsets: 72009,121161,170313,... -> 2090 @0002090=0x00082a: StripByteCounts: 49152,49152,49152,... -> 2858 @0000318=0x00013e: XResolution: 300/1 @0000326=0x000146: YResolution: 300/1 @0000334=0x00014e: Software: E990v1.0 @0000366=0x00016e: DateTime: 2001:03:30 17:16:29 @00386=0x0182: <EXIF IFD > 19 entries (at offset 386) @00388=0x0184: <0x829a=33434> [ExposureTime ] 0x5=RATIONAL 1 @620 @00400=0x0190: <0x829d=33437> [FNumber ] 0x5=RATIONAL 1 @628 . . . etc. Hint: the first column is offset from beginning of file in decimal=hex. ----------- dhh @ androcles.com |