• Home
  • History
  • Annotate
  • 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,
21                               JSAMPIMAGE input_buf, JDIMENSION input_row,
22                               JSAMPARRAY output_buf, 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  = GETJSAMPLE(*inptr0++);
49        cb = GETJSAMPLE(*inptr1++);
50        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0++);
62        cb = GETJSAMPLE(*inptr1++);
63        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0++);
71        cb = GETJSAMPLE(*inptr1++);
72        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0);
84        cb = GETJSAMPLE(*inptr1);
85        cr = GETJSAMPLE(*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,
100                                JSAMPIMAGE input_buf, JDIMENSION input_row,
101                                JSAMPARRAY output_buf, 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  = GETJSAMPLE(*inptr0++);
129        cb = GETJSAMPLE(*inptr1++);
130        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0++);
143        cb = GETJSAMPLE(*inptr1++);
144        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0++);
154        cb = GETJSAMPLE(*inptr1++);
155        cr = GETJSAMPLE(*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  = GETJSAMPLE(*inptr0);
169        cb = GETJSAMPLE(*inptr1);
170        cr = GETJSAMPLE(*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,
186                               JSAMPIMAGE input_buf, JDIMENSION input_row,
187                               JSAMPARRAY output_buf, 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 = GETJSAMPLE(*inptr0++);
206        g = GETJSAMPLE(*inptr1++);
207        b = GETJSAMPLE(*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 = GETJSAMPLE(*inptr0++);
215        g = GETJSAMPLE(*inptr1++);
216        b = GETJSAMPLE(*inptr2++);
217        rgb = PACK_SHORT_565(r, g, b);
218  
219        r = GETJSAMPLE(*inptr0++);
220        g = GETJSAMPLE(*inptr1++);
221        b = GETJSAMPLE(*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 = GETJSAMPLE(*inptr0);
229        g = GETJSAMPLE(*inptr1);
230        b = GETJSAMPLE(*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,
241                                JSAMPIMAGE input_buf, JDIMENSION input_row,
242                                JSAMPARRAY output_buf, 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(GETJSAMPLE(*inptr0++), d0)];
263        g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
264        b = range_limit[DITHER_565_B(GETJSAMPLE(*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(GETJSAMPLE(*inptr0++), d0)];
272        g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
273        b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
274        d0 = DITHER_ROTATE(d0);
275        rgb = PACK_SHORT_565(r, g, b);
276  
277        r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
278        g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
279        b = range_limit[DITHER_565_B(GETJSAMPLE(*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(GETJSAMPLE(*inptr0), d0)];
288        g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
289        b = range_limit[DITHER_565_B(GETJSAMPLE(*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,
300                                JSAMPIMAGE input_buf, JDIMENSION input_row,
301                                JSAMPARRAY output_buf, 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,
340                                 JSAMPIMAGE input_buf, JDIMENSION input_row,
341                                 JSAMPARRAY output_buf, 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