summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@tungstengraphics.com>2008-07-16 19:36:36 +0900
committerJosé Fonseca <jrfonseca@tungstengraphics.com>2008-07-16 19:36:36 +0900
commit78d18bb690d47eba6d13f8f154e64f1c33ef29fd (patch)
treecfc0c75191d75068fd4cb9640cbbabb1166869e7
parent70b1ff9ff39ca29bdbd25b31ebb183eea683d625 (diff)
gallium: ycbcr_get_tile_rgba allow reading an uneven number of pixels from yuv surfaces.
-rw-r--r--src/gallium/auxiliary/util/p_tile.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 1a1a2d96cc6..580a95568e3 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -632,13 +632,10 @@ ycbcr_get_tile_rgba(ushort *src,
const float scale = 1.0f / 255.0f;
unsigned i, j;
- /* we're assuming we're being asked for an even number of texels */
- assert((w & 1) == 0);
-
for (i = 0; i < h; i++) {
float *pRow = p;
/* do two texels at a time */
- for (j = 0; j < w; j += 2, src += 2) {
+ for (j = 0; j < (w & ~1); j += 2, src += 2) {
const ushort t0 = src[0];
const ushort t1 = src[1];
const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
@@ -676,6 +673,33 @@ ycbcr_get_tile_rgba(ushort *src,
pRow += 4;
}
+ /* do the last texel */
+ if (w & 1) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ pRow[0] = r * scale;
+ pRow[1] = g * scale;
+ pRow[2] = b * scale;
+ pRow[3] = 1.0f;
+ pRow += 4;
+ }
p += dst_stride;
}
}