Re: C : how to export raw YUV to a file ?

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 10/07/04


Date: Wed, 6 Oct 2004 18:13:16 -0400 (EDT)


On Wed, 6 Oct 2004, DEMAINE Benoit-Pierre wrote:
[I wrote:]
> | Okay, so you have two basic questions here: (1) How do I write an image
> | to disk as a PNG-format file? (2) How do I deal with YUV images, as
> | opposed to the more "canonical" (in most circles) RGB encoding?
>
> I thought that some lib could directly export from YUV to png. Looks
> like no.

   I'm sure /some/ "lib" can. A library is just a bunch of routines
someone else wrote, you know. If you can write a routine to save YUV
images as PNG, then so can someone else---and if someone else already
has, then that would be the library you want. :)

> ~From that, I have a book which explains how to convert YUV<=>RGB. But
> since I am learning clean coding, instead of doing by hand, I thought it
> d be a good idear to use dedicated tools. => which lib can convert YUV
> in anything else ?

   ImageMagick is the classic image-manipulation library, as far as I'm
concerned. So it can do this. Whether its interface is simple enough
for you to feel comfortable using it... that's another story!
   But really, the RGB->YUV->RGB conversions are so simple you ought not
to be uncomfortable writing them from scratch.

> | (1) Use libpng, a free PNG library available on the Web. There's a
> | bare-bones example C source on my website:
> | http://www.contrib.andrew.cmu.edu/~ajo/free-software/simple_png.c
> | but depending on your level of expertise, it may be easier for you to
> | read the libpng documentation yourself than try to figure out what my C
> | routines are doing. ;)
>
> 160 lines example is what you call simple ... I dont want you to send me
> a 'difficult' example ^^

   Well, that's why I keep the simple example around... so I will hardly
ever need a "difficult" one! :) Really, the program has only two
functions: ReadPNG and WritePNG. They read and write PNG-compressed color
images. That's all. You don't need to understand the details if you
don't want to. In fact, I don't understand most of libpng myself, and
I doubt the "simple" example is really as simple as it could be, with all
its cargo-cult aspects.

> let study the content :
> what
> unsigned char (*data)[3];
> exactly mean ? array of pointers ?

   Pointer to arrays. In C, you read expressions and declarations "from
the inside outward." So 'data'... is a '*'... to 'unsigned char [3]'.
Each three 'unsigned char' values are the R, G, and B components of a
single pixel. Thus 'data' points to a (bunch of contiguous) pixels;
that is to say, an image.

> I do not really understand how you read the file, or more precisely, how
> you read the content of the picture.

   That's what all the libpng library calls are for. There's no I/O going
on in the code in "simple_png.c". All the I/O is happening way down deep
inside libpng, and I'm just asking libpng to tell me what it finds out.

> oh : (*data) = malloc(*w * *h * sizeof **data);
> that is interesting ... but I still do not understand what type is data :/

   That's intentional. ;)

> the part I am focussing on is:
> ~ for (j=0; j < h; ++j)
> ~ row_pointers[j] = (png_byte*)data[j*w+0];
>
> so: data look to be an array of something, but I still do not understand
> how many dimensions it has : 1 or 2 ?

   'data' is a pointer, not an array, so it has no "dimensions." It is
pointing to a list of pixels, which you can think of as one-dimensional...
but in a computer's memory, /everything/ is one-dimensional, so that won't
help you visualize it. We're interpreting 'data' as a pointer to a
two-dimensional (w-by-h) array of pixels, where each pixel is represented
as a one-dimensional (3-element) array of 'unsigned char' (R,G,B triple).
I hope that helps. If not, take a look at some of the other image
libraries in that same directory on my website (ImageFmtc, ImagePalc,
ImageBWc)---they all use that same internal format.

> in the read func, why the hell do you read data ? I thought you would
> write it !

   Um... you're joking, right? Why do I read data in the function called
'ReadPNG'?? ^^^^
  ^^^^

> and in write, you also always read it ... what is the use of a var you
> always read ???

   In 'WritePNG', I'm calling 'fopen' with the string "wb", and I'm calling
the libpng routine 'png_write_image'. I think it's pretty clear I'm
/writing/ data. If you are still confused, I encourage you to be more
specific about what you think is going on.

> | (a) Convert the YUV data to RGB data and write it to the file as RGB.
> | You can find conversion formulas on the Web. This is a slightly lossy
> | procedure, which means you won't be able to get back exactly the YUV
> | values you started with. But that may not be a big deal.
>
> I dont want to store RGB in file. I need a compessed format.

   You can compress RGB data. You really have to understand this: The
encoding of your color information and the compression format of your file
are completely orthogonal! You know the WinZip compression program?
Think of writing down a list of RGB values in a text file and then running
it through WinZip. That's like PNG compression.[1] Now, you could just
as easily write down a list of YUV values and compress them with WinZip,
and you'd get the same compression factor as if your data were RGB.[2]
That's like what I describe below...

> | (b) Just pretend YUV is RGB. For example, if you have a YUV triple
> [...]
> | as you remember that R=Y, G=U, and B=V.
>
> my YUV is compleetely different than RGB. I cant assume what you say.
> y= light, U = green/red V=blue/red ( IIRC)

   Right. But you can /pretend/ that Y means "red" instead of "light"...
or, if you prefer this way of speaking, you can pretend that "R" means
"light" instead of "red". As I explained above, you're just going to
write down YUV values in your file instead of RGB values. You're going
to pretend that the PNG compressor expects YUV values instead of RGB
values, or, if you prefer this way of speaking, you're going to pretend
that your YUV values /actually are/ RGB values. The compression and
file-writing will take place just the same way.

> | (c) Find an image format that supports YUV colorspace directly. AFAIK,
> | the PNG format does not do YUV. I bet TIFF does, but TIFF is kind of
> | cumbersome, in my opinion. Of course, you could also just dump the raw
> | YUV data, if you didn't need to be able to see the pretty pictures
> | outside of the application you're writing.
>
> I could _optionally_ write data to a .yuv file, but I do not find any
> documentation about their headers.

   I don't think there's any standard for ".yuv" files. I think they're
like ".dat" or ".raw" files: it's just a neat way of documenting to the
user, "Hey, this file contains some kind of YUV data!"

   Remember, ask if you have any questions. And look at the other files
in www.contrib.andrew.cmu.edu/~ajo/free-software before giving up on
understanding how the pointer object 'data' works.

HTH,
-Arthur



Relevant Pages

  • Re: C : how to export raw YUV to a file ?
    ... > encoding of your color information and the compression format of your file ... You know the WinZip compression program? ... > of writing down a list of RGB values in a text file and then running it ... > as easily write down a list of YUV values and compress them with WinZip, ...
    (comp.programming)
  • Re: The Challenge! was: optimisation of images - help?
    ... The sample screenshot you posted is RGB and has more than 256 colours. ... compression. ... I don't see a link to the optimised png you mention above. ... You can reduce the number of colours further and retain some "smoothness" by different dithering methods, but that means that less compression is possible. ...
    (rec.photo.digital.slr-systems)
  • Re: The Challenge! was: optimisation of images - help?
    ... The sample screenshot you posted is RGB and has more than 256 colours. ... The compression here has caused pretty serious degradation of the image. ... I don't see a link to the optimised png you mention above. ... You can reduce the number of colours further and retain some "smoothness" by different dithering methods, but that means that less compression is possible. ...
    (rec.photo.digital.slr-systems)
  • Re: about Color Format transformation
    ... it will accept RGB or YUV in and allow RGB out only. ... Having said that your code will not reject YUV output if a downstream ... > Hi Iain ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Need help in converting YUV to RGB using OV7620
    ... Hope you guys can give me some advise on converting the YUV ... THEN consider doing colour conversion. ... the format is best described spatially as ... You cannot work out true RGB until 2nd Y and V has been acquired, ...
    (comp.arch.embedded)