JPEGsnoop icon indicating copy to clipboard operation
JPEGsnoop copied to clipboard

Lossless JPEG

Open ImpulseAdventure opened this issue 7 years ago • 5 comments

Decode lossless JPEG files

[2010/10/16] First created at https://sourceforge.net/p/jpegsnoop/feature-requests/24/

ImpulseAdventure avatar May 01 '17 04:05 ImpulseAdventure

I'm trying to understand how the DHT table is composed for Lossless JPEG, it'd be great if you could add support for the SOS header in SOF3 mode

Here is a sample image I'm using: https://www.dropbox.com/s/2vxl1h6wmo97lse/Lossless.jpg?dl=0

MarcusJohnson91 avatar Dec 27 '19 21:12 MarcusJohnson91

https://github.com/lclevy/libcraw2/blob/master/docs/cr2_lossless.pdf

lclevy avatar Dec 27 '19 21:12 lclevy

Thank you Laurent -- that is an excellent summary you created.

ImpulseAdventure avatar Dec 28 '19 02:12 ImpulseAdventure

I'm not understanding how a code is mapped to a pixel value?

from the image I posted earlier, the Huffman table is: 2[4, 5, 6] 4[2, 3, 7] 5[0] 6[1] 7[8] 8[A] 9[9] 10[B] 11[C]

where the number outside of the brackets is the number of bits, and the number(s) inside the brackets are the values.

how do I find out which pixel 11[C] maps to?

11[C] would be what binary string, and what would that binary string map to pixel wise?

MarcusJohnson91 avatar Dec 28 '19 03:12 MarcusJohnson91

Hello Marcus!

First, I must caveat this by saying that I have not spent much time decoding lossless JPEG images in detail, but perhaps this may help you get started with your question.

Unlike BMP-formatted images, a singular JPEG Huffman code doesn't directly map to a pixel value. I would recommend starting with a read through my JPEG Huffman coding tutorial first, as the differential coding scheme is covered in moderate detail with a simple two-block example. You will find that each Huffman code basically describes the "change in value" from a previous block or predicted block.

More specific to your question: Your Huffman code "11[C]" is mapped as follows (according to JPEGsnoop with DHT Expand option enabled):

     Codes of length 11 bits:
      11111111110 = 0C                   (Total Len = 23)

Once you encounter the bit sequence 11111111110 during decode, the next 12 bits will represent a signed "difference" value. In lossy compression modes, this difference value would typically describe the change in the luminance (since you have a single-channel image) for the DC coefficient versus the previous "block" or the change in an AC frequency coefficient. Thus one doesn't really convert a single coefficient (or huffman code) into a "pixel value". The DC / AC coefficients are based on a frequency-domain representation of your image (see FFT), which is quite removed from the concept of a pixel value.

In the case of lossless JPEG images, the changes are based not on the previous DCT block but a predicted value from neighboring blocks. See https://en.wikipedia.org/wiki/Lossless_JPEG

Hope that helps!

ImpulseAdventure avatar Dec 30 '19 19:12 ImpulseAdventure