7

I am working on a project for which I need to join thousands of JPEG images losslessly (I'm not talking about the Lossless JPEG/JPEG 2000/JPEG-LS formats here).

Aforementioned images have varying levels of chroma subsampling (1x1, 1x2, 2x1, 2x2), resulting in varying MCU sizes (8x8, 8x16, 16x8, 16x16 px). However, in any given set of images to be joined together, each image has identical characteristics.

For now, let's assume I only have 2 images. Image #1 (I1) is 256x256px in size and #2 (I2) is 239x256px in size. 2x2 subsampling is used such that MCU size is 16x16px. I2 thus obviously has partial MCUs at the right edge, since its width is not evenly divisible by 16. (I've read that so-called 'partial' MCUs actually contain the data for a complete MCU, but the image dimensions instruct the renderer to only display the relevant pixels and ignore/hide the extra ones.)

Looking around for tools that could help me accomplish this, I came across a modified version of JpegTran, that contains an experimental lossless crop 'n' drop (cut & paste) feature. All the other apps I encountered that support lossless JPEG editing seem to utilise IJG's (JpegTran) code, so this seemed to be the logical choice. Also, given the sheer number of images, I wanted something that could preferably be run from the command-line so that I could automate the process with a script.

Unfortunately, while everything else worked fine, it seems JpegTran truncates the partial MCUs instead of retaining them. Thus in the example above, the final joined image contains all of I1, but only 224x256px of I2. Why 224? because 239 = 14x16+15, which means there are 14 full MCUs along the width, and 1 partial MCU (just 1px short of the complete 16px). The last 15px is what is getting blanked, leading to a 495x256px image with 15px of blank (grey) pixels at the right edge. See images below (shame that imgur re-compresses them):

Image 1 (left) + Image 2 (right)

= Image 1+2

As you can clearly see, the red portion (15px) of I2 has been truncated by JpegTran. If the MCUs were 8px in width, the lost portion would have been the right-most 7px of I2. Similarly, joining I3 (256x239px) *below * I1 would cause the loss of 7 or 15px, depending on the MCU height of course:

Image 1 (top) + Image 3 (bottom)

= Image 1+3

  • Can what I am attempting even be done, or is the so-called 'lossless' JPEG crop 'n' drop only valid for images with no partial MCUs? (Maybe that is why the feature is still in an "experimental state" more than a decade after being introduced...)

  • Until I know for sure that it is impossible, I am not interested in suggestions for lossy joining. Avoiding any generation loss whatsoever is the sole reason why I'm breaking my head over this, else I'd have had this done and dusted ages ago. Also, I am not interested in suggestions related to switching image formats. I do not control the source of the images.

  • If it can be done, how? Please keep in mind that any alternate apps suggested must ideally be capable of automation, given the requirements stated above. (But given how it's unlikely I'm even going to receive a useful answer given the constraints, I would be happy with any app suggestion just as long as it actually works. I can always look into an AutoIT/AHK script or something later to automate it.)

  • I understand that an odd-sized final image might cause issues, so I am fully prepared to accept any solution, even if it results in blank (preferably black) padding pixels to the right/bottom. What I mean is, I don't care if I1 + I2 is 496x256px (1px padding) or even 512x256px (17px padding) in size, as long as the final image contains all the actual image data from both source images, and the entire process is lossless. Obviously the lesser the padding (if any), the better, but at this point any solution will do.

  • A Windows-based solution would be perfect, but a Linux-based one would be entirely acceptable (pre-compiled binaries with no external dependencies, if at all possible, instead of just code snippets). Also, freeware please, unless nothing but paid software will do the trick.

3
  • Wow, interesting question and problem! I am not an expert but I would suggest it would NOT be possible if BOTH images contained partial MCUs. If your first image (I1) always contains full MCUs then it might be possible. Have you tried IrfanView with the JPG_TRANSFORM plug-in? Otherwise, if you're up for some coding, the libjpeg library offers some low level ways to manipulate JPEG data for lossless transformations - see the documentation section titled 'Really raw data: DCT coefficients' Commented Sep 14, 2012 at 2:50
  • @Mike: Thanks for the suggestions! I1 always contains full MCUs. I tried IrfanView, but unless I'm missing something I could only see options for lossless rotation and cropping. Nothing for lossless extension or "negative crop" (that's how IJG terms it in JpegTran etc.), nor for lossless drop. As you can surmise, I first need to losslessly extend the original image, then drop the second image onto the blank extended region (which is where the truncation occurs). As for libjpeg, given that the exact same crop 'n' drop code was committed to all of IJG's apps, how would the lib be bug-free?
    – Karan
    Commented Sep 14, 2012 at 18:20
  • Please let me know where an EXE file which handles this can be located: since for now I have to modify the size via HexEdit to get around this bug: which is obviously not very efficient.
    – Alex
    Commented Nov 16, 2013 at 21:55

1 Answer 1

5

JpegTran has now been updated by its developer and the edge truncation bug has been fixed, so no other app is required to accomplish my task.

2
  • ... Please share with me where you got this updated version. I am having the same problem (it's so annoying I'm only 1 pixel short!), and I cannot find a version which does not truncate partial MCUs.
    – Alex
    Commented Nov 15, 2013 at 19:20
  • 1
    @Alex: Apologies for the extremely delayed reply but I haven't logged in here in a while. Hopefully this will help others even if it's too late for you. The JpegTran page I linked to above confusingly has two downloads for the EXE. The one in section 1 ("New jpegtran -scale lossless resize feature") is NOT the one you want here. Instead get the one from section 3 ("Lossless crop 'n' drop (cut & paste)"). The enhanced drop code was added to the app by its author on 05-Oct-2012 in response to a suggestion by my colleague who was working with me on this.
    – Karan
    Commented Jun 11, 2014 at 22:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .