Bug 415460 - JFIF files have APP0 marker after SOI where there should be APP1
Summary: JFIF files have APP0 marker after SOI where there should be APP1
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Plugin-Generic-SendByMail (show other bugs)
Version: 5.9.0
Platform: Debian stable Linux
: NOR normal
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-12-22 18:42 UTC by Anselm Lingnau
Modified: 2019-12-26 08:26 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In: 7.0.0
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Anselm Lingnau 2019-12-22 18:42:58 UTC
SUMMARY

When Digikam writes resized JFIF files to be sent by e-mail, the resulting files have a JPEG APP0 marker (starting with `ff e0 0010 4a 46 49 46 00 …’ immediately after the SOI marker (ff d8). This breaks programs like jpegexiforient which expect the APP1 marker (with EXIF data) immediately after the SOI marker, as the EXIF standard stipulates.


STEPS TO REPRODUCE
1. Use the “Send by Mail” feature of Digikam to create an e-mail message containing a JFIF attachment.
2. Save that attachment to a file.
3. Inspect the file with a hex-dump editor.

OBSERVED RESULT

Bytes 3 and 4 of the file are FF E0.

EXPECTED RESULT

Bytes 3 and 4 of the file should be FF E1 (and the EXIF data should follow these bytes as per the EXIF standard).


SOFTWARE/OS VERSIONS
Windows: 
macOS: 
Linux/KDE Plasma: 5.9.0
(available in About System)
KDE Plasma Version: as in Debian 10.1
KDE Frameworks Version: as in Debian 10.1
Qt Version: as in Debian 10.1

ADDITIONAL INFORMATION
Comment 1 caulier.gilles 2019-12-22 19:48:47 UTC
Please try with last stable 6.4.0 Linux AppImage bundle which use last Exiv2 shared lib in background to play with files metadata.

Gilles Caulier
Comment 2 Maik Qualmann 2019-12-22 21:34:15 UTC
ff d8 ff e0 == JPEG/JFIF
ff d8 ff e1 == JPEG/Exif

from Exiv2 doc:

JPEG/Exif is the most common image format used by digital cameras and other photographic image capture devices.

JPEG/JFIF is the most common format for storing and transmitting photographic images on the World Wide Web.

A quick test here shows that both Gimp and Krita save also ff d8 ff e0 (JPEG/JFIF).

Maik
Comment 3 Maik Qualmann 2019-12-22 21:54:56 UTC
There also seems to be a patch to jpegexiforient from you. I also see the error in jpegexiforient.

https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1717258.html

Maik
Comment 4 Anselm Lingnau 2019-12-23 00:56:25 UTC
Well, the EXIF standard (http://cipa.jp/std/documents/download_e.html?DC-008-Translation-2019-E) says, in section 4.5.4, “Basic Structure of JPEG Compressed Data”: “Compressed data files shall be recorded in conformance with the JPEG DCT format specified in ISO/IEC 10918-1, with the Application Marker Segment (APP1) inserted. APP1 shall be recorded immediately after the SOI marker indicating the beginning of the file”. This means that according to the standard, a file that has an APP0 (JFIF) marker segment immediately after the SOI marker and the APP1 segment after the APP0 segment is in error.

I would suggest that Digikam should either omit the EXIF information altogether when it writes JFIF (ff d8 ff e0) files for inclusion in e-mail, or else do it like it says in the relevant standard, i.e., leave out the APP0 marker segment and write only an APP1 segment with EXIF data.

I wrote a patch for jpegexiforient, but the jpeg-turbo guy said he wasn't going to take it because it would encourage sloppy implementations of the standard. I can see where he's coming from, but I'd also like this problem fixed. I'd much rather not see this devolve into a game of finger-pointing where everyone says the mistake is on the other side.
Comment 5 Anselm Lingnau 2019-12-23 01:12:28 UTC
Incidentally, I just tried the 6.4.0 Linux appimage and it exhibits the same problem. On top of that it won't even start kmail on my system but that's probably a different issue.
Comment 6 caulier.gilles 2019-12-23 05:01:19 UTC
Anselm,

As i already said, digiKam source code do not touch directly JDIF structure. It delegate the job to Exiv2 library. I recommend to report this UPSTREAM problem on Exiv2 bugzilla located in GitHub:

https://github.com/Exiv2/exiv2/issues

Thanks in advance

Gilles Caulier
Comment 7 Maik Qualmann 2019-12-23 07:05:13 UTC
Well, I don't know if the problem is with Exiv2. If I deactivate Exiv2 and only save a JPG with libjpeg, ff d8 ff e0 is generated. I don't see a switch for it at libjpeg or at Exiv2 at the moment.

Maik
Comment 8 Maik Qualmann 2019-12-23 08:27:24 UTC
If I see it correctly, your document from http://cipa.jp describes the standard for digital still cameras and not for JPEG.

I think this document is for the JPEG file format:
https://www.w3.org/Graphics/JPEG/jfif3.pdf

And here is a good overview of the use of other APPX segments:
https://github.com/corkami/formats/blob/master/image/jpeg.md

The program jpegexiforient can only process images directly from digital cameras.

Maik
Comment 9 Anselm Lingnau 2019-12-23 14:59:32 UTC
I've looked into this some more and it seems to get even worse.

When I import a portrait-orientation image into Digikam from my digital camera, Digikam turns it upright for display according to the Exif orientation flag, but the actual file is unchanged (as can be seen when opening such a file in The GIMP, which offers to turn it according to its Exif orientation). This is fine.

If I export the same image as an e-mail attachment using the Digikam e-mail plugin, it is actually physically turned upright (i.e., if you inspect the temporary image file with “file” it says it is, e.g., “768x1024”, but according to “exiv2” it keeps its original Exif orientation flag. This means that programs like “jpegexiforient”, which insist that the Exif data must come immediately after the SOI and disregard it if it occurs elsewhere in the file, do nothing, which is appropriate as the image has already been rotated by Digikam. OTOH, programs like Gwenview or The GIMP, which are apparently more tolerant (i.e., non-compliant with the Exif standard) when it comes to finding Exif tags in an image file, will turn the image *again* because they react to the erroneous Exif orientation flag written by Digikam. This is clearly wrong.

(As a funny side observation, if you use Gwenview to turn the file upright again, save it, and re-open it in Gwenview you will find that it is now actually turned too far, because Gwenview will alter both the image data and the Exif orientation flag. In The GIMP this is less of an issue as the program will prompt you to approve or deny the Exif-based rotation when it opens the file.)

All of this suggests to me that you should either make sure that the Exif info ends up where it belongs according to the Exif standard (so programs like “jpegexiforient” and “Gwenview” will behave the same) or else omit the Exif info from the exported attachments altogether so programs like “Gwenview” and The GIMP, which implement the Exif standard incorrectly, don't get confused. In any case Digikam should stop writing files that conform neither to the JFIF standard (because they include erroneous Exif data not specified by the JFIF standard) nor the Exif standard (because the Exif data is in the wrong place according to the Exif standard).

At the very least you should ensure that the Exif orientation flag that is erroneously included in the wrong place in the attachment file so only non-compliant software will find it to begin with, agrees with the actual orientation of the data in the file, so the non-compliant software doesn't get confused by it.

(For the record, I did all these experiments using the 6.4.0 appimage version of Digikam.)
Comment 10 Maik Qualmann 2019-12-25 19:33:45 UTC
I just stumbled across this interesting site because Exiv2 referred to it. For me, jpegexiforient is faulty because it only wants to process APP1.

From: https://www.codeproject.com/Articles/43665/ExifLibrary-for-NET
---
JPEG ("Joint Photographic Experts Group") is the committee that created the JPEG standard. It is also the name of the compression method (the codec) defined by the JPEG committee. JPEG is not a file format. (Actually, there is a "pure" file format – JPEG Interchange Format, JIF – described in the original JPEG specification. But it is rarely used.) The most widely used file formats containing JPEG compression are JFIF (JPEG File Interchange Format) and Exif (Exchangeable Image File Format). In everyday use, JPEG usually means a JFIF or an Exif image file.

The difference between JFIF and Exif file formats is that JFIF files use Application Marker 0 (APP0) sections to store metadata, whereas Exif files use Application Marker 1 (APP1) sections. The two file formats are incompatible because they both specify that their sections (APP0 and APP1) must be the first in the image file. In practice, however, Exif files usually include an APP0 section at the start of the image file. This does not comply with the Exif standard, but allows old JFIF readers to read the image file.

A modern JFIF or Exif reader must not assume a particular order for APPn sections. It should read the entire file and process APPn sections as it encounters them. Additionally, APPn sections might not be unique. For example, there might be more than one APP1 section in a JPEG/Exif file.
----

Maik
Comment 11 Anselm Lingnau 2019-12-26 00:54:39 UTC
That's nice but is not what the current Exif standard document says. As long as we don't have an actual standards-level document that says that the APP1 section doesn't have to come immediately after the SOI, the libjpeg-turbo people are unlikely to budge (and they're technically correct, which as we all know is the best kind of correct). They are opposed to the “robustness principle”, which the idea of deliberately writing a file that doesn't conform to the standard in order to accommodate “old JFIF readers” is all about, and it is not an unreasonable position to take if you're a purist rather than a pragmatist, and believe that bugs should be fixed in the software that actually has the bug, rather than worked around elsewhere.

In any case you should fix the broken Exif orientation marker in the exported attachment image files, because that's wrong no matter what the situation is about APP0 and APP1, and it bites especially those people with software that DOES look for APP1 in places other than immediately after the SOI. Getting that right would solve much of the original problem already.
Comment 12 Maik Qualmann 2019-12-26 08:26:24 UTC
Git commit 338776981b62d5e587221577478898816a233d16 by Maik Qualmann.
Committed on 26/12/2019 at 08:23.
Pushed by mqualmann into branch 'master'.

set Exif orientation to normal because DImg was loaded aligned
FIXED-IN: 7.0.0

M  +2    -1    NEWS
M  +17   -11   core/dplugins/generic/tools/sendbymail/manager/imageresizejob.cpp

https://invent.kde.org/kde/digikam/commit/338776981b62d5e587221577478898816a233d16