Raw YUV with odd width read incorrectly
Posted: 2013-09-25T14:27:19-07:00
It appears that the YUV "coder" is incorrectly reading images with an odd width. However, given the age and stability of IM, I'm willing to believe it's user error and not actually a bug; but I'll describe what's happening and let the experts advise. I did search around on the forums and web and didn't find this issue to have been reported. convert -version reports the following, and I am using it on Windows 7.
I'm using convert on a raw YUV image (specifically, YUV420P, YV12; 8-bit depth planar) as follows; it works fine for even widths (tried: 1280, 1366, different images of course), but with a 1365x1024 image reports:
I confirmed that it was reading too few bytes and not too many using the -identify switch:
In fact, it's reading precisely 1024 bytes too few (verified by forcing an offset with +). Using test.yuv[0] for the source image produces an image whose luma component is correct but has strange green/purple chromatic flares, suggesting offset issues with the U/V planes. The file size is 2097152 bytes = 1365*1024 (Y) + (1365 divrup 2)*(1024 divrup 2) (Cb) + (1365 divrup 2)*(1024 divrup 2) (Cr) bytes, where I'm using divrup to mean divide rounding up, i.e., (x+1)/2 in C. If the IM code did not round up, then it would expect exactly 1024 bytes too few.
Indeed, looking at coders/yuv.c, I found that when chroma_image is created, it calculates the width and height by normal (round-down) integer division by horizontal_factor and vertical_factor. When I modified the division to round up and rebuilt IM, my original convert command line worked as expected.
Is this a bug, or is it expected behavior that odd chroma info will just drop off and do something like use the previous 2x2 block's value, or are odd-width YUV images just not supported? If the existing behavior is expected, is there an option I can use to round up and look at the chroma information at the edge of my image?
Code: Select all
Version: ImageMagick 6.8.7-0 2013-09-18 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib freetype jbig jng jp2 jpeg lcms png ps png tiff webp x xml zlib
Code: Select all
convert -size 1365x1024 -depth 8 test.yuv test.bmp
convert.exe: Unexpected end-of-file `test.yuv': No such file or directory @ error/yuv.c/ReadYUVImage/429.
Code: Select all
convert -size 1365x1024 -depth 8 -identify test.yuv test.bmp
test.yuv[0] YUV 1365x1024 1365x1024+0+0 8-bit YCbCr 2.097MB 0.320u 0:00.368
test.yuv[1] YUV 1365x1024 1365x1024+0+0 8-bit YCbCr 2.097MB 0.180u 0:00.214
convert.exe: Unexpected end-of-file `test.yuv': No such file or directory @ error/yuv.c/ReadYUVImage/429.
Indeed, looking at coders/yuv.c, I found that when chroma_image is created, it calculates the width and height by normal (round-down) integer division by horizontal_factor and vertical_factor. When I modified the division to round up and rebuilt IM, my original convert command line worked as expected.
Is this a bug, or is it expected behavior that odd chroma info will just drop off and do something like use the previous 2x2 block's value, or are odd-width YUV images just not supported? If the existing behavior is expected, is there an option I can use to round up and look at the chroma information at the edge of my image?