Skip to content

Can't decode 4:2:2 subsampled JPEG images #92

Closed

Description

@k-ross

Using the TurboJPEG API, I cannot decode images that have a chroma subsampling of 4:2:2. 4:2:0 works fine. tjDecompressHeader fails, as well as tjDecompressToYUV.

Attached is a sample image that fails to decompress, but I can view in Windows Photo Viewer, as well as other image viewing programs, without issue.

mjpeg_test_422p

Activity

  1. changed the title [-]Can decode 4:2:2 subsampled JPEG images[/-] [+]Can't decode 4:2:2 subsampled JPEG images[/+] on Jul 28, 2016
  2. dcommander commented on Aug 1, 2016

    @dcommander
    Member

    The test image is doing something rather sneaky. The SOF marker in the JPEG header specifies the horizontal and vertical "sampling factors", which in a 4:2:2 image would normally be 2x1 for the luminance component and 1x1 for the chrominance components. The way to read that is: "for every 2x1-pixel block in the source image, include 2x1 luminance components from that block in the output image, but only include one chrominance component." Your test image specifies sampling factors of 2x2 for the luminance component and 1x2 for the chrominance components. If you read that as "for every 2x2-pixel block in the source image, include 2x2 luminance components from that block in the output image, but only include 1x2 chrominance components", then that would specify a 4:2:2 image, but it's definitely not the normal way of specifying a 4:2:2 image. Because the sum of the products of the horizontal and vertical sampling factors must not exceed 10, those sampling factors are normally specified using the smallest possible integers. It just so happens that 4:2:2 and 4:4:0 images can be specified in two ways without exceeding this limit of 10. That isn't the case for any of the other standard subsampling types. You can't, for instance, specify a 4:4:4 image as 2x2,2x2,2x2, because 2x2 + 2x2 + 2x2 = 12, nor could you specify a 4:2:0 image as 4x4,2x2,2x2. The referenced commit should fix the TurboJPEG such that it now allows for these non-standard images.

  3. k-ross commented on Aug 1, 2016

    @k-ross
    Author

    A little info about how the image was created. It's a single frame from an MJPEG movie file. The movie file was encoded with Adobe Media Encoder. However, when I did the encode, I accidentally specified interlaced output, so instead of each frame being 720 pixels high as it should be, I think they are broken into two 360 pixel high fields with a 2x vertical scaling factor.

    Regardless, thanks for making this change so quickly!

  4. dcommander commented on Aug 1, 2016

    @dcommander
    Member

    No problem. As an additional note for anyone who might be stumbling upon this from Google or whatnot, you can also create these non-standard images by passing -sample 2x2,1x2,1x2 or -sample 2x2,2x1,2x1 to cjpeg. The resulting JPEG images will be bitwise different from "standard" 4:2:2 or 4:4:0 images, but they will be approximately the same size, and the decompressed pixels will be identical to those of the "standard" images. I suspect that that might not be the case unless the source image height is evenly divisible by 2, but I didn't test that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions