[cvs] / xvidcore / src / image / colorspace.c Repository:
ViewVC logotype

Diff of /xvidcore/src/image/colorspace.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3.2.1, Sun Oct 6 07:05:51 2002 UTC revision 1.7, Tue Nov 26 23:44:10 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      colorspace conversions   *  - colorspace conversion module -
5   *   *
6   *      This program is free software; you can redistribute it and/or modify   *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
7   *      it under the terms of the GNU General Public License as published by   *               2002 Michael Militzer <isibaar@xvid.org>
8     *
9     *  This file is part of XviD, a free MPEG-4 video encoder/decoder
10     *
11     *  XviD is free software; you can redistribute it and/or modify it
12     *  under the terms of the GNU General Public License as published by
13   *      the Free Software Foundation; either version 2 of the License, or   *      the Free Software Foundation; either version 2 of the License, or
14   *      (at your option) any later version.   *      (at your option) any later version.
15   *   *
# Line 15  Line 20 
20   *   *
21   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
22   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
23   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24   *   *
25   *************************************************************************/   *  Under section 8 of the GNU General Public License, the copyright
26     *  holders of XVID explicitly forbid distribution in the following
27  /**************************************************************************   *  countries:
28     *
29     *    - Japan
30     *    - United States of America
31     *
32     *  Linking XviD statically or dynamically with other modules is making a
33     *  combined work based on XviD.  Thus, the terms and conditions of the
34     *  GNU General Public License cover the whole combination.
35   *   *
36   *      History:   *  As a special exception, the copyright holders of XviD give you
37     *  permission to link XviD with independent modules that communicate with
38     *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
39     *  license terms of these independent modules, and to copy and distribute
40     *  the resulting combined work under terms of your choice, provided that
41     *  every copy of the combined work is accompanied by a complete copy of
42     *  the source code of XviD (the version of XviD used to produce the
43     *  combined work), being distributed under the terms of the GNU General
44     *  Public License plus this exception.  An independent module is a module
45     *  which is not derived from or based on XviD.
46   *   *
47   *      14.04.2002      added user_to_yuv_c()   *  Note that people who make modified versions of XviD are not obligated
48   *      30.02.2002      out_yuv dst_stride2 fix   *  to grant this special exception for their modified versions; it is
49   *      26.02.2002      rgb555, rgb565   *  their choice whether to do so.  The GNU General Public License gives
50   *      24.11.2001      accuracy improvement to yuyv/vyuy conversion   *  permission to release a modified version without this exception; this
51   *      28.10.2001      total rewrite <pross@cs.rmit.edu.au>   *  exception also makes it possible to release a modified version which
52     *  carries forward this exception.
53   *   *
54   **************************************************************************/   * $Id$
55     *
56     ****************************************************************************/
57    
58  #include <string.h>                             // memcpy  #include <string.h>                             /* memcpy */
59    
60  #include "colorspace.h"  #include "colorspace.h"
61  #include "../divx4.h"                   // DEC_PICTURE  #include "../divx4.h"                   /* DEC_PICTURE */
62    
63  // function pointers  /* function pointers */
64    
65  /* input */  /* input */
66  color_inputFuncPtr rgb555_to_yv12;  color_inputFuncPtr rgb555_to_yv12;
# Line 52  Line 76 
76  color_outputFuncPtr yv12_to_rgb565;  color_outputFuncPtr yv12_to_rgb565;
77  color_outputFuncPtr yv12_to_rgb24;  color_outputFuncPtr yv12_to_rgb24;
78  color_outputFuncPtr yv12_to_rgb32;  color_outputFuncPtr yv12_to_rgb32;
 color_outputFuncPtr yv12_to_abgr;  
 color_outputFuncPtr yv12_to_rgba;  
79  color_outputFuncPtr yv12_to_yuv;  color_outputFuncPtr yv12_to_yuv;
80  color_outputFuncPtr yv12_to_yuyv;  color_outputFuncPtr yv12_to_yuyv;
81  color_outputFuncPtr yv12_to_uyvy;  color_outputFuncPtr yv12_to_uyvy;
# Line 120  Line 142 
142    
143    
144          for (y = height / 2; y; y--) {          for (y = height / 2; y; y--) {
145                  // process one 2x2 block per iteration                  /* process one 2x2 block per iteration */
146                  for (x = 0; x < (uint32_t) width; x += 2) {                  for (x = 0; x < (uint32_t) width; x += 2) {
147                          int rgb, r, g, b, r4, g4, b4;                          int rgb, r, g, b, r4, g4, b4;
148    
# Line 205  Line 227 
227    
228    
229          for (y = height / 2; y; y--) {          for (y = height / 2; y; y--) {
230                  // process one 2x2 block per iteration                  /* process one 2x2 block per iteration */
231                  for (x = 0; x < (uint32_t) width; x += 2) {                  for (x = 0; x < (uint32_t) width; x += 2) {
232                          int rgb, r, g, b, r4, g4, b4;                          int rgb, r, g, b, r4, g4, b4;
233    
# Line 477  Line 499 
499    
500                  for (x = width >> 1; x; x--) {                  for (x = width >> 1; x; x--) {
501                          *y_out++ = *src++;                          *y_out++ = *src++;
502                          //*u_out++ = *src++;                          /**u_out++ = *src++; */
503                          *u_out++ = (*(src + width2) + *src) >> 1;                          *u_out++ = (*(src + width2) + *src) >> 1;
504                          src++;                          src++;
505                          *y_out++ = *src++;                          *y_out++ = *src++;
506                          //*v_out++ = *src++;                          /**v_out++ = *src++; */
507                          *v_out++ = (*(src + width2) + *src) >> 1;                          *v_out++ = (*(src + width2) + *src) >> 1;
508                          src++;                          src++;
509    
# Line 529  Line 551 
551    
552                  for (x = width >> 1; x; x--) {                  for (x = width >> 1; x; x--) {
553                          *u_out++ = *src++;                          *u_out++ = *src++;
554                          // *u_out++ = (*(src+width2) + *src++) >> 1;                          /* *u_out++ = (*(src+width2) + *src++) >> 1; */
555                          *y_out++ = *src++;                          *y_out++ = *src++;
556                          //*v_out++ = *src++;                          /**v_out++ = *src++; */
557                          *v_out++ = (*(src + width2) + *src) >> 1;                          *v_out++ = (*(src + width2) + *src) >> 1;
558                          src++;                          src++;
559                          *y_out++ = *src++;                          *y_out++ = *src++;
# Line 606  Line 628 
628                                   int width,                                   int width,
629                                   int height)                                   int height)
630  {  {
631          const uint32_t dst_dif = 2 * dst_stride - 2 * width;          const uint32_t dst_dif = 4 * dst_stride - 2 * width;
632          int32_t y_dif = 2 * y_stride - width;          int32_t y_dif = 2 * y_stride - width;
633    
634          uint8_t *dst2 = dst + dst_stride;          uint8_t *dst2 = dst + 2 * dst_stride;
635          uint8_t *y_src2 = y_src + y_stride;          uint8_t *y_src2 = y_src + y_stride;
636          uint32_t x, y;          uint32_t x, y;
637    
# Line 630  Line 652 
652                  r = g = b = 0;                  r = g = b = 0;
653                  r2 = g2 = b2 = 0;                  r2 = g2 = b2 = 0;
654    
655                  // process one 2x2 block per iteration                  /* process one 2x2 block per iteration */
656                  for (x = 0; x < (uint32_t) width / 2; x++) {                  for (x = 0; x < (uint32_t) width / 2; x++) {
657                          int u, v;                          int u, v;
658                          int b_u, g_uv, r_v, rgb_y;                          int b_u, g_uv, r_v, rgb_y;
# Line 705  Line 727 
727                                   int width,                                   int width,
728                                   int height)                                   int height)
729  {  {
730          const uint32_t dst_dif = 2 * dst_stride - 2 * width;          const uint32_t dst_dif = 4 * dst_stride - 2 * width;
731          int32_t y_dif = 2 * y_stride - width;          int32_t y_dif = 2 * y_stride - width;
732    
733          uint8_t *dst2 = dst + dst_stride;          uint8_t *dst2 = dst + 2 * dst_stride;
734          uint8_t *y_src2 = y_src + y_stride;          uint8_t *y_src2 = y_src + y_stride;
735          uint32_t x, y;          uint32_t x, y;
736    
737          if (height < 0) {                       // flip image?          if (height < 0) {                       /* flip image? */
738                  height = -height;                  height = -height;
739                  y_src += (height - 1) * y_stride;                  y_src += (height - 1) * y_stride;
740                  y_src2 = y_src - y_stride;                  y_src2 = y_src - y_stride;
# Line 729  Line 751 
751                  r = g = b = 0;                  r = g = b = 0;
752                  r2 = g2 = b2 = 0;                  r2 = g2 = b2 = 0;
753    
754                  // process one 2x2 block per iteration                  /* process one 2x2 block per iteration */
755                  for (x = 0; x < (uint32_t) width / 2; x++) {                  for (x = 0; x < (uint32_t) width / 2; x++) {
756                          int u, v;                          int u, v;
757                          int b_u, g_uv, r_v, rgb_y;                          int b_u, g_uv, r_v, rgb_y;
# Line 785  Line 807 
807  }  }
808    
809    
810  #define MAKE_YV12_TO_RGB_C(NAME,SIZE,C1,C2,C3,C4) \  
811  void yv12_to_##NAME##_c(uint8_t * dst,          \  /* yuv 4:2:0 planar -> rgb24 */
812                                  int dst_stride,         \  
813                                  uint8_t * y_src,        \  void
814                                  uint8_t * u_src,        \  yv12_to_rgb24_c(uint8_t * dst,
815                                  uint8_t * v_src,        \                                  int dst_stride,
816                                  int y_stride,           \                                  uint8_t * y_src,
817                                  int uv_stride,          \                                  uint8_t * u_src,
818                                  int width,                      \                                  uint8_t * v_src,
819                                  int height)                     \                                  int y_stride,
820  {       \                                  int uv_stride,
821          const uint8_t a = 0;            /* alpha = 0 */         \                                  int width,
822          const uint32_t dst_dif = 2 * dst_stride - (SIZE) * width;       \                                  int height)
823          int32_t y_dif = 2 * y_stride - width;   \  {
824          uint8_t *dst2 = dst + dst_stride;       \          const uint32_t dst_dif = 6 * dst_stride - 3 * width;
825          uint8_t *y_src2 = y_src + y_stride;     \          int32_t y_dif = 2 * y_stride - width;
826          uint32_t x, y;  \  
827  \          uint8_t *dst2 = dst + 3 * dst_stride;
828          if (height < 0) {                       /* flip image? */       \          uint8_t *y_src2 = y_src + y_stride;
829                  height = -height;                                                       \          uint32_t x, y;
830                  y_src += (height - 1) * y_stride;                       \  
831                  y_src2 = y_src - y_stride;                                      \          if (height < 0) {                       /* flip image? */
832                  u_src += (height / 2 - 1) * uv_stride;          \                  height = -height;
833                  v_src += (height / 2 - 1) * uv_stride;          \                  y_src += (height - 1) * y_stride;
834                  y_dif = -width - 2 * y_stride;                          \                  y_src2 = y_src - y_stride;
835                  uv_stride = -uv_stride;                                         \                  u_src += (height / 2 - 1) * uv_stride;
836          }       \                  v_src += (height / 2 - 1) * uv_stride;
837          /* process one 2x2 block per iteration */               \                  y_dif = -width - 2 * y_stride;
838          for (y = height/2; y; y--) {                                    \                  uv_stride = -uv_stride;
839                                                                                                          \          }
840                  for (x = 0; x < (uint32_t)width/2; x++) {       \  
841                          int u, v;                                                               \          for (y = height / 2; y; y--) {
842                          int b_u, g_uv, r_v, rgb_y;                              \                  /* process one 2x2 block per iteration */
843                          int r, g, b;                                                    \                  for (x = 0; x < (uint32_t) width / 2; x++) {
844  \                          int u, v;
845                          u = u_src[x];                                                   \                          int b_u, g_uv, r_v, rgb_y;
846                          v = v_src[x];                                                   \                          int r, g, b;
847                          b_u = B_U_tab[u];                                               \  
848                          g_uv = G_U_tab[u] + G_V_tab[v];                 \                          u = u_src[x];
849                          r_v = R_V_tab[v];                                               \                          v = v_src[x];
850  \  
851                          rgb_y = RGB_Y_tab[*y_src];                              \                          b_u = B_U_tab[u];
852                          b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT));   \                          g_uv = G_U_tab[u] + G_V_tab[v];
853                          g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT));  \                          r_v = R_V_tab[v];
854                          r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT));   \  
855                          dst[0] = (C1);                                                  \                          rgb_y = RGB_Y_tab[*y_src];
856                          dst[1] = (C2);                                                  \                          b = (rgb_y + b_u) >> SCALEBITS_OUT;
857                          dst[2] = (C3);                                                  \                          g = (rgb_y - g_uv) >> SCALEBITS_OUT;
858                          if ((SIZE)>3) dst[3] = (C4);                    \                          r = (rgb_y + r_v) >> SCALEBITS_OUT;
859                          y_src++;                                                                \                          dst[0] = MAX(0, MIN(255, b));
860  \                          dst[1] = MAX(0, MIN(255, g));
861                          rgb_y = RGB_Y_tab[*y_src];                              \                          dst[2] = MAX(0, MIN(255, r));
862                          b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT));   \  
863                          g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT));  \                          y_src++;
864                          r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT));   \                          rgb_y = RGB_Y_tab[*y_src];
865                          dst[(SIZE)+0] = (C1);                                                   \                          b = (rgb_y + b_u) >> SCALEBITS_OUT;
866                          dst[(SIZE)+1] = (C2);                                                   \                          g = (rgb_y - g_uv) >> SCALEBITS_OUT;
867                          dst[(SIZE)+2] = (C3);                                                   \                          r = (rgb_y + r_v) >> SCALEBITS_OUT;
868                          if ((SIZE)>3) dst[(SIZE)+3] = (C4);                     \                          dst[3] = MAX(0, MIN(255, b));
869                          y_src++;                                                                \                          dst[4] = MAX(0, MIN(255, g));
870  \                          dst[5] = MAX(0, MIN(255, r));
871                          rgb_y = RGB_Y_tab[*y_src2];                             \                          y_src++;
872                          b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT));   \  
873                          g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT));  \                          rgb_y = RGB_Y_tab[*y_src2];
874                          r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT));   \                          b = (rgb_y + b_u) >> SCALEBITS_OUT;
875                          dst2[0] = (C1);                                                 \                          g = (rgb_y - g_uv) >> SCALEBITS_OUT;
876                          dst2[1] = (C2);                                                 \                          r = (rgb_y + r_v) >> SCALEBITS_OUT;
877                          dst2[2] = (C3);                                                 \                          dst2[0] = MAX(0, MIN(255, b));
878                          if ((SIZE)>3) dst2[3] = (C4);                   \                          dst2[1] = MAX(0, MIN(255, g));
879                          y_src2++;                                                               \                          dst2[2] = MAX(0, MIN(255, r));
880  \                          y_src2++;
881                          rgb_y = RGB_Y_tab[*y_src2];                             \  
882                          b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT));   \                          rgb_y = RGB_Y_tab[*y_src2];
883                          g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT));  \                          b = (rgb_y + b_u) >> SCALEBITS_OUT;
884                          r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT));   \                          g = (rgb_y - g_uv) >> SCALEBITS_OUT;
885                          dst2[(SIZE)+0] = (C1);                                                  \                          r = (rgb_y + r_v) >> SCALEBITS_OUT;
886                          dst2[(SIZE)+1] = (C2);                                                  \                          dst2[3] = MAX(0, MIN(255, b));
887                          dst2[(SIZE)+2] = (C3);                                                  \                          dst2[4] = MAX(0, MIN(255, g));
888                          if ((SIZE)>3) dst2[(SIZE)+3] = (C4);                    \                          dst2[5] = MAX(0, MIN(255, r));
889                          y_src2++;                                                               \                          y_src2++;
890  \  
891                          dst += 2*(SIZE);                        \                          dst += 6;
892                          dst2 += 2*(SIZE);                       \                          dst2 += 6;
893                  }                                               \                  }
894                  dst += dst_dif;                                 \  
895                  dst2 += dst_dif;                                \                  dst += dst_dif;
896                  y_src += y_dif;                                 \                  dst2 += dst_dif;
897                  y_src2 += y_dif;                                \  
898                  u_src += uv_stride;                             \                  y_src += y_dif;
899                  v_src += uv_stride;                             \                  y_src2 += y_dif;
900          }               \  
901  }                  u_src += uv_stride;
902                    v_src += uv_stride;
903  MAKE_YV12_TO_RGB_C(rgb24,3, b,g,r,0)            /* yuv420 -> bgr */          }
904  MAKE_YV12_TO_RGB_C(rgb32,4, b,g,r,a)            /* yuv420 -> bgra */  }
905  MAKE_YV12_TO_RGB_C(abgr, 4, a,b,g,r)            /* yuv420 -> abgr */  
906  MAKE_YV12_TO_RGB_C(rgba, 4, r,g,b,a)            /* yuv420 -> rgba */  
907    
908    /* yuv 4:2:0 planar -> rgb32 */
909    
910    void
911    yv12_to_rgb32_c(uint8_t * dst,
912                                    int dst_stride,
913                                    uint8_t * y_src,
914                                    uint8_t * v_src,
915                                    uint8_t * u_src,
916                                    int y_stride,
917                                    int uv_stride,
918                                    int width,
919                                    int height)
920    {
921            const uint32_t dst_dif = 8 * dst_stride - 4 * width;
922            int32_t y_dif = 2 * y_stride - width;
923    
924            uint8_t *dst2 = dst + 4 * dst_stride;
925            uint8_t *y_src2 = y_src + y_stride;
926            uint32_t x, y;
927    
928            if (height < 0) {                       /* flip image? */
929                    height = -height;
930                    y_src += (height - 1) * y_stride;
931                    y_src2 = y_src - y_stride;
932                    u_src += (height / 2 - 1) * uv_stride;
933                    v_src += (height / 2 - 1) * uv_stride;
934                    y_dif = -width - 2 * y_stride;
935                    uv_stride = -uv_stride;
936            }
937    
938            for (y = height / 2; y; y--) {
939                    /* process one 2x2 block per iteration */
940                    for (x = 0; x < (uint32_t) width / 2; x++) {
941                            int u, v;
942                            int b_u, g_uv, r_v, rgb_y;
943                            int r, g, b;
944    
945                            u = u_src[x];
946                            v = v_src[x];
947    
948                            b_u = B_U_tab[u];
949                            g_uv = G_U_tab[u] + G_V_tab[v];
950                            r_v = R_V_tab[v];
951    
952                            rgb_y = RGB_Y_tab[*y_src];
953                            b = (rgb_y + b_u) >> SCALEBITS_OUT;
954                            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
955                            r = (rgb_y + r_v) >> SCALEBITS_OUT;
956                            dst[0] = MAX(0, MIN(255, r));
957                            dst[1] = MAX(0, MIN(255, g));
958                            dst[2] = MAX(0, MIN(255, b));
959                            dst[3] = 0;
960    
961                            y_src++;
962                            rgb_y = RGB_Y_tab[*y_src];
963                            b = (rgb_y + b_u) >> SCALEBITS_OUT;
964                            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
965                            r = (rgb_y + r_v) >> SCALEBITS_OUT;
966                            dst[4] = MAX(0, MIN(255, r));
967                            dst[5] = MAX(0, MIN(255, g));
968                            dst[6] = MAX(0, MIN(255, b));
969                            dst[7] = 0;
970                            y_src++;
971    
972                            rgb_y = RGB_Y_tab[*y_src2];
973                            b = (rgb_y + b_u) >> SCALEBITS_OUT;
974                            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
975                            r = (rgb_y + r_v) >> SCALEBITS_OUT;
976                            dst2[0] = MAX(0, MIN(255, r));
977                            dst2[1] = MAX(0, MIN(255, g));
978                            dst2[2] = MAX(0, MIN(255, b));
979                            dst2[3] = 0;
980                            y_src2++;
981    
982                            rgb_y = RGB_Y_tab[*y_src2];
983                            b = (rgb_y + b_u) >> SCALEBITS_OUT;
984                            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
985                            r = (rgb_y + r_v) >> SCALEBITS_OUT;
986                            dst2[4] = MAX(0, MIN(255, r));
987                            dst2[5] = MAX(0, MIN(255, g));
988                            dst2[6] = MAX(0, MIN(255, b));
989                            dst2[7] = 0;
990                            y_src2++;
991    
992                            dst += 8;
993                            dst2 += 8;
994                    }
995    
996                    dst += dst_dif;
997                    dst2 += dst_dif;
998    
999                    y_src += y_dif;
1000                    y_src2 += y_dif;
1001    
1002                    u_src += uv_stride;
1003                    v_src += uv_stride;
1004            }
1005    }
1006    
1007    
1008    
# Line 946  Line 1067 
1067                             int width,                             int width,
1068                             int height)                             int height)
1069  {  {
1070          const uint32_t dst_dif = dst_stride - (2 * width);          const uint32_t dst_dif = 2 * (dst_stride - width);
1071          uint32_t x, y;          uint32_t x, y;
1072    
1073          if (height < 0) {          if (height < 0) {
# Line 990  Line 1111 
1111                             int width,                             int width,
1112                             int height)                             int height)
1113  {  {
1114          const uint32_t dst_dif = dst_stride - (2 * width);          const uint32_t dst_dif = 2 * (dst_stride - width);
1115          uint32_t x, y;          uint32_t x, y;
1116    
1117          if (height < 0) {          if (height < 0) {

Legend:
Removed from v.1.3.2.1  
changed lines
  Added in v.1.7

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4