Sample program for converting RGB to YCbCr and vice versa.
/*
encode.cpp
Contains functions to convert an RGB frame to YCbCr and to save the converted data.
See 'http://www.webkinesia.com/games/vcompress.php'
*/
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "rgb_ybr.h"
extern short width; //image width
extern short height; //image height
//save one YCbCr macroblock.
void save_ybrblocks( YCbCr_MACRO *ycbcr_macro, FILE *fpo )
{
short block, i, j, k, *py;
//save four 8x8 Y sample blocks
for ( block = 0; block < 4; block++ ) {
if ( block < 2 )
py = ( short * ) &ycbcr_macro->Y + 8*block; //points to beginning of block
else
py = (short *)&ycbcr_macro->Y + 128 + 8*(block-2);//points to beginning of block
for ( i = 0; i < 8; i++ ) { //one sample-block
if ( i > 0 ) py += 16; //advance py by 16 ( length of one row )
for ( j = 0; j < 8; j++ ) {
putc ( ( int ) *(py+j),fpo); //save one byte of data
}
}
}
//save one 8x8 Cb block
k = 0;
for ( i = 0; i < 8; ++i ) {
for ( j = 0; j < 8; ++j ) {
putc( ( int ) ycbcr_macro->Cb[k++], fpo );
}
}
//save one 8x8 Cr block
k = 0;
for ( i = 0; i < 8; ++i ) {
for ( j = 0; j < 8; ++j ) {
putc( ( int ) ycbcr_macro->Cr[k++], fpo );
}
}
}
/*
Convert RGB to YCbCr and save the converted data.
width, height are global variables of image.
*/
void encode ( char *image, FILE *fpo )
{
short row, col, i, j, r;
RGB macro16x16[256]; //16x16 pixel macroblock; assume 24-bit for each RGB pixel
YCbCr_MACRO ycbcr_macro; //macroblock for YCbCr samples
RGB *p; //pointer to an RGB pixel
static int nframe = 0;
for ( row = 0; row < height; row += 16 ) {
for ( col = 0; col < width; col += 16 ) {
p = ( RGB *) image + ( row * width + col ); //points to beginning of macroblock
r = 0; //note pointer arithmetic
for ( i = 0; i < 16; ++i ) {
for ( j = 0; j < 16; ++j ) {
macro16x16[r++] = (RGB) *p++;
}
p += ( width - 16 ); //points to next row within macroblock ( note pointer arithmetic )
}
macroblock2ycbcr ( macro16x16, &ycbcr_macro ); //convert from RGB to YCbCr
save_ybrblocks( &ycbcr_macro, fpo ); //save one YCbCr macroblock
} //for col
} //for row
}