taking advantage of chroma subsampling with JPEG and ycbcr in pyramidal tiff files

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
beaudet
Posts: 6
Joined: 2017-09-15T06:24:22-07:00
Authentication code: 1151

taking advantage of chroma subsampling with JPEG and ycbcr in pyramidal tiff files

Post by beaudet »

I have an uncompressed TIFF source image that I'm converting to pyramidal tiff files with JPEG compression. I would like to take advantage of the significant space savings (3x) afforded by chrominance subsampling as as John Cupitt, the author of vips, points out here:

https://github.com/jcupitt/libvips/issues/99
...vips always uses YCbCr coding for jpeg. It lets you enable chrominance subsampling and gets you another factor of two or so compression (from memory) with no quality loss. It's really a bug not to use it, in my opinion.
However, I'm not quite sure what the magickal combination of command line parameters is to get this to work without mutating colors.

I've succeeded in creating a TIFF that uses JPEG compression and the ycbcr colorspace and there is a fantastic reduction in file size but there are problems with the resulting colors in both IM 6.7.8.9 and IM 7.0.7-2.

Here's a simple reproducible case using only IM commands rather than my source image:

Create a rainbow in a new uncompressed tiff file
convert \( xc:red xc:blue +append \) \( xc:yellow xc:cyan +append \) -append -filter triangle -resize 1000x1000\! rainbow.tif

Create an uncompressed pyramidal tiff out of it (works fine without colors getting shifted)
convert rainbow.tif -define tiff:tile-geometry=256x256 ptif:standard_tiff_rainbow.ptif

And converting to ycbcr colorspace and reducing depth to 8 also seems to work fine too without shifting colors
convert rainbow.tif -define tiff:tile-geometry=256x256 -set colorspace ycbcr -colorspace ycbcr -depth 8 ptif:ycbcr_tiff_rainbow.ptif

But, adding JPEG into the mix causes red to turn to green, blue to turn red, etc.
convert rainbow.tif -define tiff:tile-geometry=256x256 -set colorspace ycbcr -colorspace ycbcr -depth 8 -compress jpeg -quality 85 ptif:ycbcr_tiff_with_jpeg_100_rainbow.ptif

interestingly, this doesn't seem to have to do with chroma subsampling since using -quality 100 produces similar color-shifted results.

If I set the first colorspace to sRGB, I get results that more closely match the original colors and using set colorspace RGB seems to fix the color shifting entirely.

Can someone explain what's going on here? I still need to test this last option with actual color profiles embedded in the source images and if there are some tweaks to this process to ensure colors match all the way from the original source image, I'd appreciate the assistance.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: taking advantage of chroma subsampling with JPEG and ycbcr in pyramidal tiff files

Post by snibgo »

beaudet wrote:-set colorspace ycbcr -colorspace ycbcr
The first of these merely changes metadata, declaring that the data is YCbCr (although it isn't, of course). The second would change the data from some other colorspace to YCbCr (as well as changing the metadata), but as the data is already declared as YCbCr, it does nothing.
snibgo's IM pages: im.snibgo.com
beaudet
Posts: 6
Joined: 2017-09-15T06:24:22-07:00
Authentication code: 1151

Re: taking advantage of chroma subsampling with JPEG and ycbcr in pyramidal tiff files

Post by beaudet »

Thanks, that makes sense
beaudet
Posts: 6
Joined: 2017-09-15T06:24:22-07:00
Authentication code: 1151

Re: taking advantage of chroma subsampling with JPEG and ycbcr in pyramidal tiff files

Post by beaudet »

Follow-up question: I know there was discussion elsewhere about ImageMagick's lack of support for chroma sub-sampling when JPEG compression is used in a TIFF files unless the colorspace is ycbcr. The latest I read was that it was due to a libtiff limitation. However, there are other programs such as vips that are able to take advantage of chroma sub-sampling and produce JPEG images in the sRGB colorspace. In the case of vips, for example, the resulting TIFF files are THREE TIMES SMALLER than ImageMagick's for the same quality setting.

Unfortunately, I am unable to figure out how to bend ImageMagick to produce a ycbcr colorspace JPEG inside of a TIFF without the colors getting out of whack. I'd appreciate any assistance.

I'm starting with an Adobe RGB profile and trying to standardize to an ICC sRGB profile that I want embedded in the tiff. However, I don't quite know how to accomplish that with I.M. if the colorspace of the JPEG inside the TIFF has to be ycbcr. What are the steps? I'm using the following approach to generate the proper colors in the sRGB space:

convert original_uncompressed.tif +profile '*' -profile <extracted profile from original_uncompressed.tif>.icc -profile standard_sRGBProfile.icc -define tiff:tile-geometry=256x256 -depth 8 ptif:target_pyramid_with_embedded_srgb_profile.tif

Interestingly, if I leave off the +profile and the first -profile, the colors become muted despite the fact that there's already an embedded ICC profile in the original image that I.M. should be using but is possibly not.

Anyway, using this command, I'm able to create a target tiff just fine in sRGB space and with an embedded sRGB profile, but using that sRGB profile in the ycbcr color space doesn't work and of course it shouldn't being a different space and all. When I only specify -colorspace ycbcr for the target, the colors in the resulting image are way too dark, yet the image is still there and the file is THREE TIMES SMALLER in size. Do I just need to correct the gamma for ycbcr or is there an equivalent color profile for the ycbcr space that is a cousin of a standard sRGB profile? Or is there some way to convert an sRGB profile to an equivalent profile in the ycbcr space which I could then use as follows:

convert original_uncompressed.tif +profile '*' -profile <extracted profile from original_uncompressed.tif>.icc -profile magical_ycbcr_profile.icc -define tiff:tile-geometry=256x256 -depth 8 ptif:target_pyramid_with_embedded_srgb_profile.tif

Any insights greatly appreciated.
Post Reply