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); }