[gdal-dev] tile artifacts in YCBCR compressed JPEG in TIFF
warmerdam at pobox.com
Wed Nov 4 14:51:03 EST 2009
Ray Joslyn wrote:
> I have noticed tile artifacts that corespond to the tile sizes when
> compressing color images with the PHOTOMETRIC=YCBCR option for JPEG compressed
> Tiff images. I do not see this if I use PHOTOMETRIC=RGB. Are there any
> options that may prevent this?
I followed up on this privately with Ray, and after some analysis I wrote:
I have looked up and down the software chain, and I've come to the conclusion
that the YCbCr 2x2 downsampling for Cb and Cr are not strictly local to the
2x2 area but instead take into account the neighbouring image data. In
libjpeg/jcprepct.c I see this comment:
* For the simple (no-context-row) case, we just need to buffer one
* row group's worth of pixels for the downsampling step. At the bottom of
* the image, we pad to a full row group by replicating the last pixel row.
* The downsampler's last output row is then replicated if needed to pad
* out to a full iMCU row.
* When providing context rows, we must buffer three row groups' worth of
* pixels. Three row groups are physically allocated, but the row pointer
* arrays are made five row groups high, with the extra pointers above and
* below "wrapping around" to point to the last and first real row groups.
* This allows the downsampler to access the proper context rows.
* At the top and bottom of the image, we create dummy context rows by
* copying the first or last real pixel row. This copying could be avoided
* by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
* trouble on the compression side.
I tried using 32x32 blocks instead of the default 256x256 and I see the
anomaly every 32 pixels.
I conclude that because the 2x2 subsampling is done deep in libjpeg it
is not practical to provide cross-tile boundary context to avoid the
anomaly. It does therefore mean largish tiles will reduce the issue.
I *think* that the reduction in the quality of the image due to the
lack of tile boundary context is minor in comparison to the information
lost in the YCbCr downsampling, and JPEG compression and it just shows
as noticable in the fiducial marks because they have a very regular form
so any alteration in the pattern of horizontal or vertical anti-aliasing
is quite noticable.
I have no real fix to propose. The only real fix would be to do the
RGB -> YCbCr conversion and YCbCr downsampling in GDAL before the imagery is
sent down through libtiff and libjpeg. This is theoretically possible, but
would require quite a lot of work and risk.
Hopefully this information - somewhat surprising to me - will also be
helpful to others.
I set the clouds in motion - turn up | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | Geospatial Programmer for Rent
More information about the gdal-dev