1 /*
2  * Small jpeg decoder library
3  *
4  * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
5  * All rights reserved.
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice,
10  *  this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright notice,
13  *  this list of conditions and the following disclaimer in the documentation
14  *  and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the author nor the names of its contributors may be
17  *  used to endorse or promote products derived from this software without
18  *  specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdint.h>
38 
39 #include "tinyjpeg.h"
40 #include "tinyjpeg-internal.h"
41 
42 /*******************************************************************************
43  *
44  * Colorspace conversion routine
45  *
46  *
47  * Note:
48  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
49  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
50  * The conversion equations to be implemented are therefore
51  *      R = Y                + 1.40200 * Cr
52  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
53  *      B = Y + 1.77200 * Cb
54  *
55  ******************************************************************************/
clamp(int i)56 static unsigned char clamp(int i)
57 {
58   if (i<0)
59     return 0;
60   else if (i>255)
61     return 255;
62   else
63     return i;
64 }
65 
66 /**
67  *  YCrCb -> RGB24 (1x1)
68  *  .---.
69  *  | 1 |
70  *  `---'
71  */
YCrCB_to_RGB24_1x1(struct jdec_private * priv,int sx,int sy)72 static void YCrCB_to_RGB24_1x1(struct jdec_private *priv, int sx, int sy)
73 {
74   const unsigned char *Y, *Cb, *Cr;
75   unsigned char *p;
76   int i,j;
77   int offset_to_next_row;
78 
79 #define SCALEBITS       10
80 #define ONE_HALF        (1UL << (SCALEBITS-1))
81 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
82 
83   p = priv->plane[0];
84   Y = priv->Y;
85   Cb = priv->Cb;
86   Cr = priv->Cr;
87   offset_to_next_row = priv->bytes_per_row[0] - 8*3;
88   for (i = sy; i > 0; i--) {
89     for (j = sx; j > 0; j++) {
90        int y, cb, cr;
91        int add_r, add_g, add_b;
92        int r, g , b;
93 
94        y  = Y[0] << SCALEBITS;
95        cb = *Cb++ - 128;
96        cr = *Cr++ - 128;
97        add_r = FIX(1.40200) * cr + ONE_HALF;
98        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
99        add_b = FIX(1.77200) * cb + ONE_HALF;
100 
101        r = (y + add_r) >> SCALEBITS;
102        *p++ = clamp(r);
103        g = (y + add_g) >> SCALEBITS;
104        *p++ = clamp(g);
105        b = (y + add_b) >> SCALEBITS;
106        *p++ = clamp(b);
107 
108        Y++;
109     }
110 
111     p += offset_to_next_row;
112   }
113 
114 #undef SCALEBITS
115 #undef ONE_HALF
116 #undef FIX
117 
118 }
119 
120 /**
121  *  YCrCb -> RGB24 (2x1)
122  *  .-------.
123  *  | 1 | 2 |
124  *  `-------'
125  */
YCrCB_to_RGB24_2x1(struct jdec_private * priv,int sx,int sy)126 static void YCrCB_to_RGB24_2x1(struct jdec_private *priv, int sx, int sy)
127 {
128   const unsigned char *Y, *Cb, *Cr;
129   unsigned char *p;
130   int i,j;
131   int offset_to_next_row;
132 
133 #define SCALEBITS       10
134 #define ONE_HALF        (1UL << (SCALEBITS-1))
135 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
136 
137   p = priv->plane[0];
138   Y = priv->Y;
139   Cb = priv->Cb;
140   Cr = priv->Cr;
141   offset_to_next_row = priv->bytes_per_row[0] - 16*3;
142   for (i = sy; i > 0; i--) {
143 
144     for (j = sx; j > 0; j -= 2) {
145 
146        int y, cb, cr;
147        int add_r, add_g, add_b;
148        int r, g , b;
149 
150        y  = Y[0] << SCALEBITS;
151        cb = *Cb++ - 128;
152        cr = *Cr++ - 128;
153        add_r = FIX(1.40200) * cr + ONE_HALF;
154        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
155        add_b = FIX(1.77200) * cb + ONE_HALF;
156 
157        r = (y + add_r) >> SCALEBITS;
158        *p++ = clamp(r);
159        g = (y + add_g) >> SCALEBITS;
160        *p++ = clamp(g);
161        b = (y + add_b) >> SCALEBITS;
162        *p++ = clamp(b);
163 
164        if (j > 1) {
165 	   y  = Y[1] << SCALEBITS;
166 	   r = (y + add_r) >> SCALEBITS;
167 	   *p++ = clamp(r);
168 	   g = (y + add_g) >> SCALEBITS;
169 	   *p++ = clamp(g);
170 	   b = (y + add_b) >> SCALEBITS;
171 	   *p++ = clamp(b);
172        }
173 
174        Y += 2;
175     }
176 
177     p += offset_to_next_row;
178   }
179 
180 #undef SCALEBITS
181 #undef ONE_HALF
182 #undef FIX
183 
184 }
185 
186 
187 /**
188  *  YCrCb -> RGB24 (1x2)
189  *  .---.
190  *  | 1 |
191  *  |---|
192  *  | 2 |
193  *  `---'
194  */
YCrCB_to_RGB24_1x2(struct jdec_private * priv,int sx,int sy)195 static void YCrCB_to_RGB24_1x2(struct jdec_private *priv, int sx, int sy)
196 {
197   const unsigned char *Y, *Cb, *Cr;
198   unsigned char *p, *p2;
199   int i,j;
200   int offset_to_next_row;
201 
202 #define SCALEBITS       10
203 #define ONE_HALF        (1UL << (SCALEBITS-1))
204 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
205 
206   p = priv->plane[0];
207   p2 = priv->plane[0] + priv->bytes_per_row[0];
208   Y = priv->Y;
209   Cb = priv->Cb;
210   Cr = priv->Cr;
211   offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
212   for (i = sy; i > 0; i -= 2) {
213     for (j = sx; j > 0; j--) {
214 
215        int y, cb, cr;
216        int add_r, add_g, add_b;
217        int r, g , b;
218 
219        cb = *Cb++ - 128;
220        cr = *Cr++ - 128;
221        add_r = FIX(1.40200) * cr + ONE_HALF;
222        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
223        add_b = FIX(1.77200) * cb + ONE_HALF;
224 
225        y  = Y[0] << SCALEBITS;
226        r = (y + add_r) >> SCALEBITS;
227        *p++ = clamp(r);
228        g = (y + add_g) >> SCALEBITS;
229        *p++ = clamp(g);
230        b = (y + add_b) >> SCALEBITS;
231        *p++ = clamp(b);
232 
233        if (i > 1) {
234 	   y  = Y[8] << SCALEBITS;
235 	   r = (y + add_r) >> SCALEBITS;
236 	   *p2++ = clamp(r);
237 	   g = (y + add_g) >> SCALEBITS;
238 	   *p2++ = clamp(g);
239 	   b = (y + add_b) >> SCALEBITS;
240 	   *p2++ = clamp(b);
241        }
242 
243        Y++;
244     }
245     Y += 8;
246     p += offset_to_next_row;
247     p2 += offset_to_next_row;
248   }
249 
250 #undef SCALEBITS
251 #undef ONE_HALF
252 #undef FIX
253 
254 }
255 
256 /**
257  *  YCrCb -> RGB24 (2x2)
258  *  .-------.
259  *  | 1 | 2 |
260  *  |---+---|
261  *  | 3 | 4 |
262  *  `-------'
263  */
YCrCB_to_RGB24_2x2(struct jdec_private * priv,int sx,int sy)264 static void YCrCB_to_RGB24_2x2(struct jdec_private *priv, int sx, int sy)
265 {
266   const unsigned char *Y, *Cb, *Cr;
267   unsigned char *p, *p2;
268   int i,j;
269   int offset_to_next_row;
270 
271 #define SCALEBITS       10
272 #define ONE_HALF        (1UL << (SCALEBITS-1))
273 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
274 
275   p = priv->plane[0];
276   p2 = priv->plane[0] + priv->bytes_per_row[0];
277   Y = priv->Y;
278   Cb = priv->Cb;
279   Cr = priv->Cr;
280   offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
281   for (i = sy; i > 0; i -= 2) {
282     for (j = sx; j > 0; j -= 2) {
283 
284        int y, cb, cr;
285        int add_r, add_g, add_b;
286        int r, g , b;
287 
288        cb = *Cb++ - 128;
289        cr = *Cr++ - 128;
290        add_r = FIX(1.40200) * cr + ONE_HALF;
291        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
292        add_b = FIX(1.77200) * cb + ONE_HALF;
293 
294        y  = Y[0] << SCALEBITS;
295        r = (y + add_r) >> SCALEBITS;
296        *p++ = clamp(r);
297        g = (y + add_g) >> SCALEBITS;
298        *p++ = clamp(g);
299        b = (y + add_b) >> SCALEBITS;
300        *p++ = clamp(b);
301 
302        if (j > 1) {
303 	   y  = Y[1] << SCALEBITS;
304 	   r = (y + add_r) >> SCALEBITS;
305 	   *p++ = clamp(r);
306 	   g = (y + add_g) >> SCALEBITS;
307 	   *p++ = clamp(g);
308 	   b = (y + add_b) >> SCALEBITS;
309 	   *p++ = clamp(b);
310        }
311 
312        if (i > 1) {
313 	   y  = Y[16+0] << SCALEBITS;
314 	   r = (y + add_r) >> SCALEBITS;
315 	   *p2++ = clamp(r);
316 	   g = (y + add_g) >> SCALEBITS;
317 	   *p2++ = clamp(g);
318 	   b = (y + add_b) >> SCALEBITS;
319 	   *p2++ = clamp(b);
320 
321 	   if (j > 1) {
322 	       y  = Y[16+1] << SCALEBITS;
323 	       r = (y + add_r) >> SCALEBITS;
324 	       *p2++ = clamp(r);
325 	       g = (y + add_g) >> SCALEBITS;
326 	       *p2++ = clamp(g);
327 	       b = (y + add_b) >> SCALEBITS;
328 	       *p2++ = clamp(b);
329 	   }
330        }
331 
332        Y += 2;
333     }
334     Y  += 16;
335     p  += offset_to_next_row;
336     p2 += offset_to_next_row;
337   }
338 
339 #undef SCALEBITS
340 #undef ONE_HALF
341 #undef FIX
342 
343 }
344 
initialize_rgb24(struct jdec_private * priv,unsigned int * bytes_per_blocklines,unsigned int * bytes_per_mcu)345 static int initialize_rgb24(struct jdec_private *priv,
346 			    unsigned int *bytes_per_blocklines,
347 			    unsigned int *bytes_per_mcu)
348 {
349   if (!priv->bytes_per_row[0])
350     priv->bytes_per_row[0] = priv->width * 3;
351   if (priv->components[0] == NULL)
352     priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
353 
354   bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
355   bytes_per_mcu[0] = 3*8;
356 
357   return !priv->components[0];
358 }
359 
360 static const struct tinyjpeg_colorspace format_rgb24 =
361   {
362     {
363       YCrCB_to_RGB24_1x1,
364       YCrCB_to_RGB24_1x2,
365       YCrCB_to_RGB24_2x1,
366       YCrCB_to_RGB24_2x2,
367     },
368     tinyjpeg_decode_mcu_3comp_table,
369     initialize_rgb24
370   };
371 
372 const tinyjpeg_colorspace_t TINYJPEG_FMT_RGB24 = &format_rgb24;
373