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).

ModeByte 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!
 Hi, this is a very useful article. I have been using it, finally I can understand how JPEG files are organized and all the types of markers in JPEG.
But I have a doubt: how to generate each MCU's from these marker segment.
 Hadn't remembered that JPEGsnoop could extract images from an AVI! all my other tools threw up on the AVIs my old Fuji camera makes, but JPEGsnoop handled them right off!

(I wish I could make the preview less blurry, tho the extracted images are good.)
 Great to hear it! Unfortunately the preview quality is at the mercy of what the encoder used :)
2015-10-02Tom D
 I have a digital phone photo that I am wondering about. The metadata shows that it was taken at 7pm. I think it was actually taken later in the evening and that the metadata may have been changed. Is there any way to prove that it was or was not altered?
 In general, you can't easily determine if the metadata has changed since there is no history in any changes. However, depending on what camera created the image, there are sometimes a few different ways that the date is encoded. By reviewing all of the date fields in the JPEGsnoop output log, you may find one of them doesn't match the others -- which could be a hint.
 I was hoping i could read Huffman code from jpeg (it has secret code in it, it is geocaching and north/east coordinates) so can i use this programm ? image: THANKS !
 When you say "secret code", do you mean that some data was hidden with a steganography technique such as LSB embedding? JPEGsnoop will report out the frequency of each huffman code which might give some hint as to whether this has been done. I have not added any feature yet that would attempt to strip out the least significant bits, though.
I have a jpeg file. how to get the decoded or IDCT value of a image...please help..
 am working on an embedded JPEG Encoder project using the Jpegant library ( I am currently trying to get a single MCU compressed into a JPEG using this library, and I am using JPEGSnoop to verify the contents of the JPEG. My raw data is YUV422 so I am compressing two 8x8 blocks of Y (luma) data, and one 8x8 block each of Cb and Cr data. I am getting the following error in JPEGSnoop and I am out of ideas as to what might be causing the error:

*** 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

Since the JPEG is so small, the raw file data is hosted at this pastebin link:

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.
 I am working on an embedded JPEG Encoder project using the Jpegant library ( I am currently trying to get a single MCU compressed into a JPEG using this library, and I am using JPEGSnoop to verify the contents of the JPEG. My raw data is YUV422 so I am compressing two 8x8 blocks of Y (luma) data, and one 8x8 block each of Cb and Cr data. I am getting the following error in JPEGSnoop and I am out of ideas as to what might be causing the error:

*** 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

Since the JPEG is so small, the raw file data is hosted at this pastebin link:

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.
 Hi Matt -- I can take a look for you. Check your email for a request for more info and source files. Thanks!
 This is definitely a wonderful tool for pinpointing the corrupted pixels in an image. I

or this one
 Glad to hear it was useful! Thanks for pointing out some examples of corruption to test out!
 I downloaded JPEGSnoop when first issued for 'Just in case I need this' reasons. Well, I am writing this whilst reading a crashed hard drive externally and finding that, whilst all files and folders are intact, most of them cannot be opened (documents and pictures). Strangely though, the left hand pane/column under details (at the bottom) shows perfect examples of the pic or doc that I am trying to open. So I know neither has been corrupted. Can you tell me how to use your product to reverse the process that has occurred during the disk failure or even to manually re-write them one by one.

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.
 Great job Guys! This software enabled me to recover a corrupt jpeg file in no time. Keep up!
 Glad to hear it!
 Hello Cal,

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
 Great tool mate! i thank you for it.
Also i read smthin bout a baby, congratulations
2012-12-05Mauro Gallo
 Hi guys, great work!
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
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!
 JPEGsnoop cannot prove "without a doubt" that a set of photos were taken in sequence. JPEGsnoop will detail all of the metadata that is carried in the image, some of which (EXIF) includes date and time information. There are many utilities out there that can let you modify the EXIF date/timestamps that accompany the image data. Since the standard EXIF metadata carried with the image does not have any cryptographic hash built-in (like some high-end dSLRs with image verification), there is no way to verify that this metadata has not been altered. JPEGsnoop's authenticity capabilities are more focused on the image itself -- the compression "fingerprints" are changed once you modify the image. JPEGsnoop can often pick up on the "fingerprints / signatures" left behind from various image editors. Unlike EXIF metadata, these compression signatures are much harder to "modify" to cover ones tracks.

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:
  • EXIF IFD0.DateTime
  • EXIF SubIFD.DateTimeOriginal
  • EXIF SubIFD.DateTimeDigitized
  • Canon.ImageNumber
Of these, the last one is most interesting: it is an incrementing shot count from the camera, which suggests you have approximately 1666694 and 1666695 shots. Most simple EXIF editors won't let you modify this counter, so it is probably the best indicator that these shots were taken in succession. The average computer user would not be able to modify this counter. However, if someone is familiar with a hex editor one could make them represent any count they wished.

Hope that helps!
 I have been looking on the Internet for some time for a command-line tool able to detect corrupted jpeg file. I'm glad to have found at last JPEGsnoop, I'm wondering which options should be used (both at the command line level and at the JPEGsnoop options) in order to locate as many corrupted jpeg files as possible.
 Hi -- JPEGsnoop is not designed specifically to do such a search efficiently. However, it may be possible to achieve a basic search as follows: From the GUI, use the menu option "Batch Process..." and select the root folder of your JPEG files that you'd like to search. Then, optionally select to enable subdirectories. Once you begin the process, each file will be processed and the accompanying log file written out (into the same directory as the JPEG file). You could then do a windows search across these JPEG files for "ERROR".

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 :)
2012-11-10James P
 Greets Calvin,

Is it possible to extract all images from a single file without exporting each one individually?
Thank you for this wonderful program.
 Yes! With the most recent version of JPEGsnoop, you can use the "Export JPEG..." option, click on the checkbox for "Extract all JPEGs" and hit OK. The individual images will be saved out in the same directory as the original file.
 Hello Calvin,
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.

 Hi Vahid -- glad to see it is useful!

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.
 I had a raid drive controller go out - we restored the images off of the raid - 2TB. We now have 146,000 jpegs, from my random samplings it seems about 20% are corrupt. Is there any way automatically sort out / delete the corrupt images?

 Oh, that's a terrible situation... so sorry to hear that. One way to approach this is to use JPEGsnoop in batch mode and let it process a number of the subdirectories (you might want to limit the number at first as I have not tested batch processing on such a large fileset). You can then do a text file search in these directories for ERROR (which will probably appear in the JPEGsnoop text output associated with each file). The tool isn't optimized to do this type of batch corrupt detection process, but it might be a start.
 Very impressive and helpful tool calvin Thank you.

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
 Take a photo with your camera. Upload it to Facebook. Download it from Facebook. Run the downloaded image through JPEGSnoop.

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. :)
 You're absolutely right Jim... The term "edited" is used very loosely. Really, all that is meant is "not-original". As it is incredibly hard to differentiate simple resaving (recompression) from an edit+resaving, I haven't made any efforts to report "double quantization". I'm definitely open to ideas on suitable terminology. Of course most people are interested in determining if an image has been altered in the more general sense of the word (ie. modified to misrepresent reality), rather than simple resaving, resizing, etc. Regarding the DCT histogram, what type of data were you thinking could be interesting from a histogram perspective? 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.

 First, determine the MCU coordinates. You can do this by moving your mouse over the image and looking at the status bar in the bottom right of the window. Alternately, click on the image at the location you are interested in decoding (this will log the MCU coordinate in the text portion of the window).

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.
2011-10-24Veeranjaneyulu T
 Jpegsnoop is failing to decode an image which does not have EOI. Could you let us know how to handle this case, i mean if there is no EOI? We tried to count the no.of MCUs present in image and say decoding over once it completes decoding all the MCUs. Am eager to know if there is any other approach?
 I believe JPEGsnoop should complete decoding an image even without an EOI as it only depends on the image dimensions described in headers. I just tested it with a removed EOI and you should see the warning message: "Early EOF - file may be missing EOI". The approach you mention: stopping processing once you have decoded the expected number of MCUs is how I would approach it.
2011-10-19Veeranjaneyulu T
 ERROR: Expected marker 0xFF, got 0x0A @ offset 0x00000059. Consider using [Tools->Img Search Fwd/Rev].

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?

 A stop button on the toolbar would be helpful. I have gotten the program into a couple of long projects that I regretted. Hate to close the program and lose whatever's already been done, just to keep it from doing more of it. Great program nonetheless -- thanks!
 Great suggestion. I have added a feature request to the SourceForge page (ID 3295582).
 Do you know if the Droid Cell phone photo on Verizon captures the location where it was taken (GPS coordinates)? I tired running a photo through your program, but couldn't determine from the read out if it did.
 If you can indicate the phone model and/or post a link to an example photo, I can run it through to have a look.

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.

 Interesting project... it would be relatively easy for someone to write a program to do this automatically for you (although it may have limited appeal!). The easiest way to disrupt the image is to:
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
 The exact same thing (application) would be extremely useful for TIFF files.It would make possible to for example reassemble an jpeg file from the jpeg -encoded tiles of an tiff and the reverse.And yes,I do realize how much work this involves...

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.
 this is a wonderful site and a great ressource that gives me hope. I've learned that I saved some pictures on a USB stick with a bad sector and therefore some of the jpeg files have been corrupted resulting in pictures with different shades and offsetting. I am still discovering the power of JPEGSnoop, but am wondering to what other ressource may I combine it to attempt any restoration of my images?

any direction is always appreciated.
2009-07-06mary moo
 aloha, not sure if i am in the right forum...but i do have a question perhaps you can help me goes!...i keep getting photos sent to me on one of those "friend social networks" i believe the person is sending fake photos of him, because when i zoom in, his image of his face is all made up of pixels or boxes, and i cannot make out the face. none of the other photos i receive from friends seem to have this problem of clearly identifying who is in the photo. just wondered if there is a way to know if you are being duped by someone claiming to be who they are not via phot. thanks
 Hi Mary -- It sounds like the image you were sent is just "highly compressed", which leads to the "blocking artifacts" you see. (To confirm, do you see the same blocking in other areas of the same image?) The person sending you the image may have saved it at a very low quality setting, unlike images you have seen from others. In order to determine whether the photo is real, you'd probably have to perform various image content analyses, which is not only very subjective but also a challenging process to carry out.
 I have a jpeg that was edited. I want to recover the original (unedited) image, even the thumbnail. When i use Ctrl+2 i get the "No SOI marker in forward search" message. I noticed on one of the posts you said "If the images don't show an SOI marker (after searching forward in the file), it is less likely that the image will be recoverable", on the report after image processing there is this line,

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.
 It is not always possible to recover traces of the original image. In order for it to work, two facts must hold true:
  • 1) original digital photo must contain additional embedded images (such as EXIF thumbnails or alternate image elements)
  • 2) image editing application must not remove/strip off these other metadata portions.
In your case, if JPEGsnoop reports "No SOI marker in forward search" after pressing Ctrl+2 only once, then it is likely that the image editor has removed the embedded JPEG thumbnail and you will not be able to easily recover traces of the original image.
 Have a fun: Tools->Search Executable for DQT and point to JPEGsnoop.exe :)
 Yes, it's possible to use the tool to find the standard table within itself!

is it able to determine the percentage of zero dct coefficients? it would be nice for the linear p-domain modeling (

thanks for the answer
 Hi there Damien -- Although the percentage of various DHT coefficients can be determined from the statistical data reported (combined with the DHT expand option), it won't give you the percentage of 0 DCT coeffs per MCU. I have added this to the requested feature list. Thx.

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?

 Hi Simon -- No. The current version of JPEGsnoop does not perform any localized detection of altered content. There are various image processing algorithms that I am contemplating adding, some of which may help pinpoint various types of edits.
 Cal -

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?

 Hi Mitch -- With the current feature set, no. JPEGsnoop will show you information about the software used to encode the JPEG image (in this case the scanner software), but it has no frame of reference to deduce further information about the original content.
 Hi Calvin: While at Disney I accidently deleted my sd card. I used several recovery programs and got most pictures back but one very important picture was corrupted only 1/3rd of picture showing and rest was grey. I had all but given up hope of recovering it until by chance (thanks Google) I happened upon your site and your utility JPEGsnoop. The abilities and information provided are way beyond my understanding however when I opened the image and clicked Image search fwd the entire image appeared. Although the quality was not 100 % it was very good and with a little help from photo shop the picture has printed satisfactorily. I thank you from the bottom of my heart because I broke a 12 year old girls heart when I deleted it. I will be sending you a token of my gratitude and sincere thanks. I am curious though what am I viewing? It is much more than a header but less than the image. Can you explain please?


St. Catharines, On. Canada
 Hi Doug -- that's great news! I believe what you have probably extracted is a medium-sized preview image that some digicams have embedded within the file. If you email me the original, I'll take a look and report back! Thank you very much for your generosity -- it was really appreciated and certainly helps motivate further development.
 Hi Calvin,

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:

I think both sides could benefit from this approach (larger userbase --> more sample images/checksums,...)

 Hi Calvin,

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:, see the related forum thread here:
 Hi Franz -- yes, that's certainly a good example of a use for the "assessment" logic. I have spent a lot of time developing scripts for photo catalog software in order to maintain versioning (original versus derivatives) -- integrating a quick double-check script could come in handy. I try to be pretty diligent with my own file naming practices, which hopefully reduces the likelihood of the problems you indicate, but having a safeguard makes sense.

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.
 Hi Calvin,

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!
 Thanks Franz... yes, it would be possible to extract out this functionality. I could add this, although I'd need to understand how this type of function would be used (to make it more useful to others).
2009-01-15Giovanni Parodi
 Hi, first of all, thanks a lot for your useful tool.
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
 Hi Giovanni -- The values you see at 0x09D3 represent the insertion of a "stuff byte". What you really need to look at are the huffman bit strings before 0x09D3 and after the stuff byte (starting at 0x09D5). Use the Detailed Scan Decode to start reporting the huffman bit strings at MCU(6,0) with a length of 3 MCUs. This way you'll be able to see the bitstring that is causing you the error.
 The Exporting embedded images feature is awesome! I was having an issue opening a file, so i took it for a spin in JPEGsnoop and saw what had heppened to the file. I ended up with the top half of one image, and the bottom half of another. I was able to extract one of the two, but the other seems lost. Either way I was happy just to see what had happened. Thanks!
 Glad to hear it!
2008-11-30Paulo Reis
 Hi Calvin.
Congratulations, that's a very useful tool.

Could you explain the difference between the "Compression Signature" and the "Compression Signature (rotated)"?


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".
2008-10-19Filipe Custódio

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
 If the images are marked as being from a camera that the database recognizes as generating EXIF info, then the lack of EXIF info in the file indicates clearly that the image must have been edited.
 Can you give more detail as to what the four assessment results are based on, and what they mean. For instance, does "Image is processed / edited" mean that the image data has definitely changed, or that it has likely been changed, or that something about the file has definitely changed, although not necessarily the image content, etc.


 George -- unfortunately, there are always methods by which a very clever user can "fool" any attempts of assessing an image's authenticity (into making it look "unedited"), but this is extremely unlikely. It is even more unlikely that they'd be able to fool multiple image analysis approaches (eg. content, JPEG signatures, error analysis, lighting, etc.)

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).
 please include quantization tables from scanners, webcams
and/or other such image capturing hardwares. Will need heavy
user contribution on this part..
2008-03-29Prakash Chovatiya
 I want the complete source code for the finger print recognization in MATLAB.
Can you provide me ?
Which is the best algoritham for me?
 please include quantization tables from scanners, webcams
and/or other such image capturing hardwares. Will need heavy
user contribution on this part..
 Really it is an useful utility through which i learnt the jpeg compressed image file format clearly.
 The assessment line indicates one of three possible outcomes:

* Image is original
* Image is likely processed / edited
* Image is processed / edited
* Uncertain if processed or original

Isn't that 4 possible outcomes?
 I recently added the "likely processed" determination. I've fixed the text now. Thanks!
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.

 [Update 11/24/2007]: I have created a page to show some examples of the corrupt JPEG repairs that I'm now able to do. If you like, send an example to the email address listed on the page. Thx.
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:

*** Decoding SCAN Data ***
  OFFSET: 0x00004182
*** NOTE: YCC Clipped. MCU=(   9,   5) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(   9,   5) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  10,   5) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  10,   5) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  11,   5) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(   9,   6) YCC=(   -1,  126,  129) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  10,   6) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  10,   6) YCC=(   -2,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  11,   6) YCC=(   -1,  126,  128) Y Underflow @...
*** NOTE: YCC Clipped. MCU=(  11,   6) YCC=(   -1,  126,  128) Y Underflow @...
    Only reported first 10 instances of this message...
*** ERROR: @ 0x0004D45D.5, num_coeffs>64 [67]
*** ERROR: Bad scan data in MCU(156,34): Lum AC CSS(1,0) @ Offset 0x0004D45E.7
           MCU located at pixel=(2504,272)
*** Resetting Error state to continue ***
*** ERROR: @ 0x0008932F.2, num_coeffs>64 [67]
*** ERROR: Bad scan data in MCU(188,60): Lum AC CSS(0,0) @ Offset 0x00089330.1
           MCU located at pixel=(3008,480)
... snip ...
Your opinion would be much appreciated.
 UPDATE: 11/21/2007
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.



Leave a comment or suggestion for this page:

(Never Shown - Optional)

NOTE: Image repair requests are not accepted. Thanks for your understanding.