home *** CD-ROM | disk | FTP | other *** search
/ Geek 6 / Geek-006.iso / linux / video / xmovie-1.5.3.tar.gz / xmovie-1.5.3.tar / xmovie-1.5.3 / quicktime / colormodels.c < prev    next >
C/C++ Source or Header  |  2000-11-29  |  26KB  |  1,156 lines

  1. #include "colormodels.h"
  2. #include <glib.h>
  3. #include <stdlib.h>
  4.  
  5.  
  6. static cmodel_yuv_t *yuv_table = 0;
  7.  
  8. void cmodel_init_yuv(cmodel_yuv_t *yuv_table)
  9. {
  10.     int i;
  11.     for(i = 0; i < 256; i++)
  12.     {
  13. /* compression */
  14.         yuv_table->rtoy_tab[i] = (long)( 0.2990 * 65536 * i);
  15.         yuv_table->rtou_tab[i] = (long)(-0.1687 * 65536 * i);
  16.         yuv_table->rtov_tab[i] = (long)( 0.5000 * 65536 * i);
  17.  
  18.         yuv_table->gtoy_tab[i] = (long)( 0.5870 * 65536 * i);
  19.         yuv_table->gtou_tab[i] = (long)(-0.3320 * 65536 * i);
  20.         yuv_table->gtov_tab[i] = (long)(-0.4187 * 65536 * i);
  21.  
  22.         yuv_table->btoy_tab[i] = (long)( 0.1140 * 65536 * i);
  23.         yuv_table->btou_tab[i] = (long)( 0.5000 * 65536 * i);
  24.         yuv_table->btov_tab[i] = (long)(-0.0813 * 65536 * i);
  25.     }
  26.  
  27.     yuv_table->vtor = &(yuv_table->vtor_tab[128]);
  28.     yuv_table->vtog = &(yuv_table->vtog_tab[128]);
  29.     yuv_table->utog = &(yuv_table->utog_tab[128]);
  30.     yuv_table->utob = &(yuv_table->utob_tab[128]);
  31.     for(i = -128; i < 128; i++)
  32.     {
  33. /* decompression */
  34.         yuv_table->vtor[i] = (long)( 1.4020 * 65536 * i);
  35.         yuv_table->vtog[i] = (long)(-0.7141 * 65536 * i);
  36.  
  37.         yuv_table->utog[i] = (long)(-0.3441 * 65536 * i);
  38.         yuv_table->utob[i] = (long)( 1.7720 * 65536 * i);
  39.     }
  40. }
  41.  
  42.  
  43. void cmodel_delete_yuv(cmodel_yuv_t *yuv_table)
  44. {
  45. }
  46.  
  47. int cmodel_is_planar(int colormodel)
  48. {
  49.     switch(colormodel)
  50.     {
  51.         case BC_YUV420P:      return 1; break;
  52.         case BC_YUV422P:      return 1; break;
  53.         case BC_YUV411P:      return 1; break;
  54.     }
  55.     return 0;
  56. }
  57.  
  58. int cmodel_calculate_pixelsize(int colormodel)
  59. {
  60.     switch(colormodel)
  61.     {
  62.         case BC_TRANSPARENCY: return 1; break;
  63.         case BC_COMPRESSED:   return 1; break;
  64.         case BC_RGB8:         return 1; break;
  65.         case BC_RGB565:       return 2; break;
  66.         case BC_BGR565:       return 2; break;
  67.         case BC_BGR888:       return 3; break;
  68.         case BC_BGR8888:      return 4; break;
  69. // Working bitmaps are packed to simplify processing
  70.         case BC_RGB888:       return 3; break;
  71.         case BC_RGBA8888:     return 4; break;
  72.         case BC_RGB161616:    return 6; break;
  73.         case BC_RGBA16161616: return 8; break;
  74.         case BC_YUV888:       return 3; break;
  75.         case BC_YUVA8888:     return 4; break;
  76.         case BC_YUV161616:    return 6; break;
  77.         case BC_YUVA16161616: return 8; break;
  78. // Planar
  79.         case BC_YUV420P:      return 1; break;
  80.         case BC_YUV422P:      return 1; break;
  81.         case BC_YUV422:       return 2; break;
  82.         case BC_YUV411P:      return 1; break;
  83.     }
  84.     return 0;
  85. }
  86.  
  87.  
  88. // Pixel transfers
  89. static inline transfer_RGBA16161616_to_RGB8(unsigned char *(*output), unsigned char *input)
  90. {
  91.     unsigned int r, g, b, a;
  92.     a = ((guint16*)input)[3] >> 8;
  93.     r = (unsigned int)((guint16*)input)[0] * a;
  94.     g = (unsigned int)((guint16*)input)[1] * a;
  95.     b = (unsigned int)((guint16*)input)[2] * a;
  96.  
  97.     *(*output) = (unsigned char)(((r & 0xc00000) >> 16) + 
  98.                 ((g & 0xe00000) >> 18) + 
  99.                 ((b & 0xe00000) >> 21));
  100.     (*output)++;
  101. }
  102.  
  103. static inline transfer_RGBA16161616_to_RGB565(unsigned char *(*output), unsigned char *input)
  104. {
  105.     unsigned int r, g, b, a;
  106.     a = ((guint16*)input)[3] >> 8;
  107.     r = (unsigned int)((guint16*)input)[0] * a;
  108.     g = (unsigned int)((guint16*)input)[1] * a;
  109.     b = (unsigned int)((guint16*)input)[2] * a;
  110.  
  111.     *(guint16*)(*output) = (guint16)(((r & 0xf80000) >> 8) + 
  112.                 ((g & 0xfc0000) >> 13) + 
  113.                 ((b & 0xf80000) >> 19));
  114.     (*output) += 2;
  115. }
  116.  
  117. static inline transfer_RGBA16161616_to_BGR888(unsigned char *(*output), unsigned char *input)
  118. {
  119.     unsigned int r, g, b, a;
  120.     a = ((guint16*)input)[3] >> 8;
  121.     r = (unsigned int)((guint16*)input)[0] * a;
  122.     g = (unsigned int)((guint16*)input)[1] * a;
  123.     b = (unsigned int)((guint16*)input)[2] * a;
  124.  
  125.     (*output)[0] = (unsigned char)(b >> 16);
  126.     (*output)[1] = (unsigned char)(g >> 16);
  127.     (*output)[2] = (unsigned char)(r >> 16);
  128.     (*output) += 3;
  129. }
  130.  
  131. static inline transfer_RGBA16161616_to_BGR8888(unsigned char *(*output), unsigned char *input)
  132. {
  133.     unsigned int r, g, b, a;
  134.     a = ((guint16*)input)[3] >> 8;
  135.     r = ((guint16*)input)[0] * a;
  136.     g = ((guint16*)input)[1] * a;
  137.     b = ((guint16*)input)[2] * a;
  138.  
  139.     (*output)[0] = (unsigned char)(b >> 16);
  140.     (*output)[1] = (unsigned char)(g >> 16);
  141.     (*output)[2] = (unsigned char)(r >> 16);
  142.     (*output) += 4;
  143. }
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153. static inline transfer_RGBA8888_to_TRANSPARENCY(unsigned char *(*output), unsigned char *input, int (*bit_counter))
  154. {
  155.     if((*bit_counter) == 7) *(*output) = 0;
  156.  
  157.     if(input[3] < 127) 
  158.     {
  159.         *(*output) |= (unsigned char)1 << (7 - (*bit_counter));
  160.     }
  161.  
  162.     if((*bit_counter) == 0)
  163.     {
  164.         (*output)++;
  165.         (*bit_counter) = 7;
  166.     }
  167.     else
  168.         (*bit_counter)--;
  169. }
  170.  
  171. // These routines blend in a background color since they should be
  172. // exclusively used for widgets.
  173.  
  174. static inline transfer_RGBA8888_to_RGB8bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b)
  175. {
  176.     unsigned int r, g, b, a, anti_a;
  177.     a = input[3];
  178.     anti_a = 255 - a;
  179.     r = (unsigned int)input[0] * a + bg_r * anti_a;
  180.     g = (unsigned int)input[1] * a + bg_g * anti_a;
  181.     b = (unsigned int)input[2] * a + bg_b * anti_a;
  182.     *(*output) = (unsigned char)(((r & 0xc000) >> 8) + 
  183.                 ((g & 0xe000) >> 10) + 
  184.                 ((b & 0xe000) >> 13));
  185.     (*output)++;
  186. }
  187.  
  188. static inline transfer_RGBA8888_to_RGB565bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b)
  189. {
  190.     unsigned int r, g, b, a, anti_a;
  191.     a = input[3];
  192.     anti_a = 255 - a;
  193.     r = (unsigned int)input[0] * a + bg_r * anti_a;
  194.     g = (unsigned int)input[1] * a + bg_g * anti_a;
  195.     b = (unsigned int)input[2] * a + bg_b * anti_a;
  196.     *(guint16*)(*output) = (guint16)((r & 0xf800) + 
  197.                 ((g & 0xfc00) >> 5) + 
  198.                 ((b & 0xf800) >> 11));
  199.     (*output) += 2;
  200. }
  201.  
  202. static inline transfer_RGBA8888_to_BGR888bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b)
  203. {
  204.     unsigned int r, g, b, a, anti_a;
  205.     a = input[3];
  206.     anti_a = 255 - a;
  207.     r = (unsigned int)input[0] * a + bg_r * anti_a;
  208.     g = (unsigned int)input[1] * a + bg_g * anti_a;
  209.     b = (unsigned int)input[2] * a + bg_b * anti_a;
  210.     (*output)[0] = (b >> 8) + 1;
  211.     (*output)[1] = (g >> 8) + 1;
  212.     (*output)[2] = (r >> 8) + 1;
  213.     (*output) += 3;
  214. }
  215.  
  216. static inline transfer_RGBA8888_to_BGR8888bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b)
  217. {
  218.     unsigned int r, g, b, a, anti_a;
  219.     a = input[3];
  220.     anti_a = 255 - a;
  221.  
  222.     r = (unsigned int)input[0] * a + bg_r * anti_a;
  223.     g = (unsigned int)input[1] * a + bg_g * anti_a;
  224.     b = (unsigned int)input[2] * a + bg_b * anti_a;
  225.  
  226.     (*output)[0] = (b >> 8) + 1;
  227.     (*output)[1] = (g >> 8) + 1;
  228.     (*output)[2] = (r >> 8) + 1;
  229.     (*output) += 4;
  230. }
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238. // These routines blend in a black background
  239.  
  240. static inline transfer_RGBA8888_to_RGB8(unsigned char *(*output), unsigned char *input)
  241. {
  242.     unsigned int r, g, b, a;
  243.     a = input[3];
  244.     r = (unsigned int)input[0] * a;
  245.     g = (unsigned int)input[1] * a;
  246.     b = (unsigned int)input[2] * a;
  247.     *(*output) = (unsigned char)(((r & 0xc000) >> 8) + 
  248.                 ((g & 0xe000) >> 10) + 
  249.                 ((b & 0xe000) >> 13));
  250.     (*output)++;
  251. }
  252.  
  253. static inline transfer_RGBA8888_to_RGB565(unsigned char *(*output), unsigned char *input)
  254. {
  255.     unsigned int r, g, b, a;
  256.     a = input[3];
  257.     r = (unsigned int)input[0] * a;
  258.     g = (unsigned int)input[1] * a;
  259.     b = (unsigned int)input[2] * a;
  260.     *(guint16*)(*output) = (guint16)((r & 0xf800) + 
  261.                 ((g & 0xfc00) >> 5) + 
  262.                 ((b & 0xf800) >> 11));
  263.     (*output) += 2;
  264. }
  265.  
  266. static inline transfer_RGBA8888_to_BGR888(unsigned char *(*output), unsigned char *input)
  267. {
  268.     unsigned int r, g, b, a;
  269.     a = input[3];
  270.     r = (unsigned int)input[0] * a;
  271.     g = (unsigned int)input[1] * a;
  272.     b = (unsigned int)input[2] * a;
  273.     (*output)[0] = (b >> 8) + 1;
  274.     (*output)[1] = (g >> 8) + 1;
  275.     (*output)[2] = (r >> 8) + 1;
  276.     (*output) += 3;
  277. }
  278.  
  279. static inline transfer_RGBA8888_to_BGR8888(unsigned char *(*output), unsigned char *input)
  280. {
  281.     unsigned int r, g, b, a;
  282.     a = input[3];
  283.     r = (unsigned int)input[0] * a;
  284.     g = (unsigned int)input[1] * a;
  285.     b = (unsigned int)input[2] * a;
  286.     (*output)[0] = (b >> 8) + 1;
  287.     (*output)[1] = (g >> 8) + 1;
  288.     (*output)[2] = (r >> 8) + 1;
  289.     (*output) += 4;
  290. }
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300. static inline transfer_RGB888_to_RGB8(unsigned char *(*output), unsigned char *input)
  301. {
  302.     *(*output) = (unsigned char)((input[0] & 0xc0) +
  303.                              ((input[1] & 0xe0) >> 2) +
  304.                               ((input[2] & 0xe0) >> 5));
  305.     (*output)++;
  306. }
  307.  
  308. static inline transfer_RGB888_to_RGB565(unsigned char *(*output), unsigned char *input)
  309. {
  310.     guint16 r, g, b;
  311.     r = *input++;
  312.     g = *input++;
  313.     b = *input;
  314.     *(guint16*)(*output) = ((r & 0xf8) << 8)
  315.              + ((g & 0xfc) << 3)
  316.              + ((b & 0xf8) >> 3);
  317.     (*output) += 2;
  318. }
  319.  
  320. static inline transfer_RGB888_to_BGR888(unsigned char *(*output), unsigned char *input)
  321. {
  322.     (*output)[0] = input[2];
  323.     (*output)[1] = input[1];
  324.     (*output)[2] = input[0];
  325.     (*output) += 3;
  326. }
  327.  
  328. static inline transfer_RGB888_to_BGR8888(unsigned char *(*output), unsigned char *input)
  329. {
  330.     (*output)[0] = input[2];
  331.     (*output)[1] = input[1];
  332.     (*output)[2] = input[0];
  333.     (*output) += 4;
  334. }
  335.  
  336.  
  337.  
  338.  
  339. #define YUV_TO_RGB(y, u, v, r, g, b) \
  340. { \
  341.     r = ((y + yuv_table->vtor_tab[v]) >> 16); \
  342.     g = ((y + yuv_table->utog_tab[u] + yuv_table->vtog_tab[v]) >> 16); \
  343.     b = ((y + yuv_table->utob_tab[u]) >> 16); \
  344.     RECLIP(r, 0, 255); \
  345.     RECLIP(g, 0, 255); \
  346.     RECLIP(b, 0, 255); \
  347. }
  348.  
  349. static inline transfer_YUV420P_to_RGB8(unsigned char *(*output), 
  350.     unsigned char *input_y,
  351.     unsigned char *input_u,
  352.     unsigned char *input_v)
  353. {
  354.     int y, u, v;
  355.     int r, g, b;
  356.     
  357.     y = (int)(*input_y) << 16;
  358.     u = *input_u;
  359.     v = *input_v;
  360.     YUV_TO_RGB(y, u, v, r, g, b)
  361.  
  362.     *(*output) = (unsigned char)((r & 0xc0) +
  363.                              ((g & 0xe0) >> 2) +
  364.                               ((b & 0xe0) >> 5));
  365.     (*output)++;
  366. }
  367.  
  368. static inline transfer_YUV420P_to_RGB565(unsigned char *(*output), 
  369.     unsigned char *input_y,
  370.     unsigned char *input_u,
  371.     unsigned char *input_v)
  372. {
  373.     int y, u, v;
  374.     int r, g, b;
  375.     
  376.     y = (int)(*input_y) << 16;
  377.     u = *input_u;
  378.     v = *input_v;
  379.     YUV_TO_RGB(y, u, v, r, g, b)
  380.  
  381.     *(guint16*)(*output) = ((r & 0xf8) << 8)
  382.              + ((g & 0xfc) << 3)
  383.              + ((b & 0xf8) >> 3);
  384.     (*output) += 2;
  385. }
  386.  
  387. static inline transfer_YUV420P_to_BGR888(unsigned char *(*output), 
  388.     unsigned char *input_y,
  389.     unsigned char *input_u,
  390.     unsigned char *input_v)
  391. {
  392.     int y, u, v;
  393.     int r, g, b;
  394.     
  395.     y = (int)(*input_y) << 16;
  396.     u = *input_u;
  397.     v = *input_v;
  398.     YUV_TO_RGB(y, u, v, r, g, b)
  399.  
  400.     (*output)[0] = b;
  401.     (*output)[1] = g;
  402.     (*output)[2] = r;
  403.     (*output) += 3;
  404. }
  405.  
  406. static inline transfer_YUV420P_to_RGB888(unsigned char *(*output), 
  407.     unsigned char *input_y,
  408.     unsigned char *input_u,
  409.     unsigned char *input_v)
  410. {
  411.     int y, u, v;
  412.     int r, g, b;
  413.     
  414.     y = (int)(*input_y) << 16;
  415.     u = *input_u;
  416.     v = *input_v;
  417.     YUV_TO_RGB(y, u, v, r, g, b)
  418.  
  419.     (*output)[0] = r;
  420.     (*output)[1] = g;
  421.     (*output)[2] = b;
  422.     (*output) += 3;
  423. }
  424.  
  425. static inline transfer_YUV420P_to_BGR8888(unsigned char *(*output), 
  426.     unsigned char *input_y,
  427.     unsigned char *input_u,
  428.     unsigned char *input_v)
  429. {
  430.     int y, u, v;
  431.     int r, g, b;
  432.  
  433.     y = (int)(*input_y) << 16;
  434.     u = *input_u;
  435.     v = *input_v;
  436.     YUV_TO_RGB(y, u, v, r, g, b)
  437.  
  438.     (*output)[0] = b;
  439.     (*output)[1] = g;
  440.     (*output)[2] = r;
  441.     (*output) += 4;
  442. }
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454. static inline transfer_YUV422P_to_YUV888(unsigned char *(*output), 
  455.     unsigned char *input_y,
  456.     unsigned char *input_u,
  457.     unsigned char *input_v)
  458. {
  459.     (*output)[0] = *input_y;
  460.     (*output)[1] = *input_u;
  461.     (*output)[2] = *input_v;
  462.     (*output) += 3;
  463. }
  464.  
  465. static inline transfer_YUV422P_to_YUV422(unsigned char *(*output), 
  466.     unsigned char *input_y,
  467.     unsigned char *input_u,
  468.     unsigned char *input_v,
  469.     int j)
  470. {
  471. // Store U and V for even pixels only
  472.     if(!(j & 1))
  473.     {
  474.         (*output)[1] = *input_u;
  475.         (*output)[3] = *input_v;
  476.         (*output)[0] = *input_y;
  477.     }
  478.     else
  479. // Store Y and advance output for odd pixels only
  480.     {
  481.         (*output)[2] = *input_y;
  482.         (*output) += 4;
  483.     }
  484. }
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496. static inline transfer_YUV422_to_RGB8(unsigned char *(*output), 
  497.     unsigned char *input, 
  498.     int column)
  499. {
  500.     int y, u, v;
  501.     int r, g, b;
  502.  
  503. // Even pixel
  504.     if(!(column & 1))
  505.         y = (int)(input[0]) << 16;
  506.     else
  507. // Odd pixel
  508.         y = (int)(input[2]) << 16;
  509.  
  510.     u = input[1];
  511.     v = input[3];
  512.     YUV_TO_RGB(y, u, v, r, g, b)
  513.  
  514.     *(*output) = (unsigned char)((r & 0xc0) +
  515.                              ((g & 0xe0) >> 2) +
  516.                               ((b & 0xe0) >> 5));
  517.     (*output)++;
  518. }
  519.  
  520. static inline transfer_YUV422_to_RGB565(unsigned char *(*output), 
  521.     unsigned char *input, 
  522.     int column)
  523. {
  524.     int y, u, v;
  525.     int r, g, b;
  526.  
  527. // Even pixel
  528.     if(!(column & 1))
  529.         y = (int)(input[0]) << 16;
  530.     else
  531. // Odd pixel
  532.         y = (int)(input[2]) << 16;
  533.     u = input[1];
  534.     v = input[3];
  535.     YUV_TO_RGB(y, u, v, r, g, b)
  536.  
  537.     *(guint16*)(*output) = ((r & 0xf8) << 8)
  538.              + ((g & 0xfc) << 3)
  539.              + ((b & 0xf8) >> 3);
  540.     (*output) += 2;
  541. }
  542.  
  543. static inline transfer_YUV422_to_BGR888(unsigned char *(*output), 
  544.     unsigned char *input, 
  545.     int column)
  546. {
  547.     int y, u, v;
  548.     int r, g, b;
  549.  
  550. // Even pixel
  551.     if(!(column & 1))
  552.         y = (int)(input[0]) << 16;
  553.     else
  554. // Odd pixel
  555.         y = (int)(input[2]) << 16;
  556.     u = input[1];
  557.     v = input[3];
  558.     YUV_TO_RGB(y, u, v, r, g, b)
  559.  
  560.     (*output)[0] = b;
  561.     (*output)[1] = g;
  562.     (*output)[2] = r;
  563.     (*output) += 3;
  564. }
  565.  
  566. static inline transfer_YUV422_to_RGB888(unsigned char *(*output), 
  567.     unsigned char *input, 
  568.     int column)
  569. {
  570.     int y, u, v;
  571.     int r, g, b;
  572.  
  573. // Even pixel
  574.     if(!(column & 1))
  575.         y = (int)(input[0]) << 16;
  576.     else
  577. // Odd pixel
  578.         y = (int)(input[2]) << 16;
  579.     u = input[1];
  580.     v = input[3];
  581.     YUV_TO_RGB(y, u, v, r, g, b)
  582.  
  583.     (*output)[0] = r;
  584.     (*output)[1] = g;
  585.     (*output)[2] = b;
  586.     (*output) += 3;
  587. }
  588.  
  589. static inline transfer_YUV422_to_BGR8888(unsigned char *(*output), 
  590.     unsigned char *input, 
  591.     int column)
  592. {
  593.     int y, u, v;
  594.     int r, g, b;
  595.  
  596. // Even pixel
  597.     if(!(column & 1))
  598.         y = (int)(input[0]) << 16;
  599.     else
  600. // Odd pixel
  601.         y = (int)(input[2]) << 16;
  602.     u = input[1];
  603.     v = input[3];
  604.  
  605.     YUV_TO_RGB(y, u, v, r, g, b)
  606.  
  607.     (*output)[0] = b;
  608.     (*output)[1] = g;
  609.     (*output)[2] = r;
  610.     (*output) += 4;
  611. }
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619. #define TRANSFER_FRAME_HEAD \
  620.     for(i = 0; i < out_h; i++) \
  621.     { \
  622.         unsigned char *output_row = output_rows[i + out_y] + out_x * out_pixelsize; \
  623.         unsigned char *input_row = input_rows[row_table[i]]; \
  624.         int bit_counter = 7; \
  625.         for(j = 0; j < out_w; j++) \
  626.         {
  627.  
  628. #define TRANSFER_FRAME_TAIL \
  629.         } \
  630.     }
  631.  
  632.  
  633.  
  634. #define TRANSFER_YUV420_HEAD \
  635.     for(i = 0; i < out_h; i++) \
  636.     { \
  637.         unsigned char *output_row = output_rows[i + out_y] + out_x * out_pixelsize; \
  638.         unsigned char *input_y = in_y_plane + row_table[i] * total_in_w; \
  639.         unsigned char *input_u = in_u_plane + (row_table[i] / 2) * (total_in_w / 2); \
  640.         unsigned char *input_v = in_v_plane + (row_table[i] / 2) * (total_in_w / 2); \
  641.         for(j = 0; j < out_w; j++) \
  642.         {
  643.  
  644.  
  645. #define TRANSFER_YUV422P_HEAD \
  646.     for(i = 0; i < out_h; i++) \
  647.     { \
  648.         unsigned char *output_row = output_rows[i + out_y] + out_x * out_pixelsize; \
  649.         unsigned char *input_y = in_y_plane + row_table[i] * total_in_w; \
  650.         unsigned char *input_u = in_u_plane + row_table[i] * (total_in_w / 2); \
  651.         unsigned char *input_v = in_v_plane + row_table[i] * (total_in_w / 2); \
  652.         for(j = 0; j < out_w; j++) \
  653.         {
  654.  
  655.  
  656. #define TRANSFER_YUV422_HEAD \
  657.     for(i = 0; i < out_h; i++) \
  658.     { \
  659.         unsigned char *output_row = output_rows[i + out_y] + ((out_x * out_pixelsize) & 0xfffffffc); \
  660.         unsigned char *input_y = in_y_plane + row_table[i] * total_in_w; \
  661.         unsigned char *input_u = in_u_plane + row_table[i] * (total_in_w / 2); \
  662.         unsigned char *input_v = in_v_plane + row_table[i] * (total_in_w / 2); \
  663.         for(j = 0; j < out_w; j++) \
  664.         {
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672. #define TRANSFER_FRAME_PERMUTATION2(output, \
  673.     input, \
  674.     y_offset, \
  675.     u_offset, \
  676.     v_offset, \
  677.     input_column) \
  678. { \
  679.     register int i, j; \
  680.     switch(in_colormodel) \
  681.     { \
  682.         case BC_YUV420P: \
  683.             switch(out_colormodel) \
  684.             { \
  685.                 case BC_RGB8: \
  686.                     TRANSFER_YUV420_HEAD \
  687.                     transfer_YUV420P_to_RGB8((output), \
  688.                         input_y + (y_offset), \
  689.                         input_u + (u_offset), \
  690.                         input_v + (v_offset)); \
  691.                     TRANSFER_FRAME_TAIL \
  692.                     break; \
  693.                 case BC_BGR565: \
  694.                 case BC_RGB565: \
  695.                     TRANSFER_YUV420_HEAD \
  696.                     transfer_YUV420P_to_RGB565((output), \
  697.                         input_y + (y_offset), \
  698.                         input_u + (u_offset), \
  699.                         input_v + (v_offset)); \
  700.                     TRANSFER_FRAME_TAIL \
  701.                     break; \
  702.                 case BC_RGB888:      \
  703.                     TRANSFER_YUV420_HEAD \
  704.                     transfer_YUV420P_to_RGB888((output), \
  705.                         input_y + (y_offset), \
  706.                         input_u + (u_offset), \
  707.                         input_v + (v_offset)); \
  708.                     TRANSFER_FRAME_TAIL \
  709.                     break; \
  710.                 case BC_BGR888:      \
  711.                     TRANSFER_YUV420_HEAD \
  712.                     transfer_YUV420P_to_BGR888((output), \
  713.                         input_y + (y_offset), \
  714.                         input_u + (u_offset), \
  715.                         input_v + (v_offset)); \
  716.                     TRANSFER_FRAME_TAIL \
  717.                     break; \
  718.                 case BC_BGR8888: \
  719.                     TRANSFER_YUV420_HEAD \
  720.                     transfer_YUV420P_to_BGR8888((output), \
  721.                         input_y + (y_offset), \
  722.                         input_u + (u_offset), \
  723.                         input_v + (v_offset)); \
  724.                     TRANSFER_FRAME_TAIL \
  725.                     break; \
  726.                 case BC_YUV888: \
  727.                     TRANSFER_YUV420_HEAD \
  728.                     transfer_YUV422P_to_YUV888((output), \
  729.                         input_y + (y_offset), \
  730.                         input_u + (u_offset), \
  731.                         input_v + (v_offset)); \
  732.                     TRANSFER_FRAME_TAIL \
  733.                     break; \
  734.             } \
  735.             break; \
  736.  \
  737.         case BC_YUV422P: \
  738.             switch(out_colormodel) \
  739.             { \
  740.                 case BC_RGB8: \
  741.                     TRANSFER_YUV422P_HEAD \
  742.                     transfer_YUV420P_to_RGB8((output), \
  743.                         input_y + (y_offset), \
  744.                         input_u + (u_offset), \
  745.                         input_v + (v_offset)); \
  746.                     TRANSFER_FRAME_TAIL \
  747.                     break; \
  748.                 case BC_BGR565: \
  749.                 case BC_RGB565: \
  750.                     TRANSFER_YUV422P_HEAD \
  751.                     transfer_YUV420P_to_RGB565((output), \
  752.                         input_y + (y_offset), \
  753.                         input_u + (u_offset), \
  754.                         input_v + (v_offset)); \
  755.                     TRANSFER_FRAME_TAIL \
  756.                     break; \
  757.                 case BC_RGB888:      \
  758.                     TRANSFER_YUV422P_HEAD \
  759.                     transfer_YUV420P_to_RGB888((output), \
  760.                         input_y + (y_offset), \
  761.                         input_u + (u_offset), \
  762.                         input_v + (v_offset)); \
  763.                     TRANSFER_FRAME_TAIL \
  764.                     break; \
  765.                 case BC_BGR888:      \
  766.                     TRANSFER_YUV422P_HEAD \
  767.                     transfer_YUV420P_to_BGR888((output), \
  768.                         input_y + (y_offset), \
  769.                         input_u + (u_offset), \
  770.                         input_v + (v_offset)); \
  771.                     TRANSFER_FRAME_TAIL \
  772.                     break; \
  773.                 case BC_BGR8888: \
  774.                     TRANSFER_YUV422P_HEAD \
  775.                     transfer_YUV420P_to_BGR8888((output), \
  776.                         input_y + (y_offset), \
  777.                         input_u + (u_offset), \
  778.                         input_v + (v_offset)); \
  779.                     TRANSFER_FRAME_TAIL \
  780.                     break; \
  781.                 case BC_YUV888: \
  782.                     TRANSFER_YUV422P_HEAD \
  783.                     transfer_YUV422P_to_YUV888((output), \
  784.                         input_y + (y_offset), \
  785.                         input_u + (u_offset), \
  786.                         input_v + (v_offset)); \
  787.                     TRANSFER_FRAME_TAIL \
  788.                     break; \
  789.                 case BC_YUV422: \
  790.                     TRANSFER_YUV422_HEAD \
  791.                     transfer_YUV422P_to_YUV422((output), \
  792.                         input_y + (y_offset), \
  793.                         input_u + (u_offset), \
  794.                         input_v + (v_offset), \
  795.                         j); \
  796.                     TRANSFER_FRAME_TAIL \
  797.                     break; \
  798.             } \
  799.             break; \
  800.  \
  801.         case BC_YUV422: \
  802.             switch(out_colormodel) \
  803.             { \
  804.                 case BC_RGB8: \
  805.                     TRANSFER_FRAME_HEAD \
  806.                     transfer_YUV422_to_RGB8((output), (input), (input_column)); \
  807.                     TRANSFER_FRAME_TAIL \
  808.                     break; \
  809.                 case BC_BGR565: \
  810.                 case BC_RGB565: \
  811.                     TRANSFER_FRAME_HEAD \
  812.                     transfer_YUV422_to_RGB565((output), (input), (input_column)); \
  813.                     TRANSFER_FRAME_TAIL \
  814.                     break; \
  815.                 case BC_RGB888:      \
  816.                     TRANSFER_FRAME_HEAD \
  817.                     transfer_YUV422_to_RGB888((output), (input), (input_column)); \
  818.                     TRANSFER_FRAME_TAIL \
  819.                     break; \
  820.                 case BC_BGR888:      \
  821.                     TRANSFER_FRAME_HEAD \
  822.                     transfer_YUV422_to_BGR888((output), (input), (input_column)); \
  823.                     TRANSFER_FRAME_TAIL \
  824.                     break; \
  825.                 case BC_BGR8888: \
  826.                     TRANSFER_FRAME_HEAD \
  827.                     transfer_YUV422_to_BGR8888((output), (input), (input_column)); \
  828.                     TRANSFER_FRAME_TAIL \
  829.                     break; \
  830.             } \
  831.             break; \
  832.  \
  833.         case BC_RGBA16161616: \
  834.             switch(out_colormodel) \
  835.             { \
  836.                 case BC_RGB8: \
  837.                     TRANSFER_FRAME_HEAD \
  838.                     transfer_RGBA16161616_to_RGB8((output), (input)); \
  839.                     TRANSFER_FRAME_TAIL \
  840.                     break; \
  841.                 case BC_BGR565: \
  842.                 case BC_RGB565: \
  843.                     TRANSFER_FRAME_HEAD \
  844.                     transfer_RGBA16161616_to_RGB565((output), (input)); \
  845.                     TRANSFER_FRAME_TAIL \
  846.                     break; \
  847.                 case BC_BGR888:      \
  848.                     TRANSFER_FRAME_HEAD \
  849.                     transfer_RGBA16161616_to_BGR888((output), (input)); \
  850.                     TRANSFER_FRAME_TAIL \
  851.                 break; \
  852.                 case BC_BGR8888: \
  853.                     TRANSFER_FRAME_HEAD \
  854.                     transfer_RGBA16161616_to_BGR8888((output), (input)); \
  855.                     TRANSFER_FRAME_TAIL \
  856.                     break; \
  857.             } \
  858.             break; \
  859.  \
  860.         case BC_RGBA8888: \
  861.             switch(out_colormodel) \
  862.             { \
  863.                 case BC_TRANSPARENCY: \
  864.                     TRANSFER_FRAME_HEAD \
  865.                     transfer_RGBA8888_to_TRANSPARENCY((output), (input), &bit_counter); \
  866.                     TRANSFER_FRAME_TAIL \
  867.                     break; \
  868.                 case BC_RGB8: \
  869.                     if(bg_color > 0) \
  870.                         TRANSFER_FRAME_HEAD \
  871.                         transfer_RGBA8888_to_RGB8bg((output), (input), bg_r, bg_g, bg_b); \
  872.                         TRANSFER_FRAME_TAIL \
  873.                     else \
  874.                         TRANSFER_FRAME_HEAD \
  875.                         transfer_RGBA8888_to_RGB8((output), (input)); \
  876.                         TRANSFER_FRAME_TAIL \
  877.                     break; \
  878.                 case BC_BGR565: \
  879.                 case BC_RGB565: \
  880.                     if(bg_color > 0) \
  881.                         TRANSFER_FRAME_HEAD \
  882.                         transfer_RGBA8888_to_RGB565bg((output), (input), bg_r, bg_g, bg_b); \
  883.                         TRANSFER_FRAME_TAIL \
  884.                     else \
  885.                         TRANSFER_FRAME_HEAD \
  886.                         transfer_RGBA8888_to_RGB565((output), (input)); \
  887.                         TRANSFER_FRAME_TAIL \
  888.                     break; \
  889.                 case BC_BGR888: \
  890.                     if(bg_color > 0) \
  891.                         TRANSFER_FRAME_HEAD \
  892.                         transfer_RGBA8888_to_BGR888bg((output), (input), bg_r, bg_g, bg_b); \
  893.                         TRANSFER_FRAME_TAIL \
  894.                     else \
  895.                         TRANSFER_FRAME_HEAD \
  896.                         transfer_RGBA8888_to_BGR888((output), (input)); \
  897.                         TRANSFER_FRAME_TAIL \
  898.                     break; \
  899.                 case BC_BGR8888: \
  900.                     if(bg_color > 0) \
  901.                         TRANSFER_FRAME_HEAD \
  902.                         transfer_RGBA8888_to_BGR8888bg((output), (input), bg_r, bg_g, bg_b); \
  903.                         TRANSFER_FRAME_TAIL \
  904.                     else \
  905.                         TRANSFER_FRAME_HEAD \
  906.                         transfer_RGBA8888_to_BGR8888((output), (input)); \
  907.                         TRANSFER_FRAME_TAIL \
  908.                     break; \
  909.             } \
  910.             break; \
  911.  \
  912.         case BC_RGB888: \
  913.             switch(out_colormodel) \
  914.             { \
  915.                 case BC_RGB8: \
  916.                     TRANSFER_FRAME_HEAD \
  917.                     transfer_RGB888_to_RGB8((output), (input));      \
  918.                     TRANSFER_FRAME_TAIL \
  919.                     break; \
  920.                 case BC_BGR565: \
  921.                 case BC_RGB565: \
  922.                     TRANSFER_FRAME_HEAD \
  923.                     transfer_RGB888_to_RGB565((output), (input));    \
  924.                     TRANSFER_FRAME_TAIL \
  925.                     break; \
  926.                 case BC_BGR888: \
  927.                     TRANSFER_FRAME_HEAD \
  928.                     transfer_RGB888_to_BGR888((output), (input));    \
  929.                     TRANSFER_FRAME_TAIL \
  930.                     break; \
  931.                 case BC_BGR8888: \
  932.                     TRANSFER_FRAME_HEAD \
  933.                     transfer_RGB888_to_BGR8888((output), (input));   \
  934.                     TRANSFER_FRAME_TAIL \
  935.                     break; \
  936.             } \
  937.             break; \
  938.     } \
  939. }
  940.  
  941. static void transfer_frame_permutation1(unsigned char **output_rows,
  942.     unsigned char *out_y_plane,
  943.     unsigned char *out_u_plane,
  944.     unsigned char *out_v_plane,
  945.     unsigned char **input_rows,
  946.     unsigned char *in_y_plane,
  947.     unsigned char *in_u_plane,
  948.     unsigned char *in_v_plane,
  949.     int out_x,
  950.     int out_y,
  951.     int out_w,
  952.     int out_h,
  953.     int in_pixelsize,
  954.     int out_pixelsize,
  955.     int in_colormodel,
  956.     int out_colormodel,
  957.     int *column_table,
  958.     int *row_table,
  959.     int bg_r,
  960.     int bg_g,
  961.     int bg_b,
  962.     int bg_color,
  963.     int scale,
  964.     int total_in_w)
  965. {
  966.     switch(in_colormodel)
  967.     {
  968.         case BC_YUV420P:
  969.         case BC_YUV422P:
  970.             if(scale)
  971.             {
  972.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  973.                     input_row + column_table[j] * in_pixelsize,
  974.                     column_table[j],
  975.                     column_table[j] / 2,
  976.                     column_table[j] / 2,
  977.                     0);
  978.             }
  979.             else
  980.             {
  981.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  982.                     input_row + j * in_pixelsize,
  983.                     j,
  984.                     j / 2,
  985.                     j / 2,
  986.                     0);
  987.             }
  988.             break;
  989.  
  990.         case BC_YUV422:
  991.             if(scale)
  992.             {
  993.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  994.                     input_row + ((column_table[j] * in_pixelsize) & 0xfffffffc),
  995.                     0,
  996.                     0,
  997.                     0,
  998.                     column_table[j]);
  999.             }
  1000.             else
  1001.             {
  1002.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  1003.                     input_row + ((j * in_pixelsize) & 0xfffffffc),
  1004.                     0,
  1005.                     0,
  1006.                     0,
  1007.                     j);
  1008.             }
  1009.             break;
  1010.  
  1011.         default:
  1012.             if(scale)
  1013.             {
  1014.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  1015.                     input_row + column_table[j] * in_pixelsize,
  1016.                     0,
  1017.                     0,
  1018.                     0,
  1019.                     0);
  1020.             }
  1021.             else
  1022.             {
  1023.                 TRANSFER_FRAME_PERMUTATION2(&output_row, 
  1024.                     input_row + j * in_pixelsize,
  1025.                     0,
  1026.                     0,
  1027.                     0,
  1028.                     0);
  1029.             }
  1030.             break;
  1031.     }
  1032. }
  1033.  
  1034. static void get_scale_tables(int **column_table, 
  1035.     int **row_table, 
  1036.     int in_x1, 
  1037.     int in_y1, 
  1038.     int in_x2, 
  1039.     int in_y2,
  1040.     int out_x1, 
  1041.     int out_y1, 
  1042.     int out_x2, 
  1043.     int out_y2)
  1044. {
  1045.     int y_out, i;
  1046.     float w_in = in_x2 - in_x1;
  1047.     float h_in = in_y2 - in_y1;
  1048.     int w_out = out_x2 - out_x1;
  1049.     int h_out = out_y2 - out_y1;
  1050.  
  1051.     float hscale = w_in / w_out;
  1052.     float vscale = h_in / h_out;
  1053.  
  1054.     (*column_table) = malloc(sizeof(int) * w_out);
  1055.     (*row_table) = malloc(sizeof(int) * h_out);
  1056.     for(i = 0; i < w_out; i++)
  1057.     {
  1058.         (*column_table)[i] = (int)(hscale * i) + in_x1;
  1059.     }
  1060.  
  1061.     for(i = 0; i < h_out; i++)
  1062.     {
  1063.         (*row_table)[i] = (int)(vscale * i) + in_y1;
  1064.     }
  1065. }
  1066.  
  1067. void cmodel_transfer(unsigned char **output_rows, 
  1068.     unsigned char **input_rows,
  1069.     unsigned char *out_y_plane,
  1070.     unsigned char *out_u_plane,
  1071.     unsigned char *out_v_plane,
  1072.     unsigned char *in_y_plane,
  1073.     unsigned char *in_u_plane,
  1074.     unsigned char *in_v_plane,
  1075.     int in_x, 
  1076.     int in_y, 
  1077.     int in_w, 
  1078.     int in_h,
  1079.     int out_x, 
  1080.     int out_y, 
  1081.     int out_w, 
  1082.     int out_h,
  1083.     int in_colormodel, 
  1084.     int out_colormodel,
  1085.     int bg_color,
  1086.     int total_in_w)
  1087. {
  1088.     int *column_table;
  1089.     int *row_table;
  1090.     int scale_x;
  1091.     int bg_r, bg_g, bg_b;
  1092.     int in_pixelsize = cmodel_calculate_pixelsize(in_colormodel);
  1093.     int out_pixelsize = cmodel_calculate_pixelsize(out_colormodel);
  1094.  
  1095.     bg_r = (bg_color & 0xff0000) >> 16;
  1096.     bg_g = (bg_color & 0xff00) >> 8;
  1097.     bg_b = (bg_color & 0xff);
  1098.  
  1099. // Initialize tables
  1100.     if(yuv_table == 0)
  1101.     {
  1102.         yuv_table = calloc(1, sizeof(cmodel_yuv_t));
  1103.         cmodel_init_yuv(yuv_table);
  1104.     }
  1105.  
  1106. // Get scaling
  1107.     scale_x = (out_w != in_w);
  1108.     get_scale_tables(&column_table, &row_table, 
  1109.         in_x, in_y, in_x + in_w, in_y + in_h,
  1110.         out_x, out_y, out_x + out_w, out_y + out_h);
  1111.  
  1112. //printf("cmodel_transfer %d %d\n", in_colormodel, out_colormodel);
  1113.  
  1114.     transfer_frame_permutation1(output_rows,
  1115.         out_y_plane,
  1116.         out_u_plane,
  1117.         out_v_plane,
  1118.         input_rows,
  1119.         in_y_plane,
  1120.         in_u_plane,
  1121.         in_v_plane,
  1122.         out_x,
  1123.         out_y,
  1124.         out_w,
  1125.         out_h,
  1126.         in_pixelsize,
  1127.         out_pixelsize,
  1128.         in_colormodel,
  1129.         out_colormodel,
  1130.         column_table,
  1131.         row_table,
  1132.         bg_r,
  1133.         bg_g, 
  1134.         bg_b,
  1135.         bg_color,
  1136.         scale_x,
  1137.         total_in_w);
  1138.     free(column_table);
  1139.     free(row_table);
  1140. }
  1141.  
  1142. int cmodel_bc_to_x(int color_model)
  1143. {
  1144.     switch(color_model)
  1145.     {
  1146.         case BC_YUV420P:
  1147.             return FOURCC_YV12;
  1148.             break;
  1149.         case BC_YUV422:
  1150.             return FOURCC_YUV2;
  1151.             break;
  1152.     }
  1153.     return -1;
  1154. }
  1155.  
  1156.