diff options
author | Benjamin Otte <otte@redhat.com> | 2010-02-24 22:46:11 +0100 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-07-07 10:23:04 -0400 |
commit | 698e3a35b7351654d5227a90eb9c58b3a513c2b5 (patch) | |
tree | ee6c8f435382dbf2ac457cc09284c8f851027683 | |
parent | 63ec65fbee685c8e3cf882abb69a31072b92e556 (diff) |
Add packed YUV formats
YUY2, YVYU, UYVY and VYUY
-rw-r--r-- | pixman/pixman-access.c | 202 | ||||
-rw-r--r-- | pixman/pixman-format.c | 6 | ||||
-rw-r--r-- | pixman/pixman.h | 7 |
3 files changed, 176 insertions, 39 deletions
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 87eb8cc0..c1713e5a 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -1107,24 +1107,70 @@ fetch_scanline_yuy2 (pixman_image_t *image, for (i = 0; i < width; i++) { - int16_t y, u, v; - int32_t r, g, b; - - y = ((uint8_t *) bits)[(x + i) << 1] - 16; - u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128; - v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; - *buffer++ = 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); + (((uint8_t *) bits)[(x + i) << 1] << 16) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] << 8) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] ); + } +} + +static void +fetch_scanline_yvyu (pixman_image_t *image, + int x, + int line, + int width, + uint32_t * buffer, + const uint32_t *mask) +{ + const uint32_t *bits = image->bits.bits + image->bits.rowstride * line; + int i; + + for (i = 0; i < width; i++) + { + *buffer++ = 0xff000000 | + (((uint8_t *) bits)[(x + i) << 1] << 16) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] << 8) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] ); + } +} + +static void +fetch_scanline_uyvy (pixman_image_t *image, + int x, + int line, + int width, + uint32_t * buffer, + const uint32_t *mask) +{ + const uint32_t *bits = image->bits.bits + image->bits.rowstride * line; + int i; + + for (i = 0; i < width; i++) + { + *buffer++ = 0xff000000 | + (((uint8_t *) bits)[ ((x + i) << 1) + 1] << 16) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) ] << 8) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 2] ); + } +} + +static void +fetch_scanline_vyuy (pixman_image_t *image, + int x, + int line, + int width, + uint32_t * buffer, + const uint32_t *mask) +{ + const uint32_t *bits = image->bits.bits + image->bits.rowstride * line; + int i; + + for (i = 0; i < width; i++) + { + *buffer++ = 0xff000000 | + (((uint8_t *) bits)[ ((x + i) << 1) + 1] << 16) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) + 2] << 8) | + (((uint8_t *) bits)[(((x + i) << 1) & - 4) ] ); } } @@ -1827,26 +1873,49 @@ fetch_pixel_yuy2 (bits_image_t *image, { const uint32_t *bits = image->bits + image->rowstride * line; - int16_t y, u, v; - int32_t r, g, b; - - y = ((uint8_t *) bits)[offset << 1] - 16; - u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128; - v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; + return 0xff000000 | + (((uint8_t *) bits)[ offset << 1 ] << 16) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 1] << 8) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 3] ); +} + +static uint32_t +fetch_pixel_yvyu (bits_image_t *image, + int offset, + int line) +{ + const uint32_t *bits = image->bits + image->rowstride * line; - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; + return 0xff000000 | + (((uint8_t *) bits)[ offset << 1 ] << 16) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 3] << 8) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 1] ); +} + +static uint32_t +fetch_pixel_uyvy (bits_image_t *image, + int offset, + int line) +{ + const uint32_t *bits = image->bits + image->rowstride * line; - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; + return 0xff000000 | + (((uint8_t *) bits)[ (offset << 1) + 1] << 16) | + (((uint8_t *) bits)[((offset << 1) & - 4) ] << 8) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 2] ); +} + +static uint32_t +fetch_pixel_vyuy (bits_image_t *image, + int offset, + int line) +{ + const uint32_t *bits = image->bits + image->rowstride * line; return 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); + (((uint8_t *) bits)[ (offset << 1) + 1] << 16) | + (((uint8_t *) bits)[((offset << 1) & - 4) + 2] << 8) | + (((uint8_t *) bits)[((offset << 1) & - 4) ] ); } static uint32_t @@ -2798,6 +2867,63 @@ store_scanline_y444 (bits_image_t * image, } } +#define SUBSAMPLED(name,Y1,U,Y2,V) \ +static void \ +store_scanline_ ## name (bits_image_t * image, \ + int x, \ + int y, \ + int width, \ + const uint32_t *values) \ +{ \ + uint8_t *bits = (uint8_t *) (image->bits + image->rowstride * y + x / 2); \ + int i; \ +\ + if (x & 1) \ + { \ + bits[Y2] = values[0] >> 16; \ + bits[U ] = (bits[U] + ((values[0] >> 8) & 0xff)) >> 1; \ + bits[V ] = (bits[V] + ( values[0] & 0xff)) >> 1; \ + width--; \ + x++; \ + values++; \ + bits += 4; \ + } \ + if (width & 1) \ + { \ + pixman_bool_t last_pixel = (x + width == image->width); \ +\ + width--; \ +\ + if (last_pixel) \ + { \ + bits[2 * width + Y1] = values[width] >> 16; \ + bits[2 * width + U ] = values[width] >> 8; \ + bits[2 * width + V ] = values[width]; \ + } \ + else \ + { \ + bits[2 * width + Y1] = values[width] >> 16; \ + bits[2 * width + U ] = ((values[width] >> 8) + bits[2 * width + U]) >> 1; \ + bits[2 * width + V ] = ((values[width] ) + bits[2 * width + V]) >> 1; \ + } \ + } \ +\ + for (i = 0; i < width; i += 2) \ + { \ + bits[Y1] = values[i] >> 16; \ + bits[Y2] = values[i + 1] >> 16; \ + bits[U ] = ((values[i] & 0xff00) + (values[i + 1] & 0xff00)) >> 9; \ + bits[V ] = ((values[i] & 0x00ff) + (values[i + 1] & 0x00ff)) >> 1; \ +\ + bits += 4; \ + } \ +} + +SUBSAMPLED(yuy2, 0, 1, 2, 3) +SUBSAMPLED(yvyu, 0, 3, 2, 1) +SUBSAMPLED(uyvy, 1, 0, 3, 2) +SUBSAMPLED(vyuy, 1, 2, 3, 0) + /* * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit * store proc. Despite the type, this function expects a uint64_t buffer. @@ -2995,11 +3121,13 @@ static const format_info_t accessors[] = /* planar formats */ FORMAT_INFO (y444), +/* packed formats */ + FORMAT_INFO (yuy2), + FORMAT_INFO (yvyu), + FORMAT_INFO (uyvy), + FORMAT_INFO (vyuy), + /* YUV formats */ - { PIXMAN_yuy2, - fetch_scanline_yuy2, fetch_scanline_generic_64, - fetch_pixel_yuy2, fetch_pixel_generic_64, - NULL, NULL }, { PIXMAN_yv12, fetch_scanline_yv12, fetch_scanline_generic_64, diff --git a/pixman/pixman-format.c b/pixman/pixman-format.c index 979e375b..b9aeed75 100644 --- a/pixman/pixman-format.c +++ b/pixman/pixman-format.c @@ -169,8 +169,12 @@ static const format_info_t format_infos[] = { { PIXMAN_g1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* planar formats */ { PIXMAN_y444, TRUE, TRUE, 3, PIXMAN_COLOR_SPACE_YCBCR_SD, alloc_y444 }, + /* packed formats */ + { PIXMAN_yuy2, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_YCBCR_SD, alloc_bits }, + { PIXMAN_yvyu, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_YCBCR_SD, alloc_bits }, + { PIXMAN_uyvy, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_YCBCR_SD, alloc_bits }, + { PIXMAN_vyuy, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_YCBCR_SD, alloc_bits }, /* YUV formats */ - { PIXMAN_yuy2, TRUE, FALSE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, { PIXMAN_yv12, TRUE, FALSE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits } }; diff --git a/pixman/pixman.h b/pixman/pixman.h index c6301d78..5d86084d 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -726,8 +726,13 @@ typedef enum { /* planar formats */ PIXMAN_y444 = PIXMAN_FORMAT(12,PIXMAN_TYPE_PLANAR,0,0,0,1), +/* packed formats */ + PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_PACKED,0,0,0,0), + PIXMAN_yvyu = PIXMAN_FORMAT(16,PIXMAN_TYPE_PACKED,0,0,0,1), + PIXMAN_uyvy = PIXMAN_FORMAT(16,PIXMAN_TYPE_PACKED,0,0,0,2), + PIXMAN_vyuy = PIXMAN_FORMAT(16,PIXMAN_TYPE_PACKED,0,0,0,3), + /*deprecated */ - PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0), PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0) } pixman_format_code_t; |