Commit 8fbc70bb authored by Michel Lespinasse's avatar Michel Lespinasse
Browse files

Color conversion helper library.

The .c and .h files used to be in libvo/ and have been moved without change
(for now)
parent 00b6637d
AM_CFLAGS = $(OPT_CFLAGS) $(LIBMPEG2_CFLAGS)
lib_LTLIBRARIES = libmpeg2convert.la
libmpeg2convert_la_SOURCES = rgb.c
libmpeg2convert_la_LIBADD = libmpeg2convertarch.la
libmpeg2convert_la_LDFLAGS = -no-undefined
noinst_LTLIBRARIES = libmpeg2convertarch.la
libmpeg2convertarch_la_SOURCES = rgb_mmx.c rgb_vis.c
libmpeg2convertarch_la_CFLAGS = $(OPT_CFLAGS) $(ARCH_OPT_CFLAGS) $(LIBMPEG2_CFLAGS)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmpeg2convert.pc
EXTRA_DIST = convert_internal.h
/*
* convert_internal.h
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
typedef struct {
uint8_t * rgb_ptr;
int width;
int y_stride, rgb_stride, y_increm, uv_increm, rgb_increm;
int chroma420;
int dither_offset, dither_stride;
int y_stride_frame, uv_stride_frame, rgb_stride_frame, convert420;
} convert_rgb_t;
typedef void yuv2rgb_copy (void * id, uint8_t * const * src,
unsigned int v_offset);
yuv2rgb_copy * yuv2rgb_init_mmxext (int bpp, int mode,
const mpeg2_sequence_t * seq);
yuv2rgb_copy * yuv2rgb_init_mmx (int bpp, int mode,
const mpeg2_sequence_t * seq);
yuv2rgb_copy * yuv2rgb_init_vis (int bpp, int mode,
const mpeg2_sequence_t * seq);
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libmpeg2convert
Description: libmpeg2 helper functions for converting to various formats.
Version: @VERSION@
Libs: -L${libdir} -lmpeg2convert
Cflags: -I${includedir}/@PACKAGE@
/*
* yuv2rgb.c
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "attributes.h"
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "mpeg2.h"
#include "convert.h"
#include "convert_internal.h"
static uint32_t matrix_coefficients = 6;
static const int32_t Inverse_Table_6_9[8][4] = {
{117504, 138453, 13954, 34903}, /* no sequence_display_extension */
{117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
{104597, 132201, 25675, 53279}, /* unspecified */
{104597, 132201, 25675, 53279}, /* reserved */
{104448, 132798, 24759, 53109}, /* FCC */
{104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
{104597, 132201, 25675, 53279}, /* SMPTE 170M */
{117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
};
static const uint8_t dither[] ATTR_ALIGN(32) = {
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35,
3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62,
3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62,
3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62,
3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62,
19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26,
19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26,
19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26,
19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26,
0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69,
0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69,
0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69,
0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69,
16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33,
16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33,
16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33,
16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33,
4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60,
4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60,
4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60,
4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60,
20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23,
20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23,
20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23,
20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35,
15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35
};
static const uint8_t dither_temporal[64] = {
0x00, 0x20, 0x21, 0x01, 0x40, 0x60, 0x61, 0x41,
0x42, 0x62, 0x63, 0x43, 0x02, 0x22, 0x23, 0x03,
0x80, 0xa0, 0xa1, 0x81, 0xc0, 0xe0, 0xe1, 0xc1,
0xc2, 0xe2, 0xe3, 0xc3, 0x82, 0xa2, 0xa3, 0x83,
0x84, 0xa4, 0xa5, 0x85, 0xc4, 0xe4, 0xe5, 0xc5,
0xc6, 0xe6, 0xe7, 0xc7, 0x86, 0xa6, 0xa7, 0x87,
0x04, 0x24, 0x25, 0x05, 0x44, 0x64, 0x65, 0x45,
0x46, 0x66, 0x67, 0x47, 0x06, 0x26, 0x27, 0x07
};
void * table_rV[256];
void * table_gU[256];
int table_gV[256];
void * table_bU[256];
#define RGB(type,i) \
U = pu[i]; \
V = pv[i]; \
r = (type *) table_rV[V]; \
g = (type *) (((uint8_t *)table_gU[U]) + table_gV[V]); \
b = (type *) table_bU[U];
#define DST(py,dst,i,j) \
Y = py[i]; \
dst[i] = r[Y] + g[Y] + b[Y];
#define DSTRGB(py,dst,i,j) \
Y = py[i]; \
dst[3*i] = r[Y]; dst[3*i+1] = g[Y]; dst[3*i+2] = b[Y];
#define DSTBGR(py,dst,i,j) \
Y = py[i]; \
dst[3*i] = b[Y]; dst[3*i+1] = g[Y]; dst[3*i+2] = r[Y];
#define DSTDITHER(py,dst,i,j) \
Y = py[i]; \
dst[i] = r[Y+pd[2*i+96*j]] + g[Y-pd[2*i+96*j]] + b[Y+pd[2*i+1+96*j]];
#define DO(x) x
#define SKIP(x)
#define DECLARE_420(func,type,num,DST,DITHER) \
static void func (void * _id, uint8_t * const * src, \
unsigned int v_offset) \
{ \
const convert_rgb_t * const id = (convert_rgb_t *) _id; \
type * dst_1; \
const uint8_t * py_1, * pu, * pv; \
int i; \
DITHER(uint8_t dithpos = id->dither_offset;) \
\
dst_1 = (type *)(id->rgb_ptr + id->rgb_stride * v_offset); \
py_1 = src[0]; pu = src[1]; pv = src[2]; \
\
i = 8; \
do { \
const uint8_t * py_2; \
int j, U, V, Y; \
const type * r, * g, * b; \
type * dst_2; \
DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \
\
dst_2 = (type *)((char *)dst_1 + id->rgb_stride); \
py_2 = py_1 + id->y_stride; \
j = id->width; \
do { \
RGB (type, 0) \
DST (py_1, dst_1, 0, 0) \
DST (py_1, dst_1, 1, 0) \
DST (py_2, dst_2, 0, 1) \
DST (py_2, dst_2, 1, 1) \
\
RGB (type, 1) \
DST (py_2, dst_2, 2, 1) \
DST (py_2, dst_2, 3, 1) \
DST (py_1, dst_1, 2, 0) \
DST (py_1, dst_1, 3, 0) \
\
RGB (type, 2) \
DST (py_1, dst_1, 4, 0) \
DST (py_1, dst_1, 5, 0) \
DST (py_2, dst_2, 4, 1) \
DST (py_2, dst_2, 5, 1) \
\
RGB (type, 3) \
DST (py_2, dst_2, 6, 1) \
DST (py_2, dst_2, 7, 1) \
DST (py_1, dst_1, 6, 0) \
DST (py_1, dst_1, 7, 0) \
\
pu += 4; \
pv += 4; \
py_1 += 8; \
py_2 += 8; \
dst_1 += 8 * num; \
dst_2 += 8 * num; \
} while (--j); \
py_1 += id->y_increm; \
pu += id->uv_increm; \
pv += id->uv_increm; \
dst_1 = (type *)((char *)dst_1 + id->rgb_increm); \
DITHER(dithpos += id->dither_stride;) \
} while (--i); \
}
DECLARE_420 (yuv2rgb_c_32_420, uint32_t, 1, DST, SKIP)
DECLARE_420 (yuv2rgb_c_24_rgb_420, uint8_t, 3, DSTRGB, SKIP)
DECLARE_420 (yuv2rgb_c_24_bgr_420, uint8_t, 3, DSTBGR, SKIP)
DECLARE_420 (yuv2rgb_c_16_420, uint16_t, 1, DST, SKIP)
DECLARE_420 (yuv2rgb_c_8_420, uint8_t, 1, DSTDITHER, DO)
#define DECLARE_422(func,type,num,DST,DITHER) \
static void func (void * _id, uint8_t * const * src, \
unsigned int v_offset) \
{ \
const convert_rgb_t * const id = (convert_rgb_t *) _id; \
type * dst; \
const uint8_t * py, * pu, * pv; \
int i; \
DITHER(uint8_t dithpos = id->dither_offset;) \
\
dst = (type *)(id->rgb_ptr + id->rgb_stride * v_offset); \
py = src[0]; pu = src[1]; pv = src[2]; \
\
i = 16; \
do { \
int j, U, V, Y; \
const type * r, * g, * b; \
DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \
\
j = id->width; \
do { \
RGB (type, 0) \
DST (py, dst, 0, 0) \
DST (py, dst, 1, 0) \
\
RGB (type, 1) \
DST (py, dst, 2, 0) \
DST (py, dst, 3, 0) \
\
RGB (type, 2) \
DST (py, dst, 4, 0) \
DST (py, dst, 5, 0) \
\
RGB (type, 3) \
DST (py, dst, 6, 0) \
DST (py, dst, 7, 0) \
\
pu += 4; \
pv += 4; \
py += 8; \
dst += 8 * num; \
} while (--j); \
py += id->y_increm; \
pu += id->uv_increm; \
pv += id->uv_increm; \
dst = (type *)((char *)dst + id->rgb_increm); \
DITHER(dithpos += id->dither_stride;) \
} while (--i); \
}
DECLARE_422 (yuv2rgb_c_32_422, uint32_t, 1, DST, SKIP)
DECLARE_422 (yuv2rgb_c_24_rgb_422, uint8_t, 3, DSTRGB, SKIP)
DECLARE_422 (yuv2rgb_c_24_bgr_422, uint8_t, 3, DSTBGR, SKIP)
DECLARE_422 (yuv2rgb_c_16_422, uint16_t, 1, DST, SKIP)
DECLARE_422 (yuv2rgb_c_8_422, uint8_t, 1, DSTDITHER, DO)
#define DECLARE_444(func,type,num,DST,DITHER) \
static void func (void * _id, uint8_t * const * src, \
unsigned int v_offset) \
{ \
const convert_rgb_t * const id = (convert_rgb_t *) _id; \
type * dst; \
const uint8_t * py, * pu, * pv; \
int i; \
DITHER(uint8_t dithpos = id->dither_offset;) \
\
dst = (type *)(id->rgb_ptr + id->rgb_stride * v_offset); \
py = src[0]; pu = src[1]; pv = src[2]; \
\
i = 16; \
do { \
int j, U, V, Y; \
const type * r, * g, * b; \
DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \
\
j = id->width; \
do { \
RGB (type, 0) \
DST (py, dst, 0, 0) \
RGB (type, 1) \
DST (py, dst, 1, 0) \
RGB (type, 2) \
DST (py, dst, 2, 0) \
RGB (type, 3) \
DST (py, dst, 3, 0) \
RGB (type, 4) \
DST (py, dst, 4, 0) \
RGB (type, 5) \
DST (py, dst, 5, 0) \
RGB (type, 6) \
DST (py, dst, 6, 0) \
RGB (type, 7) \
DST (py, dst, 7, 0) \
\
pu += 8; \
pv += 8; \
py += 8; \
dst += 8 * num; \
} while (--j); \
py += id->y_increm; \
pu += id->y_increm; \
pv += id->y_increm; \
dst = (type *)((char *)dst + id->rgb_increm); \
DITHER(dithpos += id->dither_stride;) \
} while (--i); \
}
DECLARE_444 (yuv2rgb_c_32_444, uint32_t, 1, DST, SKIP)
DECLARE_444 (yuv2rgb_c_24_rgb_444, uint8_t, 3, DSTRGB, SKIP)
DECLARE_444 (yuv2rgb_c_24_bgr_444, uint8_t, 3, DSTBGR, SKIP)
DECLARE_444 (yuv2rgb_c_16_444, uint16_t, 1, DST, SKIP)
DECLARE_444 (yuv2rgb_c_8_444, uint8_t, 1, DSTDITHER, DO)
static void convert_start (void * _id, const mpeg2_fbuf_t * fbuf,
const mpeg2_picture_t * picture,
const mpeg2_gop_t * gop)
{
convert_rgb_t * id = (convert_rgb_t *) _id;
int uv_stride = id->uv_stride_frame;
id->y_stride = id->y_stride_frame;
id->rgb_ptr = fbuf->buf[0];
id->rgb_stride = id->rgb_stride_frame;
id->dither_stride = 32;
id->dither_offset = dither_temporal[picture->temporal_reference & 63];
if (picture->nb_fields == 1) {
uv_stride <<= 1;
id->y_stride <<= 1;
id->rgb_stride <<= 1;
id->dither_stride <<= 1;
id->dither_offset += 16;
if (!(picture->flags & PIC_FLAG_TOP_FIELD_FIRST)) {
id->rgb_ptr += id->rgb_stride_frame;
id->dither_offset += 32;
}
}
id->y_increm = (id->y_stride << id->convert420) - id->y_stride_frame;
id->uv_increm = uv_stride - id->uv_stride_frame;
id->rgb_increm = (id->rgb_stride << id->convert420) - id->rgb_stride_frame;
id->dither_stride <<= id->convert420;
}
static inline int div_round (int dividend, int divisor)
{
if (dividend > 0)
return (dividend + (divisor>>1)) / divisor;
else
return -((-dividend + (divisor>>1)) / divisor);
}
static void yuv2rgb_c_init (int order, int bpp)
{
int i;
uint8_t table_Y[1024];
uint32_t * table_32 = 0;
uint16_t * table_16 = 0;
uint8_t * table_8 = 0;
uint8_t * table_332 = 0;
int entry_size = 0;
void * table_r = 0;
void * table_g = 0;
void * table_b = 0;
int crv = Inverse_Table_6_9[matrix_coefficients][0];
int cbu = Inverse_Table_6_9[matrix_coefficients][1];
int cgu = -Inverse_Table_6_9[matrix_coefficients][2];
int cgv = -Inverse_Table_6_9[matrix_coefficients][3];
for (i = 0; i < 1024; i++) {
int j;
j = (76309 * (i - 384 - 16) + 32768) >> 16;
table_Y[i] = (j < 0) ? 0 : ((j > 255) ? 255 : j);
}
switch (bpp) {
case 32:
table_32 = (uint32_t *) malloc ((197 + 2*682 + 256 + 132) *
sizeof (uint32_t));
entry_size = sizeof (uint32_t);
table_r = table_32 + 197;
table_b = table_32 + 197 + 685;
table_g = table_32 + 197 + 2*682;
for (i = -197; i < 256+197; i++)
((uint32_t *) table_r)[i] =
table_Y[i+384] << ((order == CONVERT_RGB) ? 16 : 0);
for (i = -132; i < 256+132; i++)
((uint32_t *) table_g)[i] = table_Y[i+384] << 8;
for (i = -232; i < 256+232; i++)
((uint32_t *) table_b)[i] =
table_Y[i+384] << ((order == CONVERT_RGB) ? 0 : 16);
break;
case 24:
table_8 = (uint8_t *) malloc ((256 + 2*232) * sizeof (uint8_t));
entry_size = sizeof (uint8_t);
table_r = table_g = table_b = table_8 + 232;
for (i = -232; i < 256+232; i++)
((uint8_t * )table_b)[i] = table_Y[i+384];
break;
case 15:
case 16:
table_16 = (uint16_t *) malloc ((197 + 2*682 + 256 + 132) *
sizeof (uint16_t));
entry_size = sizeof (uint16_t);
table_r = table_16 + 197;
table_b = table_16 + 197 + 685;
table_g = table_16 + 197 + 2*682;
for (i = -197; i < 256+197; i++) {
int j = table_Y[i+384] >> 3;
if (order == CONVERT_RGB)
j <<= ((bpp==16) ? 11 : 10);
((uint16_t *)table_r)[i] = j;
}
for (i = -132; i < 256+132; i++) {
int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);
((uint16_t *)table_g)[i] = j << 5;
}
for (i = -232; i < 256+232; i++) {
int j = table_Y[i+384] >> 3;
if (order == CONVERT_BGR)
j <<= ((bpp==16) ? 11 : 10);
((uint16_t *)table_b)[i] = j;
}
break;
case 8:
table_332 = (uint8_t *) malloc ((197 + 2*682 + 256 + 232 + 71) *
sizeof (uint8_t));
entry_size = sizeof (uint8_t);
table_r = table_332 + 197;
table_g = table_332 + 197 + 682 + 30;
table_b = table_332 + 197 + 2*682;
for (i = -197; i < 256+197+30; i++)
((uint8_t *)table_r)[i] =
(table_Y[i+384] * 7 / 255) << ((order == CONVERT_RGB) ? 5 : 0);
for (i = -132; i < 256+132+30; i++)
((uint8_t *)table_g)[i-30] =
(table_Y[i+384] * 7 / 255) << ((order == CONVERT_RGB) ? 2 : 3);
for (i = -232; i < 256+232+71; i++)
((uint8_t *)table_b)[i] =
(table_Y[i+384] / 85) << ((order == CONVERT_RGB) ? 0 : 6);
break;
}
for (i = 0; i < 256; i++) {
table_rV[i] = (((uint8_t *)table_r) +
entry_size * div_round (crv * (i-128), 76309));
table_gU[i] = (((uint8_t *)table_g) +
entry_size * div_round (cgu * (i-128), 76309));
table_gV[i] = entry_size * div_round (cgv * (i-128), 76309);
table_bU[i] = (((uint8_t *)table_b) +
entry_size * div_round (cbu * (i-128), 76309));
}
}
static void convert_internal (int order, int bpp, const mpeg2_sequence_t * seq,
uint32_t accel, void * arg,
mpeg2_convert_init_t * result)
{
convert_rgb_t * id = (convert_rgb_t *) result->id;
if (!id)
result->id_size = sizeof (convert_rgb_t);
else {
id->width = seq->width >> 3;
id->y_stride_frame = seq->width;
id->uv_stride_frame = seq->chroma_width;
id->rgb_stride_frame = ((bpp + 7) >> 3) * seq->width;
id->chroma420 = id->convert420 = (seq->chroma_height < seq->height);
result->buf_size[0] = id->rgb_stride_frame * seq->height;
result->buf_size[1] = result->buf_size[2] = 0;
result->start = convert_start;
result->copy = NULL;
#ifdef ARCH_X86
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMXEXT)) {
id->convert420 = 0;
result->copy = yuv2rgb_init_mmxext (order, bpp, seq);
}
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMX)) {
id->convert420 = 0;
result->copy = yuv2rgb_init_mmx (order, bpp, seq);
}
#endif
#ifdef ARCH_SPARC
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_SPARC_VIS))
result->copy = yuv2rgb_init_vis (order, bpp, seq);
#endif
if (result->copy == NULL) {
int src, dest;
static void (* yuv2rgb_copy[3][5]) (void *, uint8_t * const *,
unsigned int) =
{{yuv2rgb_c_24_bgr_420, yuv2rgb_c_8_420, yuv2rgb_c_16_420,
yuv2rgb_c_24_rgb_420, yuv2rgb_c_32_420},
{yuv2rgb_c_24_bgr_422, yuv2rgb_c_8_422, yuv2rgb_c_16_422,
yuv2rgb_c_24_rgb_422, yuv2rgb_c_32_422},
{yuv2rgb_c_24_bgr_444, yuv2rgb_c_8_444, yuv2rgb_c_16_444,
yuv2rgb_c_24_rgb_444, yuv2rgb_c_32_444}};
id->convert420 = id->chroma420;
yuv2rgb_c_init (order, bpp);
src = ((seq->chroma_width == seq->width) +
(seq->chroma_height == seq->height));
dest = (bpp == 24 && order == CONVERT_BGR) ? 0 : (bpp + 7) >> 3;
result->copy = yuv2rgb_copy[src][dest];
}