Hi, I'm new to Magick++ and I'm struggling a bit to get this to work.
I would like to read a raw UYVY 422 8bits (planar or interlaced) image
and get the Y U and V planes without any scaling from the original image.
Is there any way to access the real data that came from the file, before
any scaling or conversion to other color spaces is done (8 bit luma and chroma samples) ?
I've got something working with the following:
...
Image img;
img.colorSpace(MagickCore::YCbCrColorspace);
img.size("1920x1080");
img.depth(8);
img.magick("UYVY");
img.read(filename);
Magick::Color c = img.pixelColor(0,0);
cerr << c1.redQuantum() << " " << c1.greenQuantum() << " " << c1.blueQuantum() << endl;
...
redQuantum() is giving me (Y/255 * 65535)
greenQuantum() is giving me (U/255 * 65535)
but blueQuantum() doesn't match the same scaling scheme, and I can't find out how to get V.
I tried with ColorYUV as well, but the y(), v() and u() functions are already scaled and shifted values,
and I would like to access the unsigned 8 bit integer values coming from the file.
Any help would be appreciated,
Thanks!
Read Y U V planes from YUV file
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Read Y U V planes from YUV file
That is because in memory all images are stored using the compile time 'Quantum Range' or Q bit depth. Q16 in this case.
see IM examples, Quality vs Depth
http://www.imagemagick.org/Usage/basics/#quality
see IM examples, Quality vs Depth
http://www.imagemagick.org/Usage/basics/#quality
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: Read Y U V planes from YUV file
Thanks for you reply Anthony,
then in the following code, what is exactly the meaning of "img.depth(8)" ?
...
Image img;
img.colorSpace(MagickCore::YCbCrColorspace);
img.size("1920x1080");
img.depth(8);
img.magick("UYVY");
img.read(filename);
...
Ok, this works in the command line, same Q16 build:
convert -depth 8 -size 1920x1080 -sampling-factor 4:2:2 -interlace plane -colorspace YUV file.yuv out.png
How can you reproduce the same command line in Magick++ ?
==============================================================
Coming back to my problem, if there is no solution to the previous problem,
now I am trying to feed an image with a blob with the data (again 8 bits YUV 422 planar data),
but the read method (or the constructor) keeps failing (throwing different exceptions depending
on the magick I use).
Let's assume that you have in a Blob, a 1920x1080 8 bits YUV frame, in 422 planar, which size is 4147200 bytes,
and you want to create a PNG version ?
I have tried:
Blob b((void*)data_ptr, size_bytes);
Image out(b,Geometry(w,h),8,"YUV"); // and "YUV:4:2:2" and with and without 8
someone asked this very same question in other thread, but no replies so far for a while...
Thanks,
then in the following code, what is exactly the meaning of "img.depth(8)" ?
...
Image img;
img.colorSpace(MagickCore::YCbCrColorspace);
img.size("1920x1080");
img.depth(8);
img.magick("UYVY");
img.read(filename);
...
Ok, this works in the command line, same Q16 build:
convert -depth 8 -size 1920x1080 -sampling-factor 4:2:2 -interlace plane -colorspace YUV file.yuv out.png
How can you reproduce the same command line in Magick++ ?
==============================================================
Coming back to my problem, if there is no solution to the previous problem,
now I am trying to feed an image with a blob with the data (again 8 bits YUV 422 planar data),
but the read method (or the constructor) keeps failing (throwing different exceptions depending
on the magick I use).
Let's assume that you have in a Blob, a 1920x1080 8 bits YUV frame, in 422 planar, which size is 4147200 bytes,
and you want to create a PNG version ?
I have tried:
Blob b((void*)data_ptr, size_bytes);
Image out(b,Geometry(w,h),8,"YUV"); // and "YUV:4:2:2" and with and without 8
someone asked this very same question in other thread, but no replies so far for a while...
Thanks,
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Read Y U V planes from YUV file
In that case the depth 8 is the depth for reading the raw data format. In other words that values are in bytes.francholi wrote:Thanks for you reply Anthony,
then in the following code, what is exactly the meaning of "img.depth(8)" ?
...
Image img;
img.colorSpace(MagickCore::YCbCrColorspace);
img.size("1920x1080");
img.depth(8);
img.magick("UYVY");
img.read(filename);
...
Ok, this works in the command line, same Q16 build:
convert -depth 8 -size 1920x1080 -sampling-factor 4:2:2 -interlace plane -colorspace YUV file.yuv out.png
If it was depth 16, then you also have the option of specifying the 'enden' of the values (LSB or MBS, for least/most significate byte order).
You probably could do better than I could for that. I can read C++ code but have never needed to program in itHow can you reproduce the same command line in Magick++ ?
I'm a little old fashioned. I like shell, C, Perl, and very occasionally PHP. I've never had a real use for C++, Ruby, Java, etc.
Code: Select all
Coming back to my problem, if there is no solution to the previous problem,
now I am trying to feed an image with a blob with the data (again 8 bits YUV 422 planar data),
but the read method (or the constructor) keeps failing (throwing different exceptions depending
on the magick I use).
Others may be able to help you more than I can for this.
You could always look at the coder!
Very Old Programmers Motto wrote:Use the source Luke!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: Read Y U V planes from YUV file
Thanks again for your reply,
I think I found some issues that I managed to solve with the conversion.
As you said, I went down the road to the yuv.c:98 ReadYUVImage() function, and the
thing is that it's doing 4:1:1 by default (at least with the bit of code
that I was using) and crashing my app because the blob is saying it's way
bigger (4:2:2).
So, if you don't specify anything, it's 4:1:1 unless I am missing something here.
The following code worked for me:
imInf->sampling_factor will get "deleted" inside IM, so don't provide a "const char*" there.)
If you don't change the sampling factor and the interlace it will not work.
Is this a bug ?
Anyway, thanks for your time!
I think I found some issues that I managed to solve with the conversion.
As you said, I went down the road to the yuv.c:98 ReadYUVImage() function, and the
thing is that it's doing 4:1:1 by default (at least with the bit of code
that I was using) and crashing my app because the blob is saying it's way
bigger (4:2:2).
So, if you don't specify anything, it's 4:1:1 unless I am missing something here.
The following code worked for me:
Code: Select all
Blob b(tempImage, size_bytes); // blob with 8 bits data (full yuv planar image)
Image img;
img.size("1920x1080");
img.depth(8);
img.magick("YUV");
img.colorSpace(MagickCore::YUVColorspace);
MagickCore::ImageInfo *imInf = img.imageInfo();
char* s = new char[6];
strcpy(s,"4:2:2\0");
imInf->sampling_factor = s;
imInf->interlace = MagickCore::PlaneInterlace;
img.read(b);
img.magick("PNG");
img.write(filename);
If you don't change the sampling factor and the interlace it will not work.
Is this a bug ?
Anyway, thanks for your time!