7

I'm working on a photo viewer. In this context, I wrote a small class to be able to read and use some EXIF data, as e.g. image orientation. This class works well for reading.

However, I want to add a new option to rotate photos. I want to rotate and write the photo data itself, not just rewrite the orientation tag. I already wrote the code to rotate and save the primary JPEG image, and it works well. But I also need to rotate the thumbnail contained in the EXIF data, if any, to keep the image coherent. For this reason I need to write in the EXIF data, to replace the existing thumbnail.

But this raises some questions, that I've some trouble answering, namely:

  • Can the EXIF data contain more than 1 thumbnail, and if yes, what is the maximum thumbnail count that an image can contain?
  • What are the supported formats for thumbnails? (I found JPEG and TIFF, are there others?)
  • Is there any guarantee in the EXIF standards that the thumbnails are always written in the late EXIF data, just before the primary image?
  • If not, then each tags containing an offset that points to a location beyond the thumbnail to replace should be updated. So, is there a standard way to iterate through all tags and sub-directories, to recognize which EXIF tags contain offsets, and to update them if needed? Or is the only way to read a number maximum of tags and rewrite only the ones that are known?
  • Or is there a way to guarantee that the size of the newly rotated thumbnail will be smaller or equal to previous thumbnail size to replace with?
hippietrail
  • 15,848
  • 18
  • 99
  • 158
Jean-Milost Reymond
  • 1,833
  • 1
  • 15
  • 36

1 Answers1

11

Here are some answers for your questions:

1) The EXIF data is laid out like a TIFF file with 2 pages. The first page is the camera information and the second page is the thumbnail. If you add more pages (with thumbnails), 99.99% of the applications probably won't notice since you'll be doing it differently than the "standard" way. As far as "maximum count", you have 64k of data that can be stored in any JFIF tag. You can put what you want in that 64k.

2) There is only 1 supported EXIF thumbnail format: TIFF. Inside the TIFF there can be compressed (JPEG) or uncompressed data. Again, you're welcome to stick LZW-compressed data in there, but most apps probably won't be prepared to display it properly.

3) The JFIF container format allows for tags with metadata to appear before the main image. The APPx tags contain metadata that can follow the standard or not. You're welcome to stick multiple EXIF APP1 tags into your files, but again, most apps won't be able to properly handle that situation. So the simple answer is that the EXIF data (including thumbnail) must come before the main image and if you put more than 1 thumbnail it will most likely be ignored.

4) If you are modifying a JFIF (including the metadata), you must rewrite the metadata. It's actually quite simple because each tag is independent and has a simple length value instead of relative offsets.

5) You can do anything you want with the size/orientation of your thumbnail as long as you make the EXIF APP1 tag data total size fit within 64k.

Here's what you need to do...

1) Read the source image (and thumbnail if present).
2) Prepare your rotated image (and thumbnail).
3) Write the new metadata with the new thumbnail image.
4) Write the new main image.

If you want to preserve the original metadata along with your new thumbnail, it's pretty easy. Just read the original tags and hold on to them, then write them in the new image. Each JFIF tag is just a 2 byte identifier (FFxx) followed by a 2 byte length and then the data. They can be packed in almost any order and there's no hard limit on how many total tags can appear before the main image.

BitBank
  • 8,500
  • 3
  • 28
  • 46
  • 1
    See also: http://www.exif.org/Exif2-2.PDF Note that according to the spec, the first APPn marker must be the APP1/Exif marker. Although it's common to have the first APPn being the APP0/JFIF marker for compatibility with JFIF. There can only be one APP1/Exif marker, and only one thumbnail (in IFD1). The thumbnail can be uncompressed (RGB or YCbCr) or JPEG (though I've never seen an uncompressed YCbCr thumbnail), not LZW or other. And strictly, the container format is JIF (not JFIF), but that's nitpicking. Otherwise, great answer. :-) – Harald K Sep 11 '15 at 08:22
  • 2
    @haraldK thanks for the doc link. My point about mentioning LZW was that he wants to do something outside of the standard, so if he's not going to follow the standard, he's free to put any type of data he wants. – BitBank Sep 11 '15 at 10:01