Return to Digital Photography Articles
JPEGsnoop - Interesting Uses
by Calvin Hass © 2009
This page details a few of the many possible uses for the JPEGsnoop tool
Return to JPEGsnoop Main Page
Identifying Edited Photos
Ever wondered if that UFO photo or sasquatch sighting is a fake? ... or if that camera manufacturer's sample images have been touched up?
Check out the page: Using JPEGsnoop to Identify Edited Photos
Extract Embedded Images
How to Extract JPEG Thumbnail image
Simply open the image in JPEGsnoop, then press Ctrl-2 (Image Search Fwd) until you see the current decoded image is the embedded thumbnail (the image view will be very small, generally 160x120 pixels). Under the Tools menu, select Export JPEG and enter in a filename for the output thumbnail image.
How to Extract video frame from AVI movie file
Open the movie file in JPEGsnoop, and ensure that it has been decoded as a MotionJPEG file (only these AVI files are supported currently). Press Ctrl-2 (Image Search Fwd) until you see the desired video frame shown below in the image view window. Under the Tools menu, select Export JPEG and enter in a filename for the output frame image. Note that exporting frames from videos is completely lossless -- no recompression is applied!
Extract JPEG Images from PDF Documents
PDF Documents often contain embedded JPEG images. You can easily search through these images and extract the ones you want by using the Export JPEG command.
Motion JPEG AVI Decoding
Starting with version 0.7.0 of JPEGsnoop, you are now able to open and decode the underlying video stream from M-JPEG AVI files, which are often used in point & shoot digital cameras. Simply do the following:
- Open the .AVI file
- Use the Image Search Fwd command (Ctrl-2) to locate the first video frame
- Hold down Ctrl-2 for continuous playback and frame / histogram decode!
NOTE: As of version 1.0.0, JPEGsnoop parses the AVI RIFF file format, in an attempt to determine if the AVI file is Motion JPEG. If the AVI is MJPEG, then there is a good chance that you can step through each frame of the Image by using [Img Search Fwd]!
Identifying JPEG Quality
One of the more interesting details about a JPEG image is how the image quality is defined. The quality is defined in what is known as a quantization table, which is a series of 64 values representing different frequency components in the image. JPEGsnoop displays these tables under the marker section DQT.
Many programs use their own tables, while some base it on the example provided in the JPEG Standard Annex K. JPEGsnoop attempts to calculate an image quality rating that is based on the standard tables (compatible with cjpeg, djpeg and other tools). To help one identify whether or not the quantization table was derived from the example ones in the Annex, JPEGsnoop calculates the ratio between the Annex table and the file's table, after the heading: AnnexRatio. If all the values nearly the same, then it implies that the quantization table is simply a scaled version of the Annex table.
If the quantization tables are indeed based on the Annex table, then the quality factor (Approx quality factor) that is displayed should be accurate.
Identifying Photoshop Quality Settings
If you are interested in finding out what quality setting was used in Adobe Photoshop's Save As or Save For Web, look for the following in either the APP12 or APP13 marker sections:
Photoshop Save As Quality =
Photoshop Save For Web Quality =
By resaving a JPEG with the same settings you significantly reduce the amount of recompression error!
Searching Executables - Enhancing your Scanner / Cellphone Camera Image Quality
With the help of JPEGsnoop, you can identify the changes required to hack / modify certain programs / firmware to increase their image quality. For example, I was able to improve the quality of JPEG images from my scanner! Many others have done a similar thing to improve the images out from their cellphone!
In release 1.0.0 of JPEGsnoop, you can locate the embedded compression quality settings within any software executable, using the Tools->Search Executable for DQT. Once located, you are then able improve the quality of the JPEG images created by this software!
How to Use Executable Search for DQT
This feature is only useful for advanced who have an understanding of the quantization tables. In essence, the basic idea is that many binary executables (software editors, drivers, utilities, firmware) contain a built-in JPEG encoder. These JPEG encoders often hard-code the DQT tables that define the resulting image quality delivered by the program. JPEGsnoop will attempt to locate the DQT table within an executable, which would then allow a "hacker" to modify the table to increase image quality or decrease output file size (for example).
NOTE: JPEGsnoop opens the executable files in read-only mode and will not make any changes!
There are two modes of operation:
- JPEG file not opened yet
- Prompt the user to locate an executable for examination.
- Search the executable for the JPEG Standard DQT (defined in Annex K)
- Search is performed with 1,2,4-byte luminance tables in both endian modes.
- JPEG file already opened
- Prompt the user to locate an executable for examination.
- Search the executable for the JPEG Standard DQT (defined in Annex K)
- Search the executable for a DQT that matches the luminance DQT (table 0) of the opened JPEG file
- Search is performed with 1,2,4-byte luminance tables in both endian modes.
So, let's say that you have a program called JPEG Maker (JPEGMaker.exe) and it generated an output file called NiceJPEG.jpg. Unfortunately, JPEG Maker didn't provide you with any options as to the output quality of the JPEG. Using JPEGsnoop, you determine that the DQT table (quality level) is very poor.
You open up a sample JPEG file from JPEG Maker (NiceJPEG.jpg), and then use the Search Executable for DQT command. JPEGsnoop prompts you to locate the binary (JPEGMaker.exe), and it then proceeds to search the JPEGMaker.exe file.
If you'd like to test this option, consider running it on the cjpeg.exe (IJG Library free JPEG Encoder) executable. You'll see that JPEGsnoop is able to find the JPEG standard DQT table in the file.
*** Searching Executable for DQT *** Filename: [cjpeg.exe] Size: [104960] Searching for DQT Luminance table matching [JPEG Standard] Searching patterns with 1-byte DQT entries Searching patterns with 2-byte DQT entries Searching patterns with 2-byte DQT entries, endian byteswap Searching patterns with 4-byte DQT entries Searching patterns with 4-byte DQT entries, endian byteswap Found @ 0x00013BCF Done Search |
Searching Executable for DQT Table |
---|
In the example above, JPEGsnoop located a 4-byte table in the executable starting at file offset 0x13BCF. If you were permitted to make changes to the executable, you would now have the file offset you need to insert your own DQT table.
The table below shows what the different search modes are looking for. Note that the search is for the DQT table with the zig-zag ordering (i.e. the same left-to-right, top-to-bottom sequence as in the JFIF DQT).
Mode | Byte Swap? | Entries |
---|---|---|
Original DQT Table | 01,02,03 ... | |
Search 1-byte Table | 0x 01 02 03 ... | |
Search 2-byte Table | No | 0x 0001 0002 0003 ... |
Search 2-byte Table | Yes | 0x 0100 0200 0300 ... |
Search 4-byte Table | No | 0x 00000001 00000002 00000003 ... |
Search 4-byte Table | Yes | 0x 01000000 02000000 03000000 ... |
Error Detection in Corrupt JPEG Photos
There are many errors (typically from corrupted JPEG) that can be identified by JPEGsnoop. An error in the file may appear in many different forms when decoding a JPEG image. These may include:
- Overread scan segment - Decoder runs out of data when trying to read the variable-length huffman codes to produce all of the needed MCUs.
- Invalid huffman code - When searching for the next bits that appear in the file (within the scan segment), no match was found in the variable length huffman code tables.
- YCC clipping in DC - Each MCU adds or subtracts from the DC (average) value in the previous MCU. These should all stay within an 8-bit range, but corruption in the DC coefficient may cause this value to wander out of range. This type of error will cause sudden large-scale changes in color or brightness in your image. As this type of error generally won't recover, JPEGsnoop will only report the first 10 of these in the log file.
- >64 coefficients in MCU - When trying to find all of the AC coefficients that correspond to a single MCU, the decoder counted more than 63 AC coefficients (+ 1 DC coefficient) without observing an EOB (End of Block) or an exact count of 64 coefficients (an implicit EOB).
When JPEGsnoop detects an error, it generally will show you the exact location of the error in the original JPEG file. This will be reported in the form:
*** ERROR: Can't find huffman bitstring @ 0x00002DC3.1, table 0, value [0xffc84d5a] *** ERROR: Bad huffman code @ 0x00002DC3.1 *** ERROR: Bad scan data in MCU(2,10): Lum DC CSS(0,1) @ Offset 0x00002DC3.1 MCU located at pixel=(32,168)
Precise Bit Error Detection
In the above, the @ 0x00002DC3.1 refers to the hexadecimal file offset 2DC3 (11715) bytes, bit 1 (of 8). Note that JPEGsnoop has the unique ability to report precise positioning, including the bit within the byte that contains the start of the error!
Reader's Comments:
Please leave your comments or suggestions below!But I have a doubt: how to generate each MCU's from these marker segment.
(I wish I could make the preview less blurry, tho the extracted images are good.)
I have a jpeg file. how to get the decoded or IDCT value of a image...please help..
'''
*** Decoding SCAN Data ***
OFFSET: 0x0000025F
Scan Decode Mode: Full IDCT (AC + DC)
Scan Data encountered marker 0xFFD9 @ 0x00000286.0
*** ERROR: Bad marker @ 0x00000288.4
*** ERROR: Bad scan data in MCU(0,0): Lum CSS(0,1) @ Offset 0x00000299.3
MCU located at pixel=(0,8)
'''
I followed the instructions for doing a Detailed Decode of the only MCU in the image and I get the following:
JPEGSnoop Output Log
http://pastebin.com/wWJyXrFK
Since the JPEG is so small, the raw file data is hosted at this pastebin link:
http://pastebin.com/MXyv9TKP
I am at a loss for what might be causing this problem. I would greatly appreciate any insight you might have on this issue. My hope is to get this single MCU to decode properly and then re-enable the full res JPEG operation (note: I have accounted for the small image size in the jpeg header).
I can send you any more information you might need, just let me know. Thank you so much for creating this amazing tool.
'''
*** Decoding SCAN Data ***
OFFSET: 0x0000025F
Scan Decode Mode: Full IDCT (AC + DC)
Scan Data encountered marker 0xFFD9 @ 0x00000286.0
*** ERROR: Bad marker @ 0x00000288.4
*** ERROR: Bad scan data in MCU(0,0): Lum CSS(0,1) @ Offset 0x00000299.3
MCU located at pixel=(0,8)
'''
I followed the instructions for doing a Detailed Decode of the only MCU in the image and I get the following:
JPEGSnoop Output Log
http://pastebin.com/wWJyXrFK
Since the JPEG is so small, the raw file data is hosted at this pastebin link:
http://pastebin.com/MXyv9TKP
I am at a loss for what might be causing this problem. I would greatly appreciate any insight you might have on this issue. My hope is to get this single MCU to decode properly and then re-enable the full res JPEG operation (note: I have accounted for the small image size in the jpeg header).
I can send you any more information you might need, just let me know. Thank you so much for creating this amazing tool.
or this one
http://s26.postimg.org/slw5fpmjd/i00025.jpg
I will try to extract your site to an existing Drive but would ask you to answer by email if you can - my reply to which you can publish here.
First of all, I am extremely happy to have found this tool which I am using to validate the gray scale JPEG image recieved over network but unable to decode using standard image players. I am encountering a few errors as shown below
*** ERROR: @ 0x000004A0.2, num_coeffs>64 [66]
*** ERROR: Bad scan data in MCU(0,1): Lum DC CSS(0,0) @ Offset 0x000004A1.0
MCU located at pixel=(0,8)
*** ERROR: @ 0x000008B2.5, num_coeffs>64 [65]
*** ERROR: Bad scan data in MCU(6,2): Lum DC CSS(1,0) @ Offset 0x000008B3.4
MCU located at pixel=(104,16)
*** ERROR: @ 0x0000092D.7, num_coeffs>64 [65]
*** ERROR: Bad scan data in MCU(9,2): Lum DC CSS(0,0) @ Offset 0x0000092E.4
MCU located at pixel=(144,16)
*** ERROR: @ 0x00000D6F.4, num_coeffs>64 [66]
*** ERROR: Bad scan data in MCU(6,4): Lum DC CSS(0,0) @ Offset 0x00000D70.3
MCU located at pixel=(96,32)
*** ERROR: @ 0x00001084.7, num_coeffs>64 [65]
*** ERROR: Bad scan data in MCU(0,6): Lum DC CSS(1,0) @ Offset 0x00001085.4
MCU located at pixel=(8,48)
*** ERROR: @ 0x00001235.3, num_coeffs>64 [66]
*** ERROR: Bad scan data in MCU(10,6): Lum DC CSS(0,0) @ Offset 0x00001236.1
MCU located at pixel=(160,48)
*** ERROR: @ 0x0000125A.1, num_coeffs>64 [66]
*** ERROR: Bad scan data in MCU(10,6): Lum DC CSS(1,0) @ Offset 0x0000125B.3
MCU located at pixel=(168,48)
*** ERROR: @ 0x00001763.6, num_coeffs>64 [66]
*** ERROR: Bad scan data in MCU(4,9): Lum DC CSS(1,0) @ Offset 0x00001765.0
MCU located at pixel=(72,72)
*** ERROR: @ 0x00001B45.5, num_coeffs>64 [65]
*** ERROR: Bad scan data in MCU(1,11): Lum DC CSS(0,0) @ Offset 0x00001B46.2
MCU located at pixel=(16,88)
*** ERROR: @ 0x00001C21.2, num_coeffs>64 [67]
*** ERROR: Bad scan data in MCU(5,11): Lum DC CSS(1,0) @ Offset 0x00001C22.1
MCU located at pixel=(88,88)
Only reported first 20 instances of this message...
Can you please enlighten on what might be going wrong with the recieved image when decoding? Any hints that can move me forward is greatly appreciated.
Thanks in advance
Sriram
Also i read smthin bout a baby, congratulations
I've a legal question for you.
is it possible with JPEGsnoop define without a doubt that two or more photos were taken in sequence one after the other?
these are the pictures in question
http://www.ingmaurogallo.com/Immagine%20059.jpg
http://www.ingmaurogallo.com/Immagine%20060.jpg
of course I know that the pictures are in sequence because I've taken in 2007, but if things get worse, I'll have to prove it in front of a judge...
thanks in advance for your help!
Assuming one did not modify the EXIF metadata in your example images, we can see various indicators in the image metadata that show 059 was taken before 060:
Hope that helps!
Sincerely
The above method would be very slow as it was not optimized for such a test. Ideally, I would write a specific tool for that purpose, but with a baby it's less likely that I'll find the time :)
Is it possible to extract all images from a single file without exporting each one individually?
Thank you for this wonderful program.
I would like to first thank you for your very useful tool. I am using it to analyze a grayscale JPEG encoder I have developed. The generated JPEG file seems to be fine and can be decoded and opened with all the image viewers that I have tried, however, JPEGsnoop reports two errors that I don't really understand. Here are the errors:
*** ERROR: Bad marker @ 0x000057C3.5
*** ERROR: Bad scan data in MCU(63,63): Lum DC CSS(0,0) @ Offset 0x000057DB.3
MCU located at pixel=(504,504)
Could it be that the second error is just reported because of the first one? when I look into the text file of the JPEG the offset 0x000057C3 is exactly the EOI marker and it is correctly 0xFFD9 in my jpeg file but still the error is reported! Also the second error is still not clear to me! if there is really eny error how come the file can be decoded and read by all the JPEG viewers?
Could I possibly ignore these two errors? what exactly the reason could be?
Thanks s million for your help in advance, this is very vital for me now.
Vahid.
The first error message indicates that it encountered a 0xFF byte in the scan segment followed by a code other than ones expected within this segment (eg. Restart markers). Due to this error, it is very likely that the huffman bit decode will get out of sync, causing the second error message to occur.
Without seeing your example file, it is hard to determine what might be wrong with it. Note that other decoders may not specifically check for the same error conditions and simply stop decoding once the EOI sequence is seen.
If you email me the sample image I may be able to help figure it out for you. Thanks, Cal.
Thanks!
Rr
Can you please elaborate on the approx quality factor (variance)? I am working on a project that corrupts a JPEG and I am trying to understand how bit errors affect JPEG images. I ran both the original and corrupted file on jpegsnoop and i noticed that the variance value was different. But im confused on what it represents. Thank you
The software will show it as edited. Essentially, Facebook recompresses the image on your computer before it uploads it to their servers. Gone are the markers from your camera.
Other than the recompress - there's no actual "editing" as most people use the term. Nothing added or deleted to the photo.
What are your thoughts on this? Is it possible to refine the terms? Something like this could be listed as double quantization - resaved? How about a DCT histogram to point to the integrity of the image in spite of the double quantization?
Thanks. :)
How do I dump the contents of a specific MCU?
I have a case where my JPEG Encoder seems to be losing sync due to encoded MCU size and causes corruption. To confirm my suspicions, I need to check the size of the offending MCU.
-Akshay
Now, select Options -> Scan Segment -> Detailed Decode.... In the window, enter the MCU coordinates, select "Enable scan decode" and click OK. Finally, select File -> Reprocess File. This will add a new section to the text output that details the MCU bit string decoding process.
when i try to get a image details, i is reported the above error. i could not get anything about that error from this info. I have gone through the header part of the given image, it looks like it is correct. So could you plz let me know your comments on the above error or possible cases when i will get the above error?
Thanks,
Veeru.
I'm a MAC based graphic designer currently involved in a research project into the use corrupted or glitched image files. Ive been reading your various fix articles with interest. I'm wondering whether you may be able to recommend a method I might use to deliberately disrupt the binary bits in a sample JPEG that may cause the file to display shearing, wild color shifts or any other visual phenomena - the more random the better - I realize this might be an unusual request. Any help you could offer would be greatly appreciated.
Thanks
1) Locate the scan data segment (see JPEGsnoop's report)
2) Open up the file in a hex editor
3) Select a number of random locations within the file's scan data segment and delete a chunk of 100+ contiguous bytes.
4) Select a number of additional locations within the segment and change the byte values
5) Resave and reopen in image editor to see results
Enjoy!
I was wondering if there was a more simple explanation here?
I have some old photos that have the invalid jpeg marker and/or grayed out areas. I've tried this software, but don't understand it.
Also, is there anything we can do to support your development here? I'm sure a lot of people have/will be helped with all your work on this.
any direction is always appreciated.
robert
Start Offset: 0x00000000
*** Marker: SOI (xFFD8) ***
OFFSET: 0x00000000
is this not the SOI marker?
Pardon me if this is such a trivial question, I'm still a bit new at this.
is it able to determine the percentage of zero dct coefficients? it would be nice for the linear p-domain modeling (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1097953).
thanks for the answer
d
Does this software detect where a piece of the image has been modified within the whole image? Let's say a flower has been cancelled from a digital photo: can you exactly identify where it was before the alteration?
Thanks!
Is it possible for JPEGsnoop to ascertain if a hard copy picture shows "signs" of modification based upon a high quality scan of the photograph?
Thanks,
Mitch
Again THANX
Doug
St. Catharines, On. Canada
yes I think that the demand of image assessment will definitely increase as more and more image editors preserve the original metadata, making it difficult to tell apart modified photos from the "pure" ones.
Concerning the command-line assessment app: maybe you can join forces with Phil instead of developing your own app? Sooner or later you'll want to decouple the signature database from JPEGSnoop, so that users can update it without having to wait for the next JPEGSnoop release. In this process, the database could be converted to an open format that is also useable by other applications (like Robert Rottmerhusen's Nikon Lens Database: http://www.rottmerhusen.com/objektives/lensid/nikkor.html)
I think both sides could benefit from this approach (larger userbase --> more sample images/checksums,...)
Franz
there are many uses for image verification in conjunction with batch processing capabilities, e.g. purifying "polluted" photo stores (e.g. sometimes I save a modified version of the photo in the same directory of the source images, sometimes I just rename source images, so at the end it's difficult to tell apart the original photos from the modified ones).
BTW: The author of exiftool, Phil Harvey, has just updated his tool with a similar functionality called Jpegdigest: http://www.sno.phy.queensu.ca/~phil/exiftool/history.html, see the related forum thread here: http://www.cpanforum.com/threads/9972.
I had indeed seen that Phil had integrated the quantization compare in exiftool. His program is definitely one of the best apps out there for full metadata extraction and decode. Quantization tables seems like a nice extension for his tool.
JPEGSnoop is a great tool! Especially the image verfication capabilities have caught my interest. It would be great if one could use this verification in an automated environment, e.g. verifying uploaded files or huge photo stores.
Do you think you can refactor the image verification routines to an independent tool that could be invoked from other programs? I know that JPEGSnoop has some command line interface right now, but the output report is a bit difficult to parse. Furthermore JPEGSnoop currently does some sort of "all-in-one" analysis, which has a negative impact on its performance (Consider you want to verify a HDD with 3000 photos).
Thanks for your efforts!
Franz
Then I have a question, I used JpegSnoop with an image coded through my encoder and I found the following error:
*** ERROR: @ 0x000009D3.1, num_coeffs>64 [73]
*** ERROR: Bad scan data in MCU(7,1): Lum DC CSS(0,0) @ Offset 0x000009D4.4
MCU located at pixel=(56,8)
however if I look at the JPEG image in an hex editor I find that at position 0x000009D3 there is the following value,
0x000009D2 FF
0x000009D3 00
so I'm not able to understand what's the error related to.
PS I would like to attach the image, but I don't know how to do
Thanks a lot
Giovanni
Congratulations, that's a very useful tool.
Could you explain the difference between the "Compression Signature" and the "Compression Signature (rotated)"?
Thanks
Paulo
When calculating the compression signature, the order of entries in the quantization matrix are important. If you perform a lossless rotation of an image, the quantization table is also rotated. As a result, the compression signature of the rotated version is also provided. This allows one to identify a compression signature match even though an image has been "losslessly rotated".
While doing an analysis of "JFIF" encoded photos, I noticed all of them are reported as "Image is processed/edited". May this be because they lack any EXIF information? Is there a way to know why JPEGSnoop is drawing this conclusion?
Thank you,
Filipe CustÃdio
Thanks!!
George
That said, when JPEGsnoop indicates that "Image is processed / edited", it means that the compression signature does not match the signature of the camera as stated in the EXIF info. This is a very confident indicator of some degree of modification. However, all it may be telling you is that the user has opened up a photo from their digital camera in Photoshop, and then resaved it (without further changes). Of course as soon as someone resaves an image, there is a great chance that they have modified the image in the process (resizing or content modification).
and/or other such image capturing hardwares. Will need heavy
user contribution on this part..
Can you provide me ?
Which is the best algoritham for me?
and/or other such image capturing hardwares. Will need heavy
user contribution on this part..
* Image is original
* Image is likely processed / edited
* Image is processed / edited
* Uncertain if processed or original
Isn't that 4 possible outcomes?
I have the same issue with a few images I have. Can you send me a note or post a reply for repairing images which as out of sync i.e. the image is all there but in bands across the image which are offset.
--
david
Hi David -- If you email me your corrupt photo, I'll see if I can fix it. Some type of damaged photos can be corrected, especially those which appear to have banding, shifted images and colors.
I have some jpegs which I suspected had corruption within the image data stream . I found your site whilst searching on the subject and must say that I have been most impressed with what I have found.
using the "decode scan image" option my suspicions were confirmed and a number of errors were reported.
I am familiar with using a hex editor but am unsure of whether it would be possible to repair the files (after sufficient research) or if it really is a lost cause.
A typical error report is below:
Your opinion would be much appreciated.
I'm pleased to report that I managed to recover these images almost perfectly! Your photos were great examples of heavy data corruption, which in turn helped me refine the fix methodology. What I found interesting, however, is that the corruption appeared to have some periodicity within the image, but not so much within the file stream.
Hi there Brian --
It is possible to fix some corrupted / broken JPEGs -- it just depends on how damaged they are. A single-byte corruption is quite easy to fix. In your case you see that there are a series of YCC clip warnings. Since these are very minor clips, they can be ignored.
However, later on in the image (around pixel 2504x272), you see that the scan data gets out of sync (and has problems from then on). When you look at the image below this point (vertically), can you still identify some of the original image -- ie. is it just wrongly colored, shifted to one side, etc. or is it completely garbled? If you can still recognize some of the image after the first error, then there is an easier chance that you may be able to recover it.
If you email the image to me, I'll have a look and see what is possible.
Cal.
NOTE: Image repair requests are not accepted. Thanks for your understanding.