75 lines
3.0 KiB
C
Executable File
75 lines
3.0 KiB
C
Executable File
/**
|
|
* TheoraPlay; multithreaded Ogg Theora/Ogg Vorbis decoding.
|
|
*
|
|
* Please see the file LICENSE.txt in the source's root directory.
|
|
*
|
|
* This file written by Ryan C. Gordon.
|
|
*/
|
|
|
|
#if !THEORAPLAY_INTERNAL
|
|
#error Do not include this in your app. It is used internally by TheoraPlay.
|
|
#endif
|
|
|
|
static unsigned char *THEORAPLAY_CVT_FNNAME_420(const th_info *tinfo,
|
|
const th_ycbcr_buffer ycbcr)
|
|
{
|
|
const int w = tinfo->pic_width;
|
|
const int h = tinfo->pic_height;
|
|
unsigned char *pixels = (unsigned char *) malloc(w * h * 4);
|
|
if (pixels)
|
|
{
|
|
unsigned char *dst = pixels;
|
|
const int ystride = ycbcr[0].stride;
|
|
const int cbstride = ycbcr[1].stride;
|
|
const int crstride = ycbcr[2].stride;
|
|
const int yoff = (tinfo->pic_x & ~1) + ystride * (tinfo->pic_y & ~1);
|
|
const int cboff = (tinfo->pic_x / 2) + (cbstride) * (tinfo->pic_y / 2);
|
|
const unsigned char *py = ycbcr[0].data + yoff;
|
|
const unsigned char *pcb = ycbcr[1].data + cboff;
|
|
const unsigned char *pcr = ycbcr[2].data + cboff;
|
|
int posx, posy;
|
|
|
|
for (posy = 0; posy < h; posy++)
|
|
{
|
|
for (posx = 0; posx < w; posx++)
|
|
{
|
|
// http://www.theora.org/doc/Theora.pdf, 1.1 spec,
|
|
// chapter 4.2 (Y'CbCr -> Y'PbPr -> R'G'B')
|
|
// These constants apparently work for NTSC _and_ PAL/SECAM.
|
|
const float yoffset = 16.0f;
|
|
const float yexcursion = 219.0f;
|
|
const float cboffset = 128.0f;
|
|
const float cbexcursion = 224.0f;
|
|
const float croffset = 128.0f;
|
|
const float crexcursion = 224.0f;
|
|
const float kr = 0.299f;
|
|
const float kb = 0.114f;
|
|
|
|
const float y = (((float) py[posx]) - yoffset) / yexcursion;
|
|
const float pb = (((float) pcb[posx / 2]) - cboffset) / cbexcursion;
|
|
const float pr = (((float) pcr[posx / 2]) - croffset) / crexcursion;
|
|
const float r = (y + (2.0f * (1.0f - kr) * pr)) * 255.0f;
|
|
const float g = (y - ((2.0f * (((1.0f - kb) * kb) / ((1.0f - kb) - kr))) * pb) - ((2.0f * (((1.0f - kr) * kr) / ((1.0f - kb) - kr))) * pr)) * 255.0f;
|
|
const float b = (y + (2.0f * (1.0f - kb) * pb)) * 255.0f;
|
|
|
|
*(dst++) = (unsigned char) ((r < 0.0f) ? 0.0f : (r > 255.0f) ? 255.0f : r);
|
|
*(dst++) = (unsigned char) ((g < 0.0f) ? 0.0f : (g > 255.0f) ? 255.0f : g);
|
|
*(dst++) = (unsigned char) ((b < 0.0f) ? 0.0f : (b > 255.0f) ? 255.0f : b);
|
|
#if THEORAPLAY_CVT_RGB_ALPHA
|
|
*(dst++) = 0xFF;
|
|
#endif
|
|
} // for
|
|
|
|
// adjust to the start of the next line.
|
|
py += ystride;
|
|
pcb += cbstride * (posy % 2);
|
|
pcr += crstride * (posy % 2);
|
|
} // for
|
|
} // if
|
|
|
|
return pixels;
|
|
} // THEORAPLAY_CVT_FNNAME_420
|
|
|
|
// end of theoraplay_cvtrgb.h ...
|
|
|