2 * Small jpeg decoder library
4 * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
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.
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.
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.
44 #include "tinyjpeg-internal.h"
46 /*******************************************************************************
48 * Colorspace conversion routine
52 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
53 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
54 * The conversion equations to be implemented are therefore
55 * R = Y + 1.40200 * Cr
56 * G = Y - 0.34414 * Cb - 0.71414 * Cr
57 * B = Y + 1.77200 * Cb
59 ******************************************************************************/
62 * YCrCb -> YUV420P (1x1)
67 static void YCrCB_to_YUV420P_1x1(struct jdec_private
*priv
, int sx
, int sy
)
69 const unsigned char *s
, *y
;
75 for (i
= sy
; i
> 0; i
--)
78 p
+= priv
->bytes_per_row
[0];
84 for (i
= sy
; i
> 0; i
--)
86 for (j
= sx
; j
>= 0; j
-= 2) {
90 s
+= 8; /* Skip one line */
91 p
+= priv
->bytes_per_row
[1] - 4;
98 for (j
= sx
; j
>= 0; j
-= 2) {
102 s
+= 8; /* Skip one line */
103 p
+= priv
->bytes_per_row
[2] - 4;
108 * YCrCb -> YUV420P (2x1)
113 static void YCrCB_to_YUV420P_2x1(struct jdec_private
*priv
, int sx
, int sy
)
116 const unsigned char *s
, *y1
;
121 for (i
= sy
; i
> 0; i
--)
124 p
+= priv
->bytes_per_row
[0];
132 for (i
= sy
; i
> 0; i
-= 2)
135 s
+= 16; /* Skip one line */
136 p
+= priv
->bytes_per_row
[1];
141 for (i
= sy
; i
> 0; i
-= 2)
144 s
+= 16; /* Skip one line */
145 p
+= priv
->bytes_per_row
[2];
151 * YCrCb -> YUV420P (1x2)
158 static void YCrCB_to_YUV420P_1x2(struct jdec_private
*priv
, int sx
, int sy
)
160 const unsigned char *s
, *y
;
161 unsigned char *p
, *pr
;
166 for (i
= sy
; i
> 0; i
++)
169 p
+=priv
->bytes_per_row
[0];
175 for (i
= sy
; i
> 0; i
-= 2)
178 for (j
= sx
; j
> 0; j
-= 2) {
182 pr
+= priv
->bytes_per_row
[1];
190 for (j
= sx
; j
> 0; j
-= 2) {
194 pr
+= priv
->bytes_per_row
[2] - 4;
199 * YCrCb -> YUV420P (2x2)
206 static void YCrCB_to_YUV420P_2x2(struct jdec_private
*priv
, int sx
, int sy
)
209 const unsigned char *s
, *y1
;
214 for (i
= sy
; i
> 0; i
--)
217 p
+= priv
->bytes_per_row
[0];
225 for (i
= sy
; i
> 0; i
-= 2)
229 p
+= priv
->bytes_per_row
[1];
234 for (i
= sy
; i
> 0; i
-= 2)
238 p
+= priv
->bytes_per_row
[2];
242 static int initialize_yuv420p(struct jdec_private
*priv
,
243 unsigned int *bytes_per_blocklines
,
244 unsigned int *bytes_per_mcu
)
246 int half_height
= (priv
->height
+ 1) >> 2;
247 int half_width
= (priv
->width
+ 1) >> 2;
249 if (!priv
->bytes_per_row
[0])
250 priv
->bytes_per_row
[0] = priv
->width
;
251 if (!priv
->components
[0])
252 priv
->components
[0] = malloc(priv
->height
* priv
->bytes_per_row
[0]);
254 if (!priv
->bytes_per_row
[1])
255 priv
->bytes_per_row
[1] = half_width
;
256 if (!priv
->components
[1])
257 priv
->components
[1] = malloc(half_height
* priv
->bytes_per_row
[1]);
259 if (!priv
->bytes_per_row
[2])
260 priv
->bytes_per_row
[2] = half_width
;
261 if (!priv
->components
[2])
262 priv
->components
[2] = malloc(half_height
* priv
->bytes_per_row
[2]);
264 bytes_per_mcu
[0] = 8;
265 bytes_per_mcu
[1] = 4;
266 bytes_per_mcu
[2] = 4;
268 bytes_per_blocklines
[0] = priv
->width
<< 3;
269 bytes_per_blocklines
[1] = half_width
<< 2;
270 bytes_per_blocklines
[2] = half_width
<< 2;
272 /* Return nonzero on failure */
273 return !priv
->components
[0] || !priv
->components
[1] || !priv
->components
[2];
276 static const struct tinyjpeg_colorspace format_yuv420p
=
279 YCrCB_to_YUV420P_1x1
,
280 YCrCB_to_YUV420P_1x2
,
281 YCrCB_to_YUV420P_2x1
,
282 YCrCB_to_YUV420P_2x2
,
284 tinyjpeg_decode_mcu_3comp_table
,
288 const tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P
= &format_yuv420p
;