Skip to content

Latest commit

 

History

History
74 lines (65 loc) · 2.99 KB

theoraplay_cvtrgb.h

File metadata and controls

74 lines (65 loc) · 2.99 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* 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 ...