duplicate the compression fingerprint of one image and apply it to another.

35 views
Skip to first unread message

Hugh Shaw

unread,
Jun 28, 2023, 3:59:02 PM6/28/23
to libjpeg-turbo User Discussion/Support
I have a specific requirement I need help with and hope to get assistance from experts in the field. I have learned that for the same compression algorithm, the compression fingerprints are consistent. This means that the data from FF D8 to just before the scan line FF DA are always identical. Based on this information, I would like to be able to duplicate the compression fingerprint of one image and apply it to another.

Specifically, I need to accomplish two things:

First, use the perfectly compressed fingerprint from reference.jpg to compress input.jpg and generate output.jpg. Second, make sure that the DQT, SOF, and DHT information in output.jpg is exactly the same (including hex codes) as in reference.jpg. I have already ensured that the pixel dimensions of input.jpg and reference.jpg are the same.

I have attempted to code a solution, as shown below, which involves manually copying the quantization and Huffman tables, copying critical parameters, and applying the compression and decompression. However, the resulting output.jpg differs in hex code from the reference image, even though the dimensions are the same.
 
Due to lenght limitations, I can only include the code I tried in the attachment

I am unsure what the issue is and would appreciate any guidance in resolving this problem. Thank you.

Looking forward to your reply!
Best regards,
copy_jpeg_file.cpp

DRC

unread,
Jun 28, 2023, 4:19:58 PM6/28/23
to libjpeg-t...@googlegroups.com

I can only barely comprehend what you are trying to do or why, but unless the reference image is a lossless JPEG (I assume not, if it has a DQT), any decompression/compression cycle will result in generational loss.  Thus, you cannot exactly regenerate a lossy reference JPEG image unless you have the original uncompressed image that was used to generate the reference image in the first place.  Once a JPEG image is generated, then some of that original data is lost.  The best you can do is copy the DCT blocks (in the frequency domain) from one JPEG container to another, which is what jpegtran does.  That avoids a decompression/recompression cycle and thus avoids generational loss, so the transformed JPEG image has no additional loss relative to the reference JPEG image.  However, there are limits to what you can do in the frequency domain.  You can reorder the DCT blocks; spatially transpose, rotate, or flip the blocks; remove or change the order of some of the component planes (e.g. convert color to grayscale); negate the coefficients (photo negative); re-quantize the coefficients (lower the effective JPEG quality); change the entropy algorithm (e.g. convert baseline to progressive or arithmetic); add restart markers; crop the image (by discarding certain blocks); wipe an image region (by greying out certain blocks); drop another image into the source image (by replacing certain blocks); or remove metadata.

--
You received this message because you are subscribed to the Google Groups "libjpeg-turbo User Discussion/Support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libjpeg-turbo-u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/libjpeg-turbo-users/db388722-522d-40f7-b868-185684060ffan%40googlegroups.com.

Hugh Shaw

unread,
Jun 28, 2023, 4:46:25 PM6/28/23
to libjpeg-turbo User Discussion/Support

I think you may have misunderstood my intention. What I hope to achieve is to compress an image using the same compression method as reference.jpg, perfectly simulating it. In my understanding, the hex code of a JPEG includes information such as DQT, SOF, and DHT. I wonder if I can use this information to re-compress an image and generate output.jpg. Theoretically, the hex code between FFD8 and FFDA should be identical in output.jpg and reference.jpg, and the compression data after SOS should also be calculated based on information such as DQT, SOF, and DHT. I hope to use libjpeg-turbo to implement this function. It seems that jpegtran cannot achieve this.

DRC

unread,
Jun 28, 2023, 4:56:28 PM6/28/23
to libjpeg-t...@googlegroups.com

Even if you use the identical compression method, there is no way to perfectly simulate a JPEG reference image unless you can obtain the original pixels that were used to generate the reference image.  The term "re-compress" means that you have to decompress first, so you will incur generational loss, as I mentioned below.  You can't perfectly duplicate the JPEG image data (the data after the SOS marker) from the metadata and decompressed pixels of a reference JPEG image.  You can perfectly duplicate the JPEG image data from the metadata of a reference JPEG image if you have access to the original pixels that were used to generate the reference image, but your messages imply that you don't.  That means that what you're trying to do is impossible.

Hugh Shaw

unread,
Jun 28, 2023, 5:20:05 PM6/28/23
to libjpeg-turbo User Discussion/Support
What if I rephrase the question: Is there a way for me to compress a plain red image using the same compression method as reference.jpg using libjpeg-turbo? The resulting red image should have the exact same hex code between FFD8 and FFDA as reference.jpg. 

Hugh Shaw

unread,
Jun 29, 2023, 1:09:58 AM6/29/23
to libjpeg-turbo User Discussion/Support
I'm sorry for I did not express my current situation well enough for you to understand my intention: Images taken by a certain manufacturer's phone/camera have their own fixed compression algorithms. I hope to simulate these compression algorithms to generate my own images, whether they are input images or self-generated ones. This issue has been bothering me for a long time, and I have not been able to find a solution

DRC

unread,
Jun 29, 2023, 10:07:25 AM6/29/23
to libjpeg-t...@googlegroups.com

In your original message, you said that "the resulting output.jpg differs in hex code from the reference image", which implied that you expected the entire images to be bitwise-identical.  That is an unrealistic expectation.  If, however, you meant that you expected the data between the SOI and SOS markers to be the same, then what you're actually trying to do is make the image *headers* bitwise-identical.  That is also an unrealistic expectation, unless the camera uses libjpeg-turbo.  Different codecs don't always write the headers in the same way.  If, however, what you're really trying to do is duplicate the level of JPEG compression that a camera uses, then using jpeg_copy_critical_parameters() (as your code already does) is the way to do that.

That's all the help I can provide.

Hugh Shaw

unread,
Jun 29, 2023, 12:04:45 PM6/29/23
to libjpeg-turbo User Discussion/Support

Thank you very much for giving me such a clear answer!! Now I understand that I shouldn't continue studying on libjpeg-turbo. At the same time, I would like to ask, if I want to achieve my goal, is there any way to do it? For example, what kind of library should I use or what should I learn?


Thank you again!! 

Reply all
Reply to author
Forward
0 new messages