• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * jdcol565.c
3  *
4  * This file was part of the Independent JPEG Group's software:
5  * Copyright (C) 1991-1997, Thomas G. Lane.
6  * Modifications:
7  * Copyright (C) 2013, Linaro Limited.
8  * Copyright (C) 2014-2015, D. R. Commander.
9  * For conditions of distribution and use, see the accompanying README.ijg
10  * file.
11  *
12  * This file contains output colorspace conversion routines.
13  */
14 
15 /* This file is included by jdcolor.c */
16 
17 
18 INLINE
LOCAL(void)19 LOCAL(void)
20 ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
21                             JDIMENSION input_row, JSAMPARRAY output_buf,
22                             int num_rows)
23 {
24   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
25   register int y, cb, cr;
26   register JSAMPROW outptr;
27   register JSAMPROW inptr0, inptr1, inptr2;
28   register JDIMENSION col;
29   JDIMENSION num_cols = cinfo->output_width;
30   /* copy these pointers into registers if possible */
31   register JSAMPLE *range_limit = cinfo->sample_range_limit;
32   register int *Crrtab = cconvert->Cr_r_tab;
33   register int *Cbbtab = cconvert->Cb_b_tab;
34   register JLONG *Crgtab = cconvert->Cr_g_tab;
35   register JLONG *Cbgtab = cconvert->Cb_g_tab;
36   SHIFT_TEMPS
37 
38   while (--num_rows >= 0) {
39     JLONG rgb;
40     unsigned int r, g, b;
41     inptr0 = input_buf[0][input_row];
42     inptr1 = input_buf[1][input_row];
43     inptr2 = input_buf[2][input_row];
44     input_row++;
45     outptr = *output_buf++;
46 
47     if (PACK_NEED_ALIGNMENT(outptr)) {
48       y  = *inptr0++;
49       cb = *inptr1++;
50       cr = *inptr2++;
51       r = range_limit[y + Crrtab[cr]];
52       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
53                                             SCALEBITS))];
54       b = range_limit[y + Cbbtab[cb]];
55       rgb = PACK_SHORT_565(r, g, b);
56       *(INT16 *)outptr = (INT16)rgb;
57       outptr += 2;
58       num_cols--;
59     }
60     for (col = 0; col < (num_cols >> 1); col++) {
61       y  = *inptr0++;
62       cb = *inptr1++;
63       cr = *inptr2++;
64       r = range_limit[y + Crrtab[cr]];
65       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
66                                             SCALEBITS))];
67       b = range_limit[y + Cbbtab[cb]];
68       rgb = PACK_SHORT_565(r, g, b);
69 
70       y  = *inptr0++;
71       cb = *inptr1++;
72       cr = *inptr2++;
73       r = range_limit[y + Crrtab[cr]];
74       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
75                                             SCALEBITS))];
76       b = range_limit[y + Cbbtab[cb]];
77       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
78 
79       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
80       outptr += 4;
81     }
82     if (num_cols & 1) {
83       y  = *inptr0;
84       cb = *inptr1;
85       cr = *inptr2;
86       r = range_limit[y + Crrtab[cr]];
87       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
88                                             SCALEBITS))];
89       b = range_limit[y + Cbbtab[cb]];
90       rgb = PACK_SHORT_565(r, g, b);
91       *(INT16 *)outptr = (INT16)rgb;
92     }
93   }
94 }
95 
96 
97 INLINE
LOCAL(void)98 LOCAL(void)
99 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
100                              JDIMENSION input_row, JSAMPARRAY output_buf,
101                              int num_rows)
102 {
103   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
104   register int y, cb, cr;
105   register JSAMPROW outptr;
106   register JSAMPROW inptr0, inptr1, inptr2;
107   register JDIMENSION col;
108   JDIMENSION num_cols = cinfo->output_width;
109   /* copy these pointers into registers if possible */
110   register JSAMPLE *range_limit = cinfo->sample_range_limit;
111   register int *Crrtab = cconvert->Cr_r_tab;
112   register int *Cbbtab = cconvert->Cb_b_tab;
113   register JLONG *Crgtab = cconvert->Cr_g_tab;
114   register JLONG *Cbgtab = cconvert->Cb_g_tab;
115   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
116   SHIFT_TEMPS
117 
118   while (--num_rows >= 0) {
119     JLONG rgb;
120     unsigned int r, g, b;
121 
122     inptr0 = input_buf[0][input_row];
123     inptr1 = input_buf[1][input_row];
124     inptr2 = input_buf[2][input_row];
125     input_row++;
126     outptr = *output_buf++;
127     if (PACK_NEED_ALIGNMENT(outptr)) {
128       y  = *inptr0++;
129       cb = *inptr1++;
130       cr = *inptr2++;
131       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
132       g = range_limit[DITHER_565_G(y +
133                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
134                                                      SCALEBITS)), d0)];
135       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
136       rgb = PACK_SHORT_565(r, g, b);
137       *(INT16 *)outptr = (INT16)rgb;
138       outptr += 2;
139       num_cols--;
140     }
141     for (col = 0; col < (num_cols >> 1); col++) {
142       y  = *inptr0++;
143       cb = *inptr1++;
144       cr = *inptr2++;
145       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
146       g = range_limit[DITHER_565_G(y +
147                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
148                                                      SCALEBITS)), d0)];
149       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
150       d0 = DITHER_ROTATE(d0);
151       rgb = PACK_SHORT_565(r, g, b);
152 
153       y  = *inptr0++;
154       cb = *inptr1++;
155       cr = *inptr2++;
156       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
157       g = range_limit[DITHER_565_G(y +
158                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
159                                                      SCALEBITS)), d0)];
160       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
161       d0 = DITHER_ROTATE(d0);
162       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
163 
164       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
165       outptr += 4;
166     }
167     if (num_cols & 1) {
168       y  = *inptr0;
169       cb = *inptr1;
170       cr = *inptr2;
171       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
172       g = range_limit[DITHER_565_G(y +
173                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
174                                                      SCALEBITS)), d0)];
175       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
176       rgb = PACK_SHORT_565(r, g, b);
177       *(INT16 *)outptr = (INT16)rgb;
178     }
179   }
180 }
181 
182 
183 INLINE
LOCAL(void)184 LOCAL(void)
185 rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
186                             JDIMENSION input_row, JSAMPARRAY output_buf,
187                             int num_rows)
188 {
189   register JSAMPROW outptr;
190   register JSAMPROW inptr0, inptr1, inptr2;
191   register JDIMENSION col;
192   JDIMENSION num_cols = cinfo->output_width;
193   SHIFT_TEMPS
194 
195   while (--num_rows >= 0) {
196     JLONG rgb;
197     unsigned int r, g, b;
198 
199     inptr0 = input_buf[0][input_row];
200     inptr1 = input_buf[1][input_row];
201     inptr2 = input_buf[2][input_row];
202     input_row++;
203     outptr = *output_buf++;
204     if (PACK_NEED_ALIGNMENT(outptr)) {
205       r = *inptr0++;
206       g = *inptr1++;
207       b = *inptr2++;
208       rgb = PACK_SHORT_565(r, g, b);
209       *(INT16 *)outptr = (INT16)rgb;
210       outptr += 2;
211       num_cols--;
212     }
213     for (col = 0; col < (num_cols >> 1); col++) {
214       r = *inptr0++;
215       g = *inptr1++;
216       b = *inptr2++;
217       rgb = PACK_SHORT_565(r, g, b);
218 
219       r = *inptr0++;
220       g = *inptr1++;
221       b = *inptr2++;
222       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
223 
224       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
225       outptr += 4;
226     }
227     if (num_cols & 1) {
228       r = *inptr0;
229       g = *inptr1;
230       b = *inptr2;
231       rgb = PACK_SHORT_565(r, g, b);
232       *(INT16 *)outptr = (INT16)rgb;
233     }
234   }
235 }
236 
237 
238 INLINE
LOCAL(void)239 LOCAL(void)
240 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
241                              JDIMENSION input_row, JSAMPARRAY output_buf,
242                              int num_rows)
243 {
244   register JSAMPROW outptr;
245   register JSAMPROW inptr0, inptr1, inptr2;
246   register JDIMENSION col;
247   register JSAMPLE *range_limit = cinfo->sample_range_limit;
248   JDIMENSION num_cols = cinfo->output_width;
249   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
250   SHIFT_TEMPS
251 
252   while (--num_rows >= 0) {
253     JLONG rgb;
254     unsigned int r, g, b;
255 
256     inptr0 = input_buf[0][input_row];
257     inptr1 = input_buf[1][input_row];
258     inptr2 = input_buf[2][input_row];
259     input_row++;
260     outptr = *output_buf++;
261     if (PACK_NEED_ALIGNMENT(outptr)) {
262       r = range_limit[DITHER_565_R(*inptr0++, d0)];
263       g = range_limit[DITHER_565_G(*inptr1++, d0)];
264       b = range_limit[DITHER_565_B(*inptr2++, d0)];
265       rgb = PACK_SHORT_565(r, g, b);
266       *(INT16 *)outptr = (INT16)rgb;
267       outptr += 2;
268       num_cols--;
269     }
270     for (col = 0; col < (num_cols >> 1); col++) {
271       r = range_limit[DITHER_565_R(*inptr0++, d0)];
272       g = range_limit[DITHER_565_G(*inptr1++, d0)];
273       b = range_limit[DITHER_565_B(*inptr2++, d0)];
274       d0 = DITHER_ROTATE(d0);
275       rgb = PACK_SHORT_565(r, g, b);
276 
277       r = range_limit[DITHER_565_R(*inptr0++, d0)];
278       g = range_limit[DITHER_565_G(*inptr1++, d0)];
279       b = range_limit[DITHER_565_B(*inptr2++, d0)];
280       d0 = DITHER_ROTATE(d0);
281       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
282 
283       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
284       outptr += 4;
285     }
286     if (num_cols & 1) {
287       r = range_limit[DITHER_565_R(*inptr0, d0)];
288       g = range_limit[DITHER_565_G(*inptr1, d0)];
289       b = range_limit[DITHER_565_B(*inptr2, d0)];
290       rgb = PACK_SHORT_565(r, g, b);
291       *(INT16 *)outptr = (INT16)rgb;
292     }
293   }
294 }
295 
296 
297 INLINE
LOCAL(void)298 LOCAL(void)
299 gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
300                              JDIMENSION input_row, JSAMPARRAY output_buf,
301                              int num_rows)
302 {
303   register JSAMPROW inptr, outptr;
304   register JDIMENSION col;
305   JDIMENSION num_cols = cinfo->output_width;
306 
307   while (--num_rows >= 0) {
308     JLONG rgb;
309     unsigned int g;
310 
311     inptr = input_buf[0][input_row++];
312     outptr = *output_buf++;
313     if (PACK_NEED_ALIGNMENT(outptr)) {
314       g = *inptr++;
315       rgb = PACK_SHORT_565(g, g, g);
316       *(INT16 *)outptr = (INT16)rgb;
317       outptr += 2;
318       num_cols--;
319     }
320     for (col = 0; col < (num_cols >> 1); col++) {
321       g = *inptr++;
322       rgb = PACK_SHORT_565(g, g, g);
323       g = *inptr++;
324       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
325       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
326       outptr += 4;
327     }
328     if (num_cols & 1) {
329       g = *inptr;
330       rgb = PACK_SHORT_565(g, g, g);
331       *(INT16 *)outptr = (INT16)rgb;
332     }
333   }
334 }
335 
336 
337 INLINE
LOCAL(void)338 LOCAL(void)
339 gray_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
340                               JDIMENSION input_row, JSAMPARRAY output_buf,
341                               int num_rows)
342 {
343   register JSAMPROW inptr, outptr;
344   register JDIMENSION col;
345   register JSAMPLE *range_limit = cinfo->sample_range_limit;
346   JDIMENSION num_cols = cinfo->output_width;
347   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
348 
349   while (--num_rows >= 0) {
350     JLONG rgb;
351     unsigned int g;
352 
353     inptr = input_buf[0][input_row++];
354     outptr = *output_buf++;
355     if (PACK_NEED_ALIGNMENT(outptr)) {
356       g = *inptr++;
357       g = range_limit[DITHER_565_R(g, d0)];
358       rgb = PACK_SHORT_565(g, g, g);
359       *(INT16 *)outptr = (INT16)rgb;
360       outptr += 2;
361       num_cols--;
362     }
363     for (col = 0; col < (num_cols >> 1); col++) {
364       g = *inptr++;
365       g = range_limit[DITHER_565_R(g, d0)];
366       rgb = PACK_SHORT_565(g, g, g);
367       d0 = DITHER_ROTATE(d0);
368 
369       g = *inptr++;
370       g = range_limit[DITHER_565_R(g, d0)];
371       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
372       d0 = DITHER_ROTATE(d0);
373 
374       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
375       outptr += 4;
376     }
377     if (num_cols & 1) {
378       g = *inptr;
379       g = range_limit[DITHER_565_R(g, d0)];
380       rgb = PACK_SHORT_565(g, g, g);
381       *(INT16 *)outptr = (INT16)rgb;
382     }
383   }
384 }
385