• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * jdcolext.c
3  *
4  * This file was part of the Independent JPEG Group's software:
5  * Copyright (C) 1991-1997, Thomas G. Lane.
6  * libjpeg-turbo Modifications:
7  * Copyright (C) 2009, 2011, 2015, D. R. Commander.
8  * For conditions of distribution and use, see the accompanying README.ijg
9  * file.
10  *
11  * This file contains output colorspace conversion routines.
12  */
13 
14 
15 /* This file is included by jdcolor.c */
16 
17 
18 /*
19  * Convert some rows of samples to the output colorspace.
20  *
21  * Note that we change from noninterleaved, one-plane-per-component format
22  * to interleaved-pixel format.  The output buffer is therefore three times
23  * as wide as the input buffer.
24  * A starting row offset is provided only for the input buffer.  The caller
25  * can easily adjust the passed output_buf value to accommodate any row
26  * offset required on that side.
27  */
28 
29 INLINE
LOCAL(void)30 LOCAL(void)
31 ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
32                          JDIMENSION input_row, JSAMPARRAY output_buf,
33                          int num_rows)
34 {
35   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
36   register int y, cb, cr;
37   register JSAMPROW outptr;
38   register JSAMPROW inptr0, inptr1, inptr2;
39   register JDIMENSION col;
40   JDIMENSION num_cols = cinfo->output_width;
41   /* copy these pointers into registers if possible */
42   register JSAMPLE *range_limit = cinfo->sample_range_limit;
43   register int *Crrtab = cconvert->Cr_r_tab;
44   register int *Cbbtab = cconvert->Cb_b_tab;
45   register JLONG *Crgtab = cconvert->Cr_g_tab;
46   register JLONG *Cbgtab = cconvert->Cb_g_tab;
47   SHIFT_TEMPS
48 
49   while (--num_rows >= 0) {
50     inptr0 = input_buf[0][input_row];
51     inptr1 = input_buf[1][input_row];
52     inptr2 = input_buf[2][input_row];
53     input_row++;
54     outptr = *output_buf++;
55     for (col = 0; col < num_cols; col++) {
56       y  = inptr0[col];
57       cb = inptr1[col];
58       cr = inptr2[col];
59       /* Range-limiting is essential due to noise introduced by DCT losses. */
60       outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
61       outptr[RGB_GREEN] = range_limit[y +
62                               ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
63                                                 SCALEBITS))];
64       outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
65       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
66       /* alpha channel value */
67 #ifdef RGB_ALPHA
68       outptr[RGB_ALPHA] = 0xFF;
69 #endif
70       outptr += RGB_PIXELSIZE;
71     }
72   }
73 }
74 
75 
76 /*
77  * Convert grayscale to RGB: just duplicate the graylevel three times.
78  * This is provided to support applications that don't want to cope
79  * with grayscale as a separate case.
80  */
81 
82 INLINE
LOCAL(void)83 LOCAL(void)
84 gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
85                           JDIMENSION input_row, JSAMPARRAY output_buf,
86                           int num_rows)
87 {
88   register JSAMPROW inptr, outptr;
89   register JDIMENSION col;
90   JDIMENSION num_cols = cinfo->output_width;
91 
92   while (--num_rows >= 0) {
93     inptr = input_buf[0][input_row++];
94     outptr = *output_buf++;
95     for (col = 0; col < num_cols; col++) {
96       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
97       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
98       /* alpha channel value */
99 #ifdef RGB_ALPHA
100       outptr[RGB_ALPHA] = 0xFF;
101 #endif
102       outptr += RGB_PIXELSIZE;
103     }
104   }
105 }
106 
107 
108 /*
109  * Convert RGB to extended RGB: just swap the order of source pixels
110  */
111 
112 INLINE
LOCAL(void)113 LOCAL(void)
114 rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
115                          JDIMENSION input_row, JSAMPARRAY output_buf,
116                          int num_rows)
117 {
118   register JSAMPROW inptr0, inptr1, inptr2;
119   register JSAMPROW outptr;
120   register JDIMENSION col;
121   JDIMENSION num_cols = cinfo->output_width;
122 
123   while (--num_rows >= 0) {
124     inptr0 = input_buf[0][input_row];
125     inptr1 = input_buf[1][input_row];
126     inptr2 = input_buf[2][input_row];
127     input_row++;
128     outptr = *output_buf++;
129     for (col = 0; col < num_cols; col++) {
130       outptr[RGB_RED] = inptr0[col];
131       outptr[RGB_GREEN] = inptr1[col];
132       outptr[RGB_BLUE] = inptr2[col];
133       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
134       /* alpha channel value */
135 #ifdef RGB_ALPHA
136       outptr[RGB_ALPHA] = 0xFF;
137 #endif
138       outptr += RGB_PIXELSIZE;
139     }
140   }
141 }
142