view VSs_tinyjpeg/tinyjpeg.c @ 0:a8af8b3fc99d

initial commit
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Thu, 05 Jul 2012 11:35:03 +0200
parents
children 7e13c9ecc89c
line source
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 */
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdint.h>
38 #include <errno.h>
40 #include "tinyjpeg.h"
41 #include "tinyjpeg-internal.h"
43 /* Global variable to return the last error found while deconding */
44 char error_string[256];
46 static const unsigned char zigzag[64] =
47 {
48 0, 1, 5, 6, 14, 15, 27, 28,
49 2, 4, 7, 13, 16, 26, 29, 42,
50 3, 8, 12, 17, 25, 30, 41, 43,
51 9, 11, 18, 24, 31, 40, 44, 53,
52 10, 19, 23, 32, 39, 45, 52, 54,
53 20, 22, 33, 38, 46, 51, 55, 60,
54 21, 34, 37, 47, 50, 56, 59, 61,
55 35, 36, 48, 49, 57, 58, 62, 63
56 };
58 /*
59 * 4 functions to manage the stream
60 *
61 * fill_nbits: put at least nbits in the reservoir of bits.
62 * But convert any 0xff,0x00 into 0xff
63 * get_nbits: read nbits from the stream, and put it in result,
64 * bits is removed from the stream and the reservoir is filled
65 * automaticaly. The result is signed according to the number of
66 * bits.
67 * look_nbits: read nbits from the stream without marking as read.
68 * skip_nbits: read nbits from the stream but do not return the result.
69 *
70 * stream: current pointer in the jpeg data (read bytes per bytes)
71 * nbits_in_reservoir: number of bits filled into the reservoir
72 * reservoir: register that contains bits information. Only nbits_in_reservoir
73 * is valid.
74 * nbits_in_reservoir
75 * <-- 17 bits -->
76 * Ex: 0000 0000 1010 0000 1111 0000 <== reservoir
77 * ^
78 * bit 1
79 * To get two bits from this example
80 * result = (reservoir >> 15) & 3
81 *
82 */
84 #define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
85 while (nbits_in_reservoir<nbits_wanted) \
86 { \
87 unsigned char c; \
88 if (stream >= priv->stream_end) \
89 return -1; \
90 c = *stream++; \
91 reservoir <<= 8; \
92 if (c == 0xff && *stream == 0x00) \
93 stream++; \
94 reservoir |= c; \
95 nbits_in_reservoir+=8; \
96 } \
97 } while(0);
100 /* Signed version !!!! */
101 #define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
102 fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
103 result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
104 nbits_in_reservoir -= (nbits_wanted); \
105 reservoir &= ((1U<<nbits_in_reservoir)-1); \
106 if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \
107 result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \
108 } while(0);
110 #define look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
111 fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
112 result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
113 } while(0);
115 /* To speed up the decoding, we assume that the reservoir has enough bits */
116 #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
117 nbits_in_reservoir -= (nbits_wanted); \
118 reservoir &= ((1U<<nbits_in_reservoir)-1); \
119 } while(0);
121 static void resync(struct jdec_private *priv);
123 /**
124 * Get the next (valid) huffman code in the stream.
125 *
126 * To speedup the procedure, we look HUFFMAN_HASH_NBITS bits and the code is
127 * lower than HUFFMAN_HASH_NBITS we have automaticaly the length of the code
128 * and the value by using two lookup table.
129 * Else if the value is not found, just search (linear) into an array for each
130 * bits is the code is present.
131 *
132 * If the code is not present for any reason, -1 is return.
133 */
134 static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table *huffman_table)
135 {
136 int value, hcode;
137 unsigned int extra_nbits, nbits;
138 uint16_t *slowtable;
140 look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode);
141 value = huffman_table->lookup[hcode];
142 if (__likely(value >= 0))
143 {
144 unsigned int code_size = huffman_table->code_size[value];
145 skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size);
146 return value;
147 }
149 /* Decode more bits each time ... */
150 for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++)
151 {
152 nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits;
154 look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode);
155 slowtable = huffman_table->slowtable[extra_nbits];
156 /* Search if the code is in this array */
157 while (slowtable[0]) {
158 if (slowtable[0] == hcode) {
159 skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits);
160 return slowtable[1];
161 }
162 slowtable+=2;
163 }
164 }
165 return 0;
166 }
168 /**
169 *
170 * Decode a single block that contains the DCT coefficients.
171 * The table coefficients is already dezigzaged at the end of the operation.
172 *
173 */
174 static int process_Huffman_data_unit(struct jdec_private *priv, int component)
175 {
176 unsigned char j;
177 unsigned int huff_code;
178 int retcode;
179 unsigned char size_val, count_0;
181 struct component *c = &priv->component_infos[component];
182 short int DCT[64];
184 /* Initialize the DCT coef table */
185 memset(DCT, 0, sizeof(DCT));
187 /* DC coefficient decoding */
188 retcode = get_next_huffman_code(priv, c->DC_table);
189 // End of stream
190 if(retcode == -1)
191 return -1;
192 else
193 huff_code = (unsigned int)retcode;
194 //trace("+ %x\n", huff_code);
195 if (huff_code) {
196 get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]);
197 DCT[0] += c->previous_DC;
198 c->previous_DC = DCT[0];
199 } else {
200 DCT[0] = c->previous_DC;
201 }
203 /* AC coefficient decoding */
204 j = 1;
205 while (j<64)
206 {
207 huff_code = get_next_huffman_code(priv, c->AC_table);
208 //trace("- %x\n", huff_code);
210 size_val = huff_code & 0xF;
211 count_0 = huff_code >> 4;
213 if (size_val == 0)
214 { /* RLE */
215 if (count_0 == 0)
216 break; /* EOB found, go out */
217 else if (count_0 == 0xF)
218 j += 16; /* skip 16 zeros */
219 }
220 else
221 {
222 j += count_0; /* skip count_0 zeroes */
223 if (__unlikely(j >= 64))
224 {
225 snprintf(error_string, sizeof(error_string), "Bad huffman data (buffer overflow)");
226 break;
227 }
228 get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]);
229 j++;
230 }
231 }
233 for (j = 0; j < 64; j++)
234 c->DCT[j] = DCT[zigzag[j]];
235 return 0;
236 }
238 /*******************************************************************************
239 *
240 * Colorspace conversion routine
241 *
242 * Note:
243 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
244 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
245 * The conversion equations to be implemented are therefore
246 * R = Y + 1.40200 * Cr
247 * G = Y - 0.34414 * Cb - 0.71414 * Cr
248 * B = Y + 1.77200 * Cb
249 *
250 ******************************************************************************/
252 static unsigned char clamp(int i)
253 {
254 if (i<0)
255 return 0;
256 else if (i>255)
257 return 255;
258 else
259 return i;
260 }
262 #define SCALEBITS 10
263 #define ONE_HALF (1UL << (SCALEBITS-1))
264 #define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
266 /**
267 * YCrCb -> RGB24 (2x2)
268 * .-------.
269 * | 1 | 2 |
270 * |---+---|
271 * | 3 | 4 |
272 * `-------'
273 */
274 static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
275 {
276 const unsigned char *Y, *Cb, *Cr;
277 unsigned char *p, *p2;
278 int i,j;
279 int offset_to_next_row;
281 p = priv->plane;
282 p2 = priv->plane + priv->width*3;
283 Y = priv->Y;
284 Cb = priv->Cb;
285 Cr = priv->Cr;
286 offset_to_next_row = (priv->width*3*2) - 16*3;
287 for (i=0; i<8; i++) {
289 for (j=0; j<8; j++) {
291 int y, cb, cr;
292 int add_r, add_g, add_b;
293 int r, g , b;
295 cb = *Cb++ - 128;
296 cr = *Cr++ - 128;
297 add_r = FIX(1.40200) * cr + ONE_HALF;
298 add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
299 add_b = FIX(1.77200) * cb + ONE_HALF;
301 y = (*Y++) << SCALEBITS;
302 r = (y + add_r) >> SCALEBITS;
303 *p++ = clamp(r);
304 g = (y + add_g) >> SCALEBITS;
305 *p++ = clamp(g);
306 b = (y + add_b) >> SCALEBITS;
307 *p++ = clamp(b);
309 y = (*Y++) << SCALEBITS;
310 r = (y + add_r) >> SCALEBITS;
311 *p++ = clamp(r);
312 g = (y + add_g) >> SCALEBITS;
313 *p++ = clamp(g);
314 b = (y + add_b) >> SCALEBITS;
315 *p++ = clamp(b);
317 y = (Y[16-2]) << SCALEBITS;
318 r = (y + add_r) >> SCALEBITS;
319 *p2++ = clamp(r);
320 g = (y + add_g) >> SCALEBITS;
321 *p2++ = clamp(g);
322 b = (y + add_b) >> SCALEBITS;
323 *p2++ = clamp(b);
325 y = (Y[16-1]) << SCALEBITS;
326 r = (y + add_r) >> SCALEBITS;
327 *p2++ = clamp(r);
328 g = (y + add_g) >> SCALEBITS;
329 *p2++ = clamp(g);
330 b = (y + add_b) >> SCALEBITS;
331 *p2++ = clamp(b);
332 }
333 Y += 16;
334 p += offset_to_next_row;
335 p2 += offset_to_next_row;
336 }
337 }
339 /*
340 * Decode a 2x2
341 * .-------.
342 * | 1 | 2 |
343 * |---+---|
344 * | 3 | 4 |
345 * `-------'
346 */
347 static int decode_MCU_2x2_3planes(struct jdec_private *priv)
348 {
349 // Y
350 if(process_Huffman_data_unit(priv, cY))
351 return -1;
352 IDCT(&priv->component_infos[cY], priv->Y, 16);
353 if(process_Huffman_data_unit(priv, cY))
354 return -1;
355 IDCT(&priv->component_infos[cY], priv->Y+8, 16);
356 if(process_Huffman_data_unit(priv, cY))
357 return -1;
358 IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
359 if(process_Huffman_data_unit(priv, cY))
360 return -1;
361 IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
363 // Cb
364 if(process_Huffman_data_unit(priv, cCb))
365 return -1;
366 IDCT(&priv->component_infos[cCb], priv->Cb, 8);
368 // Cr
369 if(process_Huffman_data_unit(priv, cCr))
370 return -1;
371 IDCT(&priv->component_infos[cCr], priv->Cr, 8);
373 return 0;
374 }
376 static void resync(struct jdec_private *priv)
377 {
378 int i;
380 /* Init DC coefficients */
381 for (i=0; i<COMPONENTS; i++)
382 priv->component_infos[i].previous_DC = 0;
384 priv->reservoir = 0;
385 priv->nbits_in_reservoir = 0;
386 }
388 static int find_next_rst_marker(struct jdec_private *priv)
389 {
390 int rst_marker_found = 0;
391 int marker;
392 const unsigned char *stream = priv->stream;
394 /* Parse marker */
395 while (!rst_marker_found)
396 {
397 while (*stream++ != 0xff)
398 {
399 if (stream >= priv->stream_end)
400 error("EOF while search for a RST marker.");
401 }
402 /* Skip any padding ff byte (this is normal) */
403 while (*stream == 0xff)
404 stream++;
406 marker = *stream++;
407 if ((RST+priv->last_rst_marker_seen) == marker)
408 rst_marker_found = 1;
409 else if (marker >= RST && marker <= RST7)
410 error("Wrong Reset marker found, abording");
411 else if (marker == EOI)
412 return 0;
413 }
414 trace("RST Marker %d found at offset %ld\n", priv->last_rst_marker_seen, stream - priv->stream_begin);
416 priv->stream = stream;
417 priv->last_rst_marker_seen++;
418 priv->last_rst_marker_seen &= 7;
420 return 0;
421 }
423 /*******************************************************************************
424 *
425 * Functions exported of the library.
426 *
427 * Note: Some applications can access directly to internal pointer of the
428 * structure. It's is not recommended, but if you have many images to
429 * uncompress with the same parameters, some functions can be called to speedup
430 * the decoding.
431 *
432 ******************************************************************************/
434 /**
435 * Allocate a new tinyjpeg decoder object.
436 *
437 * Before calling any other functions, an object need to be called.
438 */
439 struct jdec_private *tinyjpeg_init(void)
440 {
441 struct jdec_private *priv;
443 priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private));
444 if (priv == NULL)
445 return NULL;
446 return priv;
447 }
449 /**
450 * Free a tinyjpeg object.
451 *
452 * No others function can be called after this one.
453 */
454 void tinyjpeg_free(struct jdec_private *priv)
455 {
456 free(priv);
457 }
460 /**
461 * Create a new JPEG decode task
462 *
463 */
464 struct jdec_private *create_jdec_priv_task(struct jdec_private *priv, int tasknum)
465 {
466 struct jdec_private *jdec_task;
468 jdec_task = tinyjpeg_init();
469 resync(priv);
470 if (tasknum > 0){
471 find_next_rst_marker(priv);
472 }
473 memcpy(jdec_task, priv, sizeof(struct jdec_private));
475 jdec_task->mcus_posx = (tasknum * priv->restart_interval) % priv->mcus_in_width;
476 jdec_task->mcus_posy = (tasknum * priv->restart_interval) / priv->mcus_in_width;
478 return jdec_task;
479 }
481 /**
482 * Initialize the tinyjpeg object and prepare the decoding of the stream.
483 *
484 * Check if the jpeg can be decoded with this jpeg decoder.
485 * Fill some table used for preprocessing.
486 */
487 int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size)
488 {
489 int ret;
491 /* Identify the file */
492 if ((buf[0] != 0xFF) || (buf[1] != SOI))
493 error("Not a JPG file ?\n");
495 priv->stream_begin = buf+2;
496 priv->stream_length = size-2;
497 priv->stream_end = priv->stream_begin + priv->stream_length;
499 ret = parse_JFIF(priv, priv->stream_begin);
501 return ret;
502 }
504 /**
505 * Decode and convert the jpeg image
506 *
507 * Note: components will be automaticaly allocated if no memory is attached.
508 */
509 void tinyjpeg_decode_task(void *data, SlaveVP *animatingSlv )
510 {
511 //struct jdec_private *priv, uint8_t* context
512 tinyjpeg_decode_task_args* args = (tinyjpeg_decode_task_args*) data;
514 struct jdec_private *priv = args->priv;
515 uint8_t* context = args->context;
517 // Make OmpSs not complain while compiling
518 //(void) context;
520 unsigned int x, xstride_by_mcu, ystride_by_mcu;
521 unsigned int bytes_per_blocklines, bytes_per_mcu;
522 decode_MCU_fct decode_MCU;
523 convert_colorspace_fct convert_to_pixfmt;
525 bytes_per_blocklines = priv->width * RGB_DEPTH;
526 bytes_per_mcu = RGB_DEPTH*8;
528 // Only 2x2 CU sizes are supported in this simple decoder
529 decode_MCU = decode_MCU_2x2_3planes;
530 convert_to_pixfmt = YCrCB_to_RGB24_2x2;
531 xstride_by_mcu = MCU_X_STRIDE;
532 ystride_by_mcu = MCU_Y_STRIDE;
534 bytes_per_blocklines *= ystride_by_mcu;
535 bytes_per_mcu *= xstride_by_mcu/8;
537 /* Just the decode the image by macroblock */
539 priv->plane = priv->components[0] + (priv->mcus_posy * bytes_per_blocklines) + (priv->mcus_posx * bytes_per_mcu);
541 for (x=0; x < priv->restart_interval; x++) {
542 if(decode_MCU(priv)) {
543 fprintf(stderr, "%s\n", error_string);
544 }
545 convert_to_pixfmt(priv);
547 priv->plane += bytes_per_mcu;
548 priv->mcus_posx++;
549 if (priv->mcus_posx >= priv->mcus_in_width){
550 priv->mcus_posy++;
551 priv->mcus_posx = 0;
552 priv->plane += (bytes_per_blocklines - priv->width*3);
553 }
554 }
555 return;
556 }
558 const char *tinyjpeg_get_errorstring()
559 {
560 return error_string;
561 }
563 void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height)
564 {
565 *width = priv->width;
566 *height = priv->height;
567 }
569 int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components)
570 {
571 int i;
572 for (i=0; priv->components[i] && i<COMPONENTS; i++)
573 components[i] = priv->components[i];
574 return 0;