Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

yuv2rgb.c

Go to the documentation of this file.
00001 /*
00002  * yuv2rgb.c
00003  * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
00004  * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
00005  *
00006  * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
00007  * See http://libmpeg2.sourceforge.net/ for updates.
00008  *
00009  * mpeg2dec is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * mpeg2dec is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  */
00023 
00024 #include "config.h"
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <inttypes.h>
00029 
00030 #include "mpeg2.h"
00031 #include "convert.h"
00032 #include "convert_internal.h"
00033 
00034 static uint32_t matrix_coefficients = 6;
00035 
00036 const int32_t Inverse_Table_6_9[8][4] = {
00037     {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
00038     {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
00039     {104597, 132201, 25675, 53279}, /* unspecified */
00040     {104597, 132201, 25675, 53279}, /* reserved */
00041     {104448, 132798, 24759, 53109}, /* FCC */
00042     {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
00043     {104597, 132201, 25675, 53279}, /* SMPTE 170M */
00044     {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
00045 };
00046 
00047 typedef void yuv2rgb_c_internal (uint8_t *, uint8_t *, uint8_t *, uint8_t *,
00048                                  void *, void *, int);
00049 
00050 void * table_rV[256];
00051 void * table_gU[256];
00052 int table_gV[256];
00053 void * table_bU[256];
00054 
00055 #define RGB(type,i)                                             \
00056         U = pu[i];                                              \
00057         V = pv[i];                                              \
00058         r = (type *) table_rV[V];                               \
00059         g = (type *) (((uint8_t *)table_gU[U]) + table_gV[V]);  \
00060         b = (type *) table_bU[U];
00061 
00062 #define DST(py,dst,i)                           \
00063         Y = py[2*i];                            \
00064         dst[2*i] = r[Y] + g[Y] + b[Y];          \
00065         Y = py[2*i+1];                          \
00066         dst[2*i+1] = r[Y] + g[Y] + b[Y];
00067 
00068 #define DSTRGB(py,dst,i)                                                \
00069         Y = py[2*i];                                                    \
00070         dst[6*i] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y];          \
00071         Y = py[2*i+1];                                                  \
00072         dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];
00073 
00074 #define DSTBGR(py,dst,i)                                                \
00075         Y = py[2*i];                                                    \
00076         dst[6*i] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y];          \
00077         Y = py[2*i+1];                                                  \
00078         dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
00079 
00080 static void yuv2rgb_c_32 (uint8_t * py_1, uint8_t * py_2,
00081                           uint8_t * pu, uint8_t * pv,
00082                           void * _dst_1, void * _dst_2, int width)
00083 {
00084     int U, V, Y;
00085     uint32_t * r, * g, * b;
00086     uint32_t * dst_1, * dst_2;
00087 
00088     width >>= 3;
00089     dst_1 = (uint32_t *) _dst_1;
00090     dst_2 = (uint32_t *) _dst_2;
00091 
00092     do {
00093         RGB (uint32_t, 0);
00094         DST (py_1, dst_1, 0);
00095         DST (py_2, dst_2, 0);
00096 
00097         RGB (uint32_t, 1);
00098         DST (py_2, dst_2, 1);
00099         DST (py_1, dst_1, 1);
00100 
00101         RGB (uint32_t, 2);
00102         DST (py_1, dst_1, 2);
00103         DST (py_2, dst_2, 2);
00104 
00105         RGB (uint32_t, 3);
00106         DST (py_2, dst_2, 3);
00107         DST (py_1, dst_1, 3);
00108 
00109         pu += 4;
00110         pv += 4;
00111         py_1 += 8;
00112         py_2 += 8;
00113         dst_1 += 8;
00114         dst_2 += 8;
00115     } while (--width);
00116 }
00117 
00118 /* This is very near from the yuv2rgb_c_32 code */
00119 static void yuv2rgb_c_24_rgb (uint8_t * py_1, uint8_t * py_2,
00120                               uint8_t * pu, uint8_t * pv,
00121                               void * _dst_1, void * _dst_2, int width)
00122 {
00123     int U, V, Y;
00124     uint8_t * r, * g, * b;
00125     uint8_t * dst_1, * dst_2;
00126 
00127     width >>= 3;
00128     dst_1 = (uint8_t *) _dst_1;
00129     dst_2 = (uint8_t *) _dst_2;
00130 
00131     do {
00132         RGB (uint8_t, 0);
00133         DSTRGB (py_1, dst_1, 0);
00134         DSTRGB (py_2, dst_2, 0);
00135 
00136         RGB (uint8_t, 1);
00137         DSTRGB (py_2, dst_2, 1);
00138         DSTRGB (py_1, dst_1, 1);
00139 
00140         RGB (uint8_t, 2);
00141         DSTRGB (py_1, dst_1, 2);
00142         DSTRGB (py_2, dst_2, 2);
00143 
00144         RGB (uint8_t, 3);
00145         DSTRGB (py_2, dst_2, 3);
00146         DSTRGB (py_1, dst_1, 3);
00147 
00148         pu += 4;
00149         pv += 4;
00150         py_1 += 8;
00151         py_2 += 8;
00152         dst_1 += 24;
00153         dst_2 += 24;
00154     } while (--width);
00155 }
00156 
00157 /* only trivial mods from yuv2rgb_c_24_rgb */
00158 static void yuv2rgb_c_24_bgr (uint8_t * py_1, uint8_t * py_2,
00159                               uint8_t * pu, uint8_t * pv,
00160                               void * _dst_1, void * _dst_2, int width)
00161 {
00162     int U, V, Y;
00163     uint8_t * r, * g, * b;
00164     uint8_t * dst_1, * dst_2;
00165 
00166     width >>= 3;
00167     dst_1 = (uint8_t *) _dst_1;
00168     dst_2 = (uint8_t *) _dst_2;
00169 
00170     do {
00171         RGB (uint8_t, 0);
00172         DSTBGR (py_1, dst_1, 0);
00173         DSTBGR (py_2, dst_2, 0);
00174 
00175         RGB (uint8_t, 1);
00176         DSTBGR (py_2, dst_2, 1);
00177         DSTBGR (py_1, dst_1, 1);
00178 
00179         RGB (uint8_t, 2);
00180         DSTBGR (py_1, dst_1, 2);
00181         DSTBGR (py_2, dst_2, 2);
00182 
00183         RGB (uint8_t, 3);
00184         DSTBGR (py_2, dst_2, 3);
00185         DSTBGR (py_1, dst_1, 3);
00186 
00187         pu += 4;
00188         pv += 4;
00189         py_1 += 8;
00190         py_2 += 8;
00191         dst_1 += 24;
00192         dst_2 += 24;
00193     } while (--width);
00194 }
00195 
00196 /* This is exactly the same code as yuv2rgb_c_32 except for the types of */
00197 /* r, g, b, dst_1, dst_2 */
00198 static void yuv2rgb_c_16 (uint8_t * py_1, uint8_t * py_2,
00199                           uint8_t * pu, uint8_t * pv,
00200                           void * _dst_1, void * _dst_2, int width)
00201 {
00202     int U, V, Y;
00203     uint16_t * r, * g, * b;
00204     uint16_t * dst_1, * dst_2;
00205 
00206     width >>= 3;
00207     dst_1 = (uint16_t *) _dst_1;
00208     dst_2 = (uint16_t *) _dst_2;
00209 
00210     do {
00211         RGB (uint16_t, 0);
00212         DST (py_1, dst_1, 0);
00213         DST (py_2, dst_2, 0);
00214 
00215         RGB (uint16_t, 1);
00216         DST (py_2, dst_2, 1);
00217         DST (py_1, dst_1, 1);
00218 
00219         RGB (uint16_t, 2);
00220         DST (py_1, dst_1, 2);
00221         DST (py_2, dst_2, 2);
00222 
00223         RGB (uint16_t, 3);
00224         DST (py_2, dst_2, 3);
00225         DST (py_1, dst_1, 3);
00226 
00227         pu += 4;
00228         pv += 4;
00229         py_1 += 8;
00230         py_2 += 8;
00231         dst_1 += 8;
00232         dst_2 += 8;
00233     } while (--width);
00234 }
00235 
00236 static int div_round (int dividend, int divisor)
00237 {
00238     if (dividend > 0)
00239         return (dividend + (divisor>>1)) / divisor;
00240     else
00241         return -((-dividend + (divisor>>1)) / divisor);
00242 }
00243 
00244 static yuv2rgb_c_internal * yuv2rgb_c_init (int order, int bpp)
00245 {
00246     int i;
00247     uint8_t table_Y[1024];
00248     uint32_t * table_32 = 0;
00249     uint16_t * table_16 = 0;
00250     uint8_t * table_8 = 0;
00251     int entry_size = 0;
00252     void * table_r = 0;
00253     void * table_g = 0;
00254     void * table_b = 0;
00255     yuv2rgb_c_internal * yuv2rgb;
00256 
00257     int crv = Inverse_Table_6_9[matrix_coefficients][0];
00258     int cbu = Inverse_Table_6_9[matrix_coefficients][1];
00259     int cgu = -Inverse_Table_6_9[matrix_coefficients][2];
00260     int cgv = -Inverse_Table_6_9[matrix_coefficients][3];
00261 
00262     for (i = 0; i < 1024; i++) {
00263         int j;
00264 
00265         j = (76309 * (i - 384 - 16) + 32768) >> 16;
00266         j = (j < 0) ? 0 : ((j > 255) ? 255 : j);
00267         table_Y[i] = j;
00268     }
00269 
00270     switch (bpp) {
00271     case 32:
00272         yuv2rgb = yuv2rgb_c_32;
00273 
00274         table_32 = (uint32_t *) malloc ((197 + 2*682 + 256 + 132) *
00275                                         sizeof (uint32_t));
00276 
00277         entry_size = sizeof (uint32_t);
00278         table_r = table_32 + 197;
00279         table_b = table_32 + 197 + 685;
00280         table_g = table_32 + 197 + 2*682;
00281 
00282         for (i = -197; i < 256+197; i++)
00283             ((uint32_t *) table_r)[i] =
00284                 table_Y[i+384] << ((order == CONVERT_RGB) ? 16 : 0);
00285         for (i = -132; i < 256+132; i++)
00286             ((uint32_t *) table_g)[i] = table_Y[i+384] << 8;
00287         for (i = -232; i < 256+232; i++)
00288             ((uint32_t *) table_b)[i] =
00289                 table_Y[i+384] << ((order == CONVERT_RGB) ? 0 : 16);
00290         break;
00291 
00292     case 24:
00293         yuv2rgb = (order == CONVERT_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
00294 
00295         table_8 = (uint8_t *) malloc ((256 + 2*232) * sizeof (uint8_t));
00296 
00297         entry_size = sizeof (uint8_t);
00298         table_r = table_g = table_b = table_8 + 232;
00299 
00300         for (i = -232; i < 256+232; i++)
00301             ((uint8_t * )table_b)[i] = table_Y[i+384];
00302         break;
00303 
00304     case 15:
00305     case 16:
00306         yuv2rgb = yuv2rgb_c_16;
00307 
00308         table_16 = (uint16_t *) malloc ((197 + 2*682 + 256 + 132) *
00309                                         sizeof (uint16_t));
00310 
00311         entry_size = sizeof (uint16_t);
00312         table_r = table_16 + 197;
00313         table_b = table_16 + 197 + 685;
00314         table_g = table_16 + 197 + 2*682;
00315 
00316         for (i = -197; i < 256+197; i++) {
00317             int j = table_Y[i+384] >> 3;
00318 
00319             if (order == CONVERT_RGB)
00320                 j <<= ((bpp==16) ? 11 : 10);
00321 
00322             ((uint16_t *)table_r)[i] = j;
00323         }
00324         for (i = -132; i < 256+132; i++) {
00325             int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);
00326 
00327             ((uint16_t *)table_g)[i] = j << 5;
00328         }
00329         for (i = -232; i < 256+232; i++) {
00330             int j = table_Y[i+384] >> 3;
00331 
00332             if (order == CONVERT_RGB)
00333                 j <<= ((bpp==16) ? 11 : 10);
00334 
00335             ((uint16_t *)table_b)[i] = j;
00336         }
00337         break;
00338 
00339     default:
00340         fprintf (stderr, "%ibpp not supported by yuv2rgb\n", bpp);
00341         exit (1);
00342     }
00343 
00344     for (i = 0; i < 256; i++) {
00345         table_rV[i] = (((uint8_t *)table_r) +
00346                        entry_size * div_round (crv * (i-128), 76309));
00347         table_gU[i] = (((uint8_t *)table_g) +
00348                        entry_size * div_round (cgu * (i-128), 76309));
00349         table_gV[i] = entry_size * div_round (cgv * (i-128), 76309);
00350         table_bU[i] = (((uint8_t *)table_b) +
00351                        entry_size * div_round (cbu * (i-128), 76309));
00352     }
00353 
00354     return yuv2rgb;
00355 }
00356 
00357 static void convert_yuv2rgb_c (void * _id, uint8_t * const * src,
00358                                unsigned int v_offset)
00359 {
00360     convert_rgb_t * id = (convert_rgb_t *) _id;
00361     uint8_t * dst;
00362     uint8_t * py;
00363     uint8_t * pu;
00364     uint8_t * pv;
00365     int loop;
00366 
00367     dst = id->rgb_ptr + id->rgb_stride * v_offset;
00368     py = src[0]; pu = src[1]; pv = src[2];
00369 
00370     loop = 8;
00371     do {
00372         id->yuv2rgb (py, py + (id->uv_stride << 1), pu, pv,
00373                      dst, dst + id->rgb_stride, id->width);
00374         py += id->uv_stride << 2;
00375         pu += id->uv_stride;
00376         pv += id->uv_stride;
00377         dst += 2 * id->rgb_stride;
00378     } while (--loop);
00379 }
00380 
00381 static void convert_start (void * _id, uint8_t * const * dest, int flags)
00382 {
00383     convert_rgb_t * id = (convert_rgb_t *) _id;
00384     id->rgb_ptr = dest[0];
00385     switch (flags) {
00386     case CONVERT_BOTTOM_FIELD:
00387         id->rgb_ptr += id->rgb_stride_frame;
00388         /* break thru */
00389     case CONVERT_TOP_FIELD:
00390         id->uv_stride = id->uv_stride_frame << 1;
00391         id->rgb_stride = id->rgb_stride_frame << 1;
00392         break;
00393     default:
00394         id->uv_stride = id->uv_stride_frame;
00395         id->rgb_stride = id->rgb_stride_frame;
00396     }
00397 }
00398 
00399 static void convert_internal (int order, int bpp, int width, int height,
00400                               uint32_t accel, void * arg,
00401                               convert_init_t * result)
00402 {
00403     convert_rgb_t * id = (convert_rgb_t *) result->id;
00404 
00405     if (!id) {
00406         result->id_size = sizeof (convert_rgb_t);
00407     } else {
00408         id->width = width;
00409         id->uv_stride_frame = width >> 1;
00410         id->rgb_stride_frame = ((bpp + 7) >> 3) * width;
00411 
00412         result->buf_size[0] = id->rgb_stride_frame * height;
00413         result->buf_size[1] = result->buf_size[2] = 0;
00414         result->start = convert_start;
00415 
00416         result->copy = NULL;
00417 #ifdef ARCH_X86
00418         if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMXEXT)) {
00419             result->copy = yuv2rgb_init_mmxext (order, bpp);
00420         }
00421         if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMX)) {
00422             result->copy = yuv2rgb_init_mmx (order, bpp);
00423         }
00424 #endif
00425 #ifdef LIBVO_MLIB
00426         if ((result->copy == NULL) && (accel & MPEG2_ACCEL_MLIB)) {
00427             result->copy = yuv2rgb_init_mlib (order, bpp);
00428         }
00429 #endif
00430         if (result->copy == NULL) {
00431             result->copy = convert_yuv2rgb_c;
00432             id->yuv2rgb = yuv2rgb_c_init (order, bpp);
00433         }
00434     }
00435 }
00436 
00437 void convert_rgb32 (int width, int height, uint32_t accel, void * arg,
00438                     convert_init_t * result)
00439 {
00440     convert_internal (CONVERT_RGB, 32, width, height, accel, arg, result);
00441 }
00442 
00443 void convert_rgb24 (int width, int height, uint32_t accel, void * arg,
00444                     convert_init_t * result)
00445 {
00446     convert_internal (CONVERT_RGB, 24, width, height, accel, arg, result);
00447 }
00448 
00449 void convert_rgb16 (int width, int height, uint32_t accel, void * arg,
00450                     convert_init_t * result)
00451 {
00452     convert_internal (CONVERT_RGB, 16, width, height, accel, arg, result);
00453 }
00454 
00455 void convert_rgb15 (int width, int height, uint32_t accel, void * arg,
00456                     convert_init_t * result)
00457 {
00458     convert_internal (CONVERT_RGB, 15, width, height, accel, arg, result);
00459 }
00460 
00461 void convert_bgr32 (int width, int height, uint32_t accel, void * arg,
00462                     convert_init_t * result)
00463 {
00464     convert_internal (CONVERT_BGR, 32, width, height, accel, arg, result);
00465 }
00466 
00467 void convert_bgr24 (int width, int height, uint32_t accel, void * arg,
00468                     convert_init_t * result)
00469 {
00470     convert_internal (CONVERT_BGR, 24, width, height, accel, arg, result);
00471 }
00472 
00473 void convert_bgr16 (int width, int height, uint32_t accel, void * arg,
00474                     convert_init_t * result)
00475 {
00476     convert_internal (CONVERT_BGR, 16, width, height, accel, arg, result);
00477 }
00478 
00479 void convert_bgr15 (int width, int height, uint32_t accel, void * arg,
00480                     convert_init_t * result)
00481 {
00482     convert_internal (CONVERT_BGR, 15, width, height, accel, arg, result);
00483 }
00484 
00485 convert_t * convert_rgb (int order, int bpp)
00486 {
00487     if (order == CONVERT_RGB || order == CONVERT_BGR)
00488         switch (bpp) {
00489         case 32: return (order == CONVERT_RGB) ? convert_rgb32 : convert_bgr32;
00490         case 24: return (order == CONVERT_RGB) ? convert_rgb24 : convert_bgr24;
00491         case 16: return (order == CONVERT_RGB) ? convert_rgb16 : convert_bgr16;
00492         case 15: return (order == CONVERT_RGB) ? convert_rgb15 : convert_bgr15;
00493         }
00494     return NULL;
00495 }
 

Powered by Plone

This site conforms to the following standards: