• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 -> RGBA32 (1x1)
68  *  .---.
69  *  | 1 |
70  *  `---'
71  */
YCrCB_to_RGBA32_1x1(struct jdec_private * priv,int sx,int sy)72 static void YCrCB_to_RGBA32_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*4;
88   for (i = sy; i > 0; i--) {
89     for (j = sx; j > 0; j--) {
90 
91        int y, cb, cr;
92        int add_r, add_g, add_b;
93        int r, g , b, a;
94 
95        y  = Y[0] << SCALEBITS;
96        cb = *Cb++ - 128;
97        cr = *Cr++ - 128;
98        add_r = FIX(1.40200) * cr + ONE_HALF;
99        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
100        add_b = FIX(1.77200) * cb + ONE_HALF;
101 
102        r = (y + add_r) >> SCALEBITS;
103        *p++ = clamp(r);
104        g = (y + add_g) >> SCALEBITS;
105        *p++ = clamp(g);
106        b = (y + add_b) >> SCALEBITS;
107        *p++ = clamp(b);
108        a = 255;
109        *p++ = a;
110 
111        Y++;
112     }
113 
114     p += offset_to_next_row;
115   }
116 
117 #undef SCALEBITS
118 #undef ONE_HALF
119 #undef FIX
120 
121 }
122 
123 /**
124  *  YCrCb -> RGBA32 (2x1)
125  *  .-------.
126  *  | 1 | 2 |
127  *  `-------'
128  */
YCrCB_to_RGBA32_2x1(struct jdec_private * priv,int sx,int sy)129 static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv, int sx, int sy)
130 {
131   const unsigned char *Y, *Cb, *Cr;
132   unsigned char *p;
133   int i,j;
134   int offset_to_next_row;
135 
136 #define SCALEBITS       10
137 #define ONE_HALF        (1UL << (SCALEBITS-1))
138 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
139 
140   p = priv->plane[0];
141   Y = priv->Y;
142   Cb = priv->Cb;
143   Cr = priv->Cr;
144   offset_to_next_row = priv->bytes_per_row[0] - 16*4;
145   for (i = sy; i > 0; i--) {
146     for (j = sx; j > 0; j -= 2) {
147 
148        int y, cb, cr;
149        int add_r, add_g, add_b;
150        int r, g , b, a;
151 
152        y  = Y[0] << SCALEBITS;
153        cb = *Cb++ - 128;
154        cr = *Cr++ - 128;
155        add_r = FIX(1.40200) * cr + ONE_HALF;
156        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
157        add_b = FIX(1.77200) * cb + ONE_HALF;
158 
159        r = (y + add_r) >> SCALEBITS;
160        *p++ = clamp(r);
161        g = (y + add_g) >> SCALEBITS;
162        *p++ = clamp(g);
163        b = (y + add_b) >> SCALEBITS;
164        *p++ = clamp(b);
165        a = 255;
166        *p++ = a;
167 
168        if (j > 1) {
169 	   y  = Y[1] << SCALEBITS;
170 	   r = (y + add_r) >> SCALEBITS;
171 	   *p++ = clamp(r);
172 	   g = (y + add_g) >> SCALEBITS;
173 	   *p++ = clamp(g);
174 	   b = (y + add_b) >> SCALEBITS;
175 	   *p++ = clamp(b);
176 	   a = 255;
177 	   *p++ = a;
178        }
179 
180        Y += 2;
181     }
182 
183     p += offset_to_next_row;
184   }
185 
186 #undef SCALEBITS
187 #undef ONE_HALF
188 #undef FIX
189 
190 }
191 
192 
193 /**
194  *  YCrCb -> RGBA32 (1x2)
195  *  .---.
196  *  | 1 |
197  *  |---|
198  *  | 2 |
199  *  `---'
200  */
YCrCB_to_RGBA32_1x2(struct jdec_private * priv,int sx,int sy)201 static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv, int sx, int sy)
202 {
203   const unsigned char *Y, *Cb, *Cr;
204   unsigned char *p, *p2;
205   int i,j;
206   int offset_to_next_row;
207 
208 #define SCALEBITS       10
209 #define ONE_HALF        (1UL << (SCALEBITS-1))
210 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
211 
212   p = priv->plane[0];
213   p2 = priv->plane[0] + priv->bytes_per_row[0];
214   Y = priv->Y;
215   Cb = priv->Cb;
216   Cr = priv->Cr;
217   offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4;
218   for (i = sy; i > 0; i -= 2) {
219     for (j = sx; j > 0; j--) {
220 
221        int y, cb, cr;
222        int add_r, add_g, add_b;
223        int r, g , b, a;
224 
225        cb = *Cb++ - 128;
226        cr = *Cr++ - 128;
227        add_r = FIX(1.40200) * cr + ONE_HALF;
228        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
229        add_b = FIX(1.77200) * cb + ONE_HALF;
230 
231        y  = Y[0] << SCALEBITS;
232        r = (y + add_r) >> SCALEBITS;
233        *p++ = clamp(r);
234        g = (y + add_g) >> SCALEBITS;
235        *p++ = clamp(g);
236        b = (y + add_b) >> SCALEBITS;
237        *p++ = clamp(b);
238        a = 255;
239        *p++ = a;
240 
241        if (i > 1) {
242 	   y  = Y[8] << SCALEBITS;
243 	   r = (y + add_r) >> SCALEBITS;
244 	   *p2++ = clamp(r);
245 	   g = (y + add_g) >> SCALEBITS;
246 	   *p2++ = clamp(g);
247 	   b = (y + add_b) >> SCALEBITS;
248 	   *p2++ = clamp(b);
249 	   a = 255;
250 	   *p2++ = a;
251        }
252 
253        Y++;
254     }
255     Y += 8;
256     p += offset_to_next_row;
257     p2 += offset_to_next_row;
258   }
259 
260 #undef SCALEBITS
261 #undef ONE_HALF
262 #undef FIX
263 
264 }
265 
266 /**
267  *  YCrCb -> RGBA32 (2x2)
268  *  .-------.
269  *  | 1 | 2 |
270  *  |---+---|
271  *  | 3 | 4 |
272  *  `-------'
273  */
YCrCB_to_RGBA32_2x2(struct jdec_private * priv,int sx,int sy)274 static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv, int sx, int sy)
275 {
276   const unsigned char *Y, *Cb, *Cr;
277   unsigned char *p, *p2;
278   int i,j;
279   int offset_to_next_row;
280 
281 #define SCALEBITS       10
282 #define ONE_HALF        (1UL << (SCALEBITS-1))
283 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
284 
285   p = priv->plane[0];
286   p2 = priv->plane[0] + priv->bytes_per_row[0];
287   Y = priv->Y;
288   Cb = priv->Cb;
289   Cr = priv->Cr;
290   offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4;
291   for (i = sy; i > 0; i -= 2) {
292     for (j = sx; i > 0; j -= 2) {
293 
294        int y, cb, cr;
295        int add_r, add_g, add_b;
296        int r, g , b, a;
297 
298        cb = *Cb++ - 128;
299        cr = *Cr++ - 128;
300        add_r = FIX(1.40200) * cr + ONE_HALF;
301        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
302        add_b = FIX(1.77200) * cb + ONE_HALF;
303 
304        y  = Y[0] << SCALEBITS;
305        r = (y + add_r) >> SCALEBITS;
306        *p++ = clamp(r);
307        g = (y + add_g) >> SCALEBITS;
308        *p++ = clamp(g);
309        b = (y + add_b) >> SCALEBITS;
310        *p++ = clamp(b);
311        a = 255;
312        *p++ = a;
313 
314        if (j > 1) {
315 	   y  = Y[1] << SCALEBITS;
316 	   r = (y + add_r) >> SCALEBITS;
317 	   *p++ = clamp(r);
318 	   g = (y + add_g) >> SCALEBITS;
319 	   *p++ = clamp(g);
320 	   b = (y + add_b) >> SCALEBITS;
321 	   *p++ = clamp(b);
322 	   a = 255;
323 	   *p++ = a;
324        }
325 
326        if (i > 1) {
327 	   y  = Y[16+0] << SCALEBITS;
328 	   r = (y + add_r) >> SCALEBITS;
329 	   *p2++ = clamp(r);
330 	   g = (y + add_g) >> SCALEBITS;
331 	   *p2++ = clamp(g);
332 	   b = (y + add_b) >> SCALEBITS;
333 	   *p2++ = clamp(b);
334 	   a = 255;
335 	   *p2++ = a;
336 
337 	   if (j > 1) {
338 	       y  = Y[16+1] << SCALEBITS;
339 	       r = (y + add_r) >> SCALEBITS;
340 	       *p2++ = clamp(r);
341 	       g = (y + add_g) >> SCALEBITS;
342 	       *p2++ = clamp(g);
343 	       b = (y + add_b) >> SCALEBITS;
344 	       *p2++ = clamp(b);
345 	       a = 255;
346 	       *p2++ = a;
347 	   }
348        }
349 
350        Y += 2;
351     }
352     Y  += 16;
353     p  += offset_to_next_row;
354     p2 += offset_to_next_row;
355   }
356 
357 #undef SCALEBITS
358 #undef ONE_HALF
359 #undef FIX
360 
361 }
362 
initialize_rgba32(struct jdec_private * priv,unsigned int * bytes_per_blocklines,unsigned int * bytes_per_mcu)363 static int initialize_rgba32(struct jdec_private *priv,
364 			     unsigned int *bytes_per_blocklines,
365 			     unsigned int *bytes_per_mcu)
366 {
367   if (!priv->bytes_per_row[0])
368     priv->bytes_per_row[0] = priv->width * 4;
369   if (!priv->components[0])
370     priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
371 
372   bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
373   bytes_per_mcu[0] = 4*8;
374 
375   return !priv->components[0];
376 }
377 
378 static const struct tinyjpeg_colorspace format_rgba32 =
379   {
380     {
381       YCrCB_to_RGBA32_1x1,
382       YCrCB_to_RGBA32_1x2,
383       YCrCB_to_RGBA32_2x1,
384       YCrCB_to_RGBA32_2x2,
385     },
386     tinyjpeg_decode_mcu_3comp_table,
387     initialize_rgba32
388   };
389 
390 const tinyjpeg_colorspace_t TINYJPEG_FMT_RGBA32 = &format_rgba32;
391