mozilla / mozjpeg

Improved JPEG encoder.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

turbojpeg transformer does not copy exif data (false report)

avisecag opened this issue · comments

I am very sorry, after chasing after things for some more time, it turns out that for some reason, the browser plugin I'm using for viewing exif data is having a hard time reading it from the recompressed files, but pretty much all other readers work without issue. In other words, the exif data is actually there, I just couldn't see it in that particular viewer.

In case you were wondering, the viewer in question is exif viewer extension for firefox: https://addons.mozilla.org/en-US/firefox/addon/exif-viewer/
It's a bit inconsistent. For some images it appears load the data fairly well, for some it takes an unusually long time to load the data, and for some it just doesn't seem to appear. No clue what's going on there, but certainly not your problem, since other exif viewers I tried in the meantime all seem to work well.

I'm leaving the original post here just for completness sake:

No longer relevant

I'm using mozjpeg from java through the turbojpg library. Everything seems to be working quite splendidly, except when using TJTransformer for lossless compression, the exif data is gone (when using TJDecompressor and TJCompressor too, obviously, but there it's very much expected).

There may be a misunderstanding on my part and it isn't actually intended to copy the exif data, but I've taken a look around the source code and from what little I could make out, it would suggest that the exif is supposed to be coppied.

In the jpegtan documentation, it says:

    -copy all       Copy all extra markers.  This setting preserves
                    miscellaneous markers found in the source file, such
                    as JFIF thumbnails, __Exif data__, and Photoshop settings.
                    In some files, these extra markers can be sizable.
                    Note that this option will copy thumbnails as-is;
                    they will not be transformed.

While the copy options as such are not available in turbojpeg except for OPT_COPYNONE, the code would suggest that if not set, the fallback is to copy all (turbojpeg.c, 1991-1994):

    if (!(t[i].options & TJXOPT_COPYNONE)) saveMarkers = 1;
  }

  jcopy_markers_setup(dinfo, saveMarkers ? JCOPYOPT_ALL : JCOPYOPT_NONE);

As these seem to be the identifiers that jpegtran uses to set its copy options, I would expect the exif data to be copied from the old file to the compressed file. But it isn't. Either something goes wrong along the way, or I'm not using it right, or I just simply misunderstand the intent (in which case the documentation might be improved a wee bit).

Here's my kotlin code showing how I use the library, by the way, just in case I'm doing something horribly wrong (but then again, I'm observing the same result by just running the turbojpeg.jar that is produced by the build process):

    private fun mozjpegRecompress(file: File): File {
        val inputBuffer = readJpgData(file)
        val outputBuffer = TJTransformer(inputBuffer).use {
            // Create a buffer with the estimated size needed for the entire conversion.
            val maxOutputBuffer = ByteArray(TJ.bufSize(it.width, it.height, it.subsamp))
            it.transform(arrayOf(maxOutputBuffer), arrayOf(TJTransform()), 0)
            // In the end, save the relevant jpg data in the output buffer. 
            maxOutputBuffer.take(it.transformedSizes.first()).toByteArray()
        }

        val outFile = File("${file.parent}/${file.nameWithoutExtension}_recompressed.jpg")
        FileOutputStream(outFile).use {
            it.write(outputBuffer, 0, outputBuffer.size)
        }
        return outFile
    }