[Theora] theora2rgb 0.1 fixed

David Kment davidkment at web.de
Wed Nov 30 11:03:22 PST 2005


hi again!

thanks to Makoto Setoh, this is finally working properly :)

this is just an example, and needs some more testing.

---david

/*
* theora2rgb 0.1
*
* Converts a yuv_buffer filled by theora_decode_YUVout to
* a 24bit RGB buffer, ordered R-G-B, interleaved.
* Currently, the color conversion is not very efficient.
* In addition, encoder specified color is ignored, resulting colors
* are a little red-weighted, and no resolution scaling is done.
*/

#include <stdio.h>
#include "theora/theora.h"

#define clip(a) (((a)&256) ? ((a)>>31)^(-1) : (a))

void theoraToRGB(theora_info ti, yuv_buffer yuv) {

  // create yuvbuf in interleaved YUV format.

  int i, j, crop_offset = 0;

  unsigned char* yuvbuf = (unsigned char *)malloc(ti.width * ti.height * 3);
  unsigned char* rgbbuf = (unsigned char *)malloc(ti.width * ti.height * 3);

  crop_offset=ti.offset_x+yuv.y_stride*ti.offset_y;

  int k=0;
  i = 0;
  while(i<ti.height) {
    for(j=0;j<ti.width;j++) {
      yuvbuf[k]=yuv.y[crop_offset+yuv.y_stride*i+j];
      k += 3;
    }
    i++;
  }

  crop_offset=(ti.offset_x/2)+(yuv.uv_stride)*(ti.offset_y/2);

  k=1;
  i=0;
  while(i<ti.height/2) {
    for(j=0;j<ti.width/2;j++) {
      yuvbuf[k++]=yuv.u[crop_offset+yuv.uv_stride*i+j];
      yuvbuf[k++]=yuv.v[crop_offset+yuv.uv_stride*i+j];
      k++;
      yuvbuf[k++]=yuv.u[crop_offset+yuv.uv_stride*i+j];
      yuvbuf[k++]=yuv.v[crop_offset+yuv.uv_stride*i+j];
      k++;
    }
    for(j=0;j<ti.width/2;j++) {
      yuvbuf[k++]=yuv.u[crop_offset+yuv.uv_stride*i+j];
      yuvbuf[k++]=yuv.v[crop_offset+yuv.uv_stride*i+j];
      k++;
      yuvbuf[k++]=yuv.u[crop_offset+yuv.uv_stride*i+j];
      yuvbuf[k++]=yuv.v[crop_offset+yuv.uv_stride*i+j];
      k++;
    }
    i++;
  }

  // convert yuvbuf to rgbbuf, interleaved RGB.

  int offset = 0, y, u, v;

  while(offset < ti.width * ti.height * 3) {

    y = yuvbuf[offset++] - 16;
    u = yuvbuf[offset++] - 128;
    v = yuvbuf[offset++] - 128;

    offset -= 3;

    rgbbuf[offset++] = clip((298 * y + 409 * v + 128) >> 8);
    rgbbuf[offset++] = clip((298 * y + 100 * u - 208 * v + 128) >> 8);
    rgbbuf[offset++] = clip((298 * y + 516 * u + 128) >> 8);
  }

  // just for testing: dump RGB data to RAW file

  FILE * ofp = fopen("rgb.raw", "wb");
  fwrite(rgbbuf, sizeof(char), ti.width * ti.height * 3, ofp);

  fclose(ofp);

  free(yuvbuf);
  free(rgbbuf);
}



More information about the Theora mailing list