Return to Digital Photography Articles

JPEGsnoop - Source Code

JPEGsnoop is released as Open Source!

Return to JPEGsnoop Main Page

JPEGsnoop is now Open Source on GitHub!

I'm happy to announce that I have now released JPEGsnoop source code to the open source community. I am hoping that this will enable others to add value in the project in new ways, in addition to helping those who are learning to write their own JPEG decoders

After researching many of the options pertaining to how the source code was released, here are the details:

  • Source code has now been moved to GitHub as of v1.8.0 (previously sourceforge)
  • Source code repository via Git for revision control
  • License agreement is GPL v2 (although I may consider LGPL if sufficient interest)
  • JPEGsnoop Source Code repository on GitHub
    NOTE: Source code for version 1.8.0 has now been posted
  • JPEGsnoop Feature Requests and Bug Reports
  • Please contribute to the project!

Considerations for Open Source

After analyzing digital images for years and developing JPEGsnoop in my spare time, I decided to explore the possibility of releasing the source code to the Open Source community for further development. I was looking to my readers to provide their input in how to best approach this transition.

There are many wonderful application developers out there who are more than capable of improving upon the features and user interface, and I'd like to give everyone the opportunity.

The Source Code

  • JPEGsnoop is written in Visual C++
  • JPEGsnoop uses Windows MFC framework
  • No 3rd party libraries are required: All image decode/display, EXIF decode, etc. are written independently.
  • An extensive database of camera signatures is also included with the source code.

Are you interested in improving JPEGsnoop?

Please let me know if you are a programmer with ideas that you'd like to roll into future releases of JPEGsnoop.

Porting JPEGsnoop to Mac and/or LINUX

Quite frequently, I have been receiving requests to port JPEGsnoop to other operating systems. In most cases, the User Interface code has been reasonably well separated from the primary analysis code, so a port should be relatively easy.


Reader's Comments:

Please leave your comments or suggestions below!

With the GUI, I'm able to batch process and specify an output log directory. How can I do this with the command line interface? All of the log files are being written to the same directory as the source files.

 Good suggestion. I have filed a feature request on the GitHub: JPEGsnoop issues page.
In my previous submission, I realized I have made a mistake in the output format.

For image of say 256*460 image, i need it to output 64 matrices of (256/8) by ((460+4)/8) which is equivalent to 32*58 output. Hence 32*58 for DC component, 32*58 for first AC[1], 32*58 for second AC[2], etc.

The output size should varies based on the dimension of the input image.

Thank you.
Is this software able to extract out all of DC[1] and AC[63] components of an image and output it into an 8 by 8 matrix for each individual DC and AC component separately?

If not, how can I implement it myself?

Thank you for your effort, is an amazing work you've done there.
2018-02-07JIncy Fernandez
 Dear Sir,
I am Jincy Fernandez , doing research. I would like to know how the compressed bits of jpeg converted to MCU.
2018-01-28UK Dwivedi
 Hello, I have got a family-photo & want it enlarged/printed to minimum 2o inchx30 inch and more also if possible also from the following image. Pl. tell how can it done.
 Just a follow-up that JPGsnoop seems to be working properly under xubuntu 17.10 running wine-stable with no libraries or drivers added. Just unzip somewhere and run wine jpgsnoop.exe.
 That's great to hear! Thanks for the followup, Brian. Someday I would like to make the JPEGsnoop core cross-platform so that command-line analysis and batches can be launched from LINUX without the compatibility layer, but for now it seems Wine might be a reasonable workaround. thx
 The mars rovers use an ICER compression software which converts RAW into JPEG before it ever reaches earth. However every single spirit and opportunity image from their raw database is a match for the sony cybershot U, and the chroma sampling is 2x2 which could be an indicator that this camera took the image? It is also 2MP camera which is what NASA claims their mars cameras use. What is the probability that their images just happen to match a specific camera signature ? The subsamp match says yes on each one
 It is very unlikely that they used a Sony Cybershot camera :) If you look at the list of matching signatures you will see "IJG Library - Quality 75". This is the most probable match since many software encoders implement the IJG library for JPEG compression. The fact that the Cybershot camera happens to use the same quantization table as this specific IJG table is more likely coincidence.
 hi, I am new in this field and I hope you help me, my question is: one image jpeg contains 4 tables huffman or there are 4 tables for each MCU?
 Hi sara -- the JPEG image will often contain 4 huffman tables. These huffman tables (defined in the DHT section) are used to decode every MCU. For example, when we begin a MCU we generally start with the luminance component which refers to the DC Huffman table for luminance followed by the AC Huffman table for luminance (for the remainder of the coefficients). Once we're done with the luminance, we then decode the chrominance component which again starts with the DC Huffman table for chrominance and then proceeds to use the AC Huffman table for chrominance. Have a look at my JPEG Huffman coding tutorial for details.
 I am using the detailed decode feature to understand low level details of JPEG. However, I am having trouble understanding the output, here is a part of it:

    Lum (Tbl #0), MCU=[0,0]
      [0x0000026F.0]: ZRL=[ 0] Val=[ -360] Coef=[00= DC] Data=[0x FC 97 A2 8A = 0b (11111100 10010111 -------- --------)] 
      [0x00000271.0]: ZRL=[ 0] Val=[    0] Coef=[01..01] Data=[0x A2 8A 2B F2 = 0b (1010---- -------- -------- --------)] EOB
                      DCT Matrix=[ -720     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]

    Lum (Tbl #0), MCU=[0,0]
      [0x00000271.4]: ZRL=[ 0] Val=[    0] Coef=[00= DC] Data=[0x A2 8A 2B F2 = 0b (----00-- -------- -------- --------)] EOB
      [0x00000271.6]: ZRL=[ 0] Val=[    0] Coef=[01..01] Data=[0x A2 8A 2B F2 = 0b (------10 10------ -------- --------)] EOB
                      DCT Matrix=[    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]

    Lum (Tbl #0), MCU=[0,0]
      [0x00000272.2]: ZRL=[ 0] Val=[    0] Coef=[00= DC] Data=[0x 8A 2B F2 73 = 0b (--00---- -------- -------- --------)] EOB
      [0x00000272.4]: ZRL=[ 0] Val=[    0] Coef=[01..01] Data=[0x 8A 2B F2 73 = 0b (----1010 -------- -------- --------)] EOB
                      DCT Matrix=[    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]

    Lum (Tbl #0), MCU=[0,0]
      [0x00000273.0]: ZRL=[ 0] Val=[    0] Coef=[00= DC] Data=[0x 2B F2 73 FD = 0b (00------ -------- -------- --------)] EOB
      [0x00000273.2]: ZRL=[ 0] Val=[    0] Coef=[01..01] Data=[0x 2B F2 73 FD = 0b (--1010-- -------- -------- --------)] EOB
                      DCT Matrix=[    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]
                                 [    0     0     0     0     0     0     0     0]

Why does same MCU for Y repeat so many times? What is Tb1? What are the binary digits and dashes in the bracket? Why does EOB occur at end of each line. I have many questions about this. Is there detailed user guide on this program?
 Hi -- the best way to understand this section of the report is to study my JPEG Huffman Coding Tutorial. The repeat of the Y is done because your image is using chroma subsampling, in this case you probably have half the chroma (color) resolution in both horizontal and vertical dimensions. "Tbl" refers to the table index. There may be several huffman coding tables that are present in the image which provide the mapping between variable length bit codes and the run length codes (see the huffman coding tutorial for more on this). The digits and dashes represent one or more bits that are associated with the current line. As the variable length codes are not usually a multiple of 8 bits, we see cases where only two bits are used (eg. to encode an EOB) whereas other times a full 16 bits are used. In cases where the DCT matrix has a lot of zeros, an EOB code is used to tell the decoder that no more non-zero values exist in the matrix. If your image has many of the MCUs with flat color (ie. all 16x16 pixels are the same color), then you will see many instances of these EOB codes.
 Hi, how can i get the source code of JpegSnoop? Thanks
 Hi Ferdinando -- the source code is currently available on Sourceforge though I may move it to GitHub someday soon.
I add cameras to the local database but I always get the same message: "Appears to be new signature for known camera.
If the camera/software doesn't appear in list above,
PLEASE ADD TO DATABASE with [Tools->Add Camera to DB]"

The added cameras do appear in the list above but with a *?? where "CAM" should be and a blank where "Yes" under Subsamp Match?. How can I get the local DB to be accepted correctly?
 Hi -- Yes, it turns out that there was a bug in the "Add Camera to DB" function that causes the signatures to be saved in the wrong mode. This will be fixed in the next release. Thanks for letting me know about it!
 Hi! I like JPEGsnoop, I use it sometimes to examine compression/quality factor, now going to try broader usage within JPEG part of Image Processing class (its mostly MATLAB, but still). Visited your website to get the latest version and it came to my attention what SourceForge project is out of sync (file releases at 1.7.3, svn at 1.7.1 while you offer 1.7.5 here). Could you please update SF project or at least do a svn checkin?
 Yes, I plan to make an SVN checkin within the next few week. Thanks for the interest!
UPDATE: The source code for v1.7.5 is now uploaded to the SVN!
 Hi, I am a Student of University of Catania. I would like to create a plugin for a University project. This plugin has to use the function of extraction of thumbnail that already exists in jpegsnoop. Are there some API for implement this function in my plugin? Thank you very much.
 I don't have a specific API, but you could use the command-line options to call JPEGsnoop to extract all of the embedded images (which will include a thumbnail). Give "-ext_all" a try to see if it does what you need. You may end up with multiple images, so you'll want to ignore the full-resolution extracted image and only look for the ones that have a file size < 64KB.
 First of all, thanks for this great software tool! However, the Signatures file is (again) quite old. Are you still investigating the possibility to generate it on this website? Would be a great feature!
 Hi Peter -- great to hear that it has been useful! I am not currently updating the signature set bundled with JPEGsnoop at the moment as it is hard to justify the time & effort. I may look into a way that the website dataset can be imported, but one would have to keep in mind that the reliability of the user-submitted quantization dataset would be uncertain without careful review and screening.
 While discussing in a more generic topic about JPEG carving (from disks/disk images) for forensics or recovery, I made a test with JpegSnoop, the results of which may be of interest, details are on this thread:
starting form here:

As a side note the tool does not run on XP (but all is needed is to change the OS version and subsystem from 6 to 5 in the PE header and it works nicely).

It is a known issue with a number of programs compiled with latish releases of MS compilers that "removed" support for XP.

 Thanks very much jaclaz for the interesting series of tests for JPEG carving! I have followed up on forensicfocus.

Regarding the Win XP operation, yes, the new compiler I was using for v1.7.0 initially stopped targeting for WinXP. This issue was fixed in release v1.7.3 (available now).
 Very nice thanks
 I cannot find any source code more recent than 1.5.2, but I do see binaries up to 1.6.1. Where should I look?

Is there a 64bit version of the exe? I get memory issues with some really big sat images.
 Hi Calvin,

What is the status of adding the capability to fix corrupted jpegs? Right now I can view my jpeg thumbnails, but most of the actual pictures when I open are grey or they look like they got smooshed together with grey around them.

 Hi Kenny - unfortunately I don't have plans in the near future to add corrupt fixing capabilities to JPEGsnoop. It is a very complex process that doesn't lend itself well to automation by a tool.
 Could you please update the sourceforge code to the newest version. Preferably also in a zip (outside of the SVN rep). Thanks!
 Hi -- for sure. I had migrated to a new computer (what improvement an SSD makes!) but overlooked re-instantiating the SVN linkage. I will aim to get the repository caught up soon. Thanks for the reminder! [UPDATE 2013/05/14]: The SVN repository is now current.
 very useful information....if anybody has matlab code for jpeg compression....pls help me out....
 Wonderful tool :)

Faststone can create Jpgs with different color spaces than YCbCr, like RGB or YCbCrK. I don't know if a RGB-Jpg is still standard, at least all other programs I checked so far can display it correctly.

*** Marker: SOF2 (Progressive DCT) (xFFC2) ***
Number of Img components = 3
Component[1]: ID=0x52, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (?]
Component[2]: ID=0x47, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (?]
Component[3]: ID=0x42, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (?]
 Thanks Hoogo -- The tool doesn't detect or handle other color spaces at the moment (other than YCC). I have only rarely ever come across a file other than YCC (or possibly CMYK for printing), but it is on the feature request list. I think it should be relatively easy to extend to support RGB at least. thanks
 Great code, very useful. The signature repository in Signatures.inl in svn is getting a little old. Any chance you could update it with any new ones you've collected? Or a link to a page that generates them from the mysql database? Thanks a lot for all your hard work!
 Hi Dan -- thanks for the feedback! Yes, I have slowed down on my signature updates mainly because my newborn baby has taken up the majority of my spare time :) I think your suggestion of opening up the database might be a good idea. The database currently has almost 28,000 [unverified] entries.

What I would need to decide is: how to provide access (web rendered output, signature file format or DB queries), how to manage server load, and what filtering should be done (if any). If anyone has any ideas, please let me know. Just producing a "JPEGsnoop_db.dat" file to download wouldn't work since it wouldn't have undergone any filtering.
 brilliant page.
 Hi, I think I've find a bug in this program.
If I create a new file and rename it (changing the extension) and then make changes with paint, the final image does not recognize in JPEGsnoop.
"JPEGsnoop 1.5.2 by Calvin Hass

Filename: [C: / Users / Antonio / Desktop / $ RUDWR80.jpg]
Filesize: [1414710] Bytes

Start Offset: 0x00000000
NOTE: File with JPEG markers did not start. Consider using [Tools-> Img Search Fwd] to locate embedded JPEG. "
 Hi Anto -- I can't seem to recreate the issue you noted here. Could you give me more specifics on what the file renaming changed (ie. before and after, including extension)? Thanks
 Yeah Sourceforge guys... or Google Code.
 I've posted it to SourceForge now! I'll be posting links to everything shortly.
 1. You might want to mention somewhere that the source code cannot be compiled with Visual Studio Express Edition, because it requires MFC libraries (which included only in VS Standard Edition and above).

2. You're not supposed to commit executable files to source control (Release/JPEGsnoop.exe). The common practice is to tell SVN to ignore 'Release' and 'Debug' folders (if you're using TortoiseSVN, right click on those folders, TSVN -> add to ignore list -> the name of the folder). You can also do this for other auto-generated files such as *.ncb etc.
 Great points!! I am new to this process, so I'll fix the second one soon. As for the first item, I'll see if I can find some place to put intro text for the source (didn't see any in SourceForge), so I'll probably just put it in a README within the vault.


UPDATE: I have now corrected the repository to remove binaries.
 If you are open sourcing it then I would recommend Google Code as your repository. I have had better experience using it than Sourceforge. I hope you do eventually decide to open source, as it will be fascinating to examine how your program works!
 Thanks! In the end I went with Sourceforge -- and am in the process of tidying up the codebase. I am happy to give others an opportunity to enhance what I have put together. Hopefully others will take advantage of this and introduce new capabilities.
 I would like to encourage you to move forward.

Sometimes I need advanced parsing visualization and picture pixels zoom. This capabilities could be added in future by enthusiasts, probably I'll do it.

I believe, that port to Linux is required as well.
I would advise to merge Image debugger to JPEGSnoop

As far as it is built with wxWidgets - it could be a choice of graphic library to use.

See you in repository ;)
 Thanks Yaroslav...
2010-09-15Michael Soegtrop
 Dear Calvin,

JPEGSnoop is pretty good as it is, but I would definitly add some features here and there as I need them when you release it to open source. I might e.g. think about adding support for progressive JPEGs. I would prefer LGPL because it might give the code a broader user base, but GPL would also be fine. I would prefer sourceforge because it is not commercial like google, but I don't have a strong opinion on this either.

Best regards,

 Thanks Michael for the suggestions!
 hi man, how can i get sources of JPEGSnoop?
 Source code is currently in the process of being made available.... stay tuned!
 very good!
 Great news. I am willing to see jpegsnoop run on linux.

Somebody highlight me this wikipedia entry (it may help you) :
 Thanks, that's really useful!
2010-04-24mark cox
 I would consider the LGPL to be a good compromise because it would allow code to be factored out into a library that could then have multiple frontends or application users. Also, i prefer googlecode over sourceforge. i find it so much simpler to use.
 Thanks Mark!
 I also recommend Sourceforge.

Great news, releasing such software is great for people trying to understand jpeg standard as i am at the moment :)

License and depot host site depend of what you want to do now!
If you still want to manage yourself patch, bug and keep source a depot impulseadventure is the best solution. But you will have to install yourself all the web stuff, and you will probably never want to share this management with someone else that you probably will never meet.

If you want at the end that somebody else handle all this software life. Depot on remote server is probably the best. They provide bugzilla database for bug tracking and feature request, mailing list services, forum ... You are free to use it. There is some permission management too this allow to share project management : commit, release, forum moderation ...
Which of google code, sourceforge, freahmeat ... Well ...
Google "Don't be evil" ( Some people think they are ...
Sourceforge i read a day the same about them.

Once you publish your code the only thing that protect you and your work is the licence.
If you don't care about what people will do with it, BSD licence is great. Eventually somebody will make money with it :)
If you choose a more restrictive licence (ie GPL ), you force people who use your work to share with the community their personnal work.

So it really depend of which project future you want to go.
 Thanks Thomas. Given the number of people that have downloaded and use JPEGsnoop, it is difficult for me to keep up with the magnitude of development feature requests & support. Some features, such as the signature matching / database, could use some collaborative input into how it can be made more useful / accurate. I also recognize my limitations in user interface development, which again reinforces the benefit of opening it up for others.

I am inclined to migrate the hosting off-site (eg. to sourceforge) so that I can leverage the bugzilla, CVS, support forums and greater visibility. I don't have any problem with others taking control over the direction of the program, though I am still keen to keep involved in the development & ideas for the future.

Regarding the licensing, my personal preference is to help increase the sharing & learning with others, which seems more in line with a GPL-type license. I will need to spend some time looking at this in greater detail, but that's the direction I'm currently leaning.
 Lessee, the other question, about opensource licensing. There are a variety available, some better than others. I'm sure you're aware of them, but here's my opinion:

If you want to enforce a future of opensource, then GPL2 is probably a good choice and is pretty well known and understood by now.

If you want to make it as free as possible for the world to use (including closed-source projects), while retaining acknowledgment of its origins, then the BSD lic. works.

Personally I would *not* go with the GPL3 lic. as it gets into political motivations that are, IMO, quite at odds with the whole philosophy of shared source.
 Great input... I am relatively new to the licensing terms, so I will need to dig into this carefully.
 Sourceforge is probably the best known and most accessable distribution point for opensource stuff. Most likely to show up in a search for a particular type of program, too. So it is what I'd recommend, at least from userland.

I'd be glad to see it happen as one of my small ongoing fears is that source will be lost forever for unique programs (it has happened before), which are then frozen in time. So thank you for considering this method of assuring JpegSnoop's ongoing future.
 Thanks Rez! I would love to see the program continue development as I have a huge list of interesting features that people have requested but only a limited amount of time available.


Leave a comment or suggestion for this page:

(Never Shown - Optional)

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