[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