Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__jpeg_decoder__Proj
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/VSs_tinyjpeg/tinyjpeg.c Thu Jul 05 11:35:03 2012 +0200 1.3 @@ -0,0 +1,575 @@ 1.4 +/* 1.5 + * Small jpeg decoder library 1.6 + * 1.7 + * Copyright (c) 2006, Luc Saillard <luc@saillard.org> 1.8 + * All rights reserved. 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * - Redistributions of source code must retain the above copyright notice, 1.13 + * this list of conditions and the following disclaimer. 1.14 + * 1.15 + * - Redistributions in binary form must reproduce the above copyright notice, 1.16 + * this list of conditions and the following disclaimer in the documentation 1.17 + * and/or other materials provided with the distribution. 1.18 + * 1.19 + * - Neither the name of the author nor the names of its contributors may be 1.20 + * used to endorse or promote products derived from this software without 1.21 + * specific prior written permission. 1.22 + * 1.23 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.24 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.25 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.26 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.27 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.28 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.29 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.30 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.31 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.32 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.33 + * POSSIBILITY OF SUCH DAMAGE. 1.34 + * 1.35 + */ 1.36 + 1.37 +#include <stdio.h> 1.38 +#include <stdlib.h> 1.39 +#include <string.h> 1.40 +#include <stdint.h> 1.41 +#include <errno.h> 1.42 + 1.43 +#include "tinyjpeg.h" 1.44 +#include "tinyjpeg-internal.h" 1.45 + 1.46 +/* Global variable to return the last error found while deconding */ 1.47 +char error_string[256]; 1.48 + 1.49 +static const unsigned char zigzag[64] = 1.50 +{ 1.51 + 0, 1, 5, 6, 14, 15, 27, 28, 1.52 + 2, 4, 7, 13, 16, 26, 29, 42, 1.53 + 3, 8, 12, 17, 25, 30, 41, 43, 1.54 + 9, 11, 18, 24, 31, 40, 44, 53, 1.55 + 10, 19, 23, 32, 39, 45, 52, 54, 1.56 + 20, 22, 33, 38, 46, 51, 55, 60, 1.57 + 21, 34, 37, 47, 50, 56, 59, 61, 1.58 + 35, 36, 48, 49, 57, 58, 62, 63 1.59 +}; 1.60 + 1.61 +/* 1.62 + * 4 functions to manage the stream 1.63 + * 1.64 + * fill_nbits: put at least nbits in the reservoir of bits. 1.65 + * But convert any 0xff,0x00 into 0xff 1.66 + * get_nbits: read nbits from the stream, and put it in result, 1.67 + * bits is removed from the stream and the reservoir is filled 1.68 + * automaticaly. The result is signed according to the number of 1.69 + * bits. 1.70 + * look_nbits: read nbits from the stream without marking as read. 1.71 + * skip_nbits: read nbits from the stream but do not return the result. 1.72 + * 1.73 + * stream: current pointer in the jpeg data (read bytes per bytes) 1.74 + * nbits_in_reservoir: number of bits filled into the reservoir 1.75 + * reservoir: register that contains bits information. Only nbits_in_reservoir 1.76 + * is valid. 1.77 + * nbits_in_reservoir 1.78 + * <-- 17 bits --> 1.79 + * Ex: 0000 0000 1010 0000 1111 0000 <== reservoir 1.80 + * ^ 1.81 + * bit 1 1.82 + * To get two bits from this example 1.83 + * result = (reservoir >> 15) & 3 1.84 + * 1.85 + */ 1.86 + 1.87 +#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ 1.88 + while (nbits_in_reservoir<nbits_wanted) \ 1.89 + { \ 1.90 + unsigned char c; \ 1.91 + if (stream >= priv->stream_end) \ 1.92 + return -1; \ 1.93 + c = *stream++; \ 1.94 + reservoir <<= 8; \ 1.95 + if (c == 0xff && *stream == 0x00) \ 1.96 + stream++; \ 1.97 + reservoir |= c; \ 1.98 + nbits_in_reservoir+=8; \ 1.99 + } \ 1.100 +} while(0); 1.101 + 1.102 + 1.103 +/* Signed version !!!! */ 1.104 +#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ 1.105 + fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ 1.106 + result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ 1.107 + nbits_in_reservoir -= (nbits_wanted); \ 1.108 + reservoir &= ((1U<<nbits_in_reservoir)-1); \ 1.109 + if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \ 1.110 + result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \ 1.111 +} while(0); 1.112 + 1.113 +#define look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ 1.114 + fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ 1.115 + result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ 1.116 +} while(0); 1.117 + 1.118 +/* To speed up the decoding, we assume that the reservoir has enough bits */ 1.119 +#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ 1.120 + nbits_in_reservoir -= (nbits_wanted); \ 1.121 + reservoir &= ((1U<<nbits_in_reservoir)-1); \ 1.122 +} while(0); 1.123 + 1.124 +static void resync(struct jdec_private *priv); 1.125 + 1.126 +/** 1.127 + * Get the next (valid) huffman code in the stream. 1.128 + * 1.129 + * To speedup the procedure, we look HUFFMAN_HASH_NBITS bits and the code is 1.130 + * lower than HUFFMAN_HASH_NBITS we have automaticaly the length of the code 1.131 + * and the value by using two lookup table. 1.132 + * Else if the value is not found, just search (linear) into an array for each 1.133 + * bits is the code is present. 1.134 + * 1.135 + * If the code is not present for any reason, -1 is return. 1.136 + */ 1.137 +static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table *huffman_table) 1.138 +{ 1.139 + int value, hcode; 1.140 + unsigned int extra_nbits, nbits; 1.141 + uint16_t *slowtable; 1.142 + 1.143 + look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode); 1.144 + value = huffman_table->lookup[hcode]; 1.145 + if (__likely(value >= 0)) 1.146 + { 1.147 + unsigned int code_size = huffman_table->code_size[value]; 1.148 + skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size); 1.149 + return value; 1.150 + } 1.151 + 1.152 + /* Decode more bits each time ... */ 1.153 + for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++) 1.154 + { 1.155 + nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits; 1.156 + 1.157 + look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode); 1.158 + slowtable = huffman_table->slowtable[extra_nbits]; 1.159 + /* Search if the code is in this array */ 1.160 + while (slowtable[0]) { 1.161 + if (slowtable[0] == hcode) { 1.162 + skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits); 1.163 + return slowtable[1]; 1.164 + } 1.165 + slowtable+=2; 1.166 + } 1.167 + } 1.168 + return 0; 1.169 +} 1.170 + 1.171 +/** 1.172 + * 1.173 + * Decode a single block that contains the DCT coefficients. 1.174 + * The table coefficients is already dezigzaged at the end of the operation. 1.175 + * 1.176 + */ 1.177 +static int process_Huffman_data_unit(struct jdec_private *priv, int component) 1.178 +{ 1.179 + unsigned char j; 1.180 + unsigned int huff_code; 1.181 + int retcode; 1.182 + unsigned char size_val, count_0; 1.183 + 1.184 + struct component *c = &priv->component_infos[component]; 1.185 + short int DCT[64]; 1.186 + 1.187 + /* Initialize the DCT coef table */ 1.188 + memset(DCT, 0, sizeof(DCT)); 1.189 + 1.190 + /* DC coefficient decoding */ 1.191 + retcode = get_next_huffman_code(priv, c->DC_table); 1.192 + // End of stream 1.193 + if(retcode == -1) 1.194 + return -1; 1.195 + else 1.196 + huff_code = (unsigned int)retcode; 1.197 + //trace("+ %x\n", huff_code); 1.198 + if (huff_code) { 1.199 + get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); 1.200 + DCT[0] += c->previous_DC; 1.201 + c->previous_DC = DCT[0]; 1.202 + } else { 1.203 + DCT[0] = c->previous_DC; 1.204 + } 1.205 + 1.206 + /* AC coefficient decoding */ 1.207 + j = 1; 1.208 + while (j<64) 1.209 + { 1.210 + huff_code = get_next_huffman_code(priv, c->AC_table); 1.211 + //trace("- %x\n", huff_code); 1.212 + 1.213 + size_val = huff_code & 0xF; 1.214 + count_0 = huff_code >> 4; 1.215 + 1.216 + if (size_val == 0) 1.217 + { /* RLE */ 1.218 + if (count_0 == 0) 1.219 + break; /* EOB found, go out */ 1.220 + else if (count_0 == 0xF) 1.221 + j += 16; /* skip 16 zeros */ 1.222 + } 1.223 + else 1.224 + { 1.225 + j += count_0; /* skip count_0 zeroes */ 1.226 + if (__unlikely(j >= 64)) 1.227 + { 1.228 + snprintf(error_string, sizeof(error_string), "Bad huffman data (buffer overflow)"); 1.229 + break; 1.230 + } 1.231 + get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); 1.232 + j++; 1.233 + } 1.234 + } 1.235 + 1.236 + for (j = 0; j < 64; j++) 1.237 + c->DCT[j] = DCT[zigzag[j]]; 1.238 + return 0; 1.239 +} 1.240 + 1.241 +/******************************************************************************* 1.242 + * 1.243 + * Colorspace conversion routine 1.244 + * 1.245 + * Note: 1.246 + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are 1.247 + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. 1.248 + * The conversion equations to be implemented are therefore 1.249 + * R = Y + 1.40200 * Cr 1.250 + * G = Y - 0.34414 * Cb - 0.71414 * Cr 1.251 + * B = Y + 1.77200 * Cb 1.252 + * 1.253 + ******************************************************************************/ 1.254 + 1.255 +static unsigned char clamp(int i) 1.256 +{ 1.257 + if (i<0) 1.258 + return 0; 1.259 + else if (i>255) 1.260 + return 255; 1.261 + else 1.262 + return i; 1.263 +} 1.264 + 1.265 +#define SCALEBITS 10 1.266 +#define ONE_HALF (1UL << (SCALEBITS-1)) 1.267 +#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) 1.268 + 1.269 +/** 1.270 + * YCrCb -> RGB24 (2x2) 1.271 + * .-------. 1.272 + * | 1 | 2 | 1.273 + * |---+---| 1.274 + * | 3 | 4 | 1.275 + * `-------' 1.276 + */ 1.277 +static void YCrCB_to_RGB24_2x2(struct jdec_private *priv) 1.278 +{ 1.279 + const unsigned char *Y, *Cb, *Cr; 1.280 + unsigned char *p, *p2; 1.281 + int i,j; 1.282 + int offset_to_next_row; 1.283 + 1.284 + p = priv->plane; 1.285 + p2 = priv->plane + priv->width*3; 1.286 + Y = priv->Y; 1.287 + Cb = priv->Cb; 1.288 + Cr = priv->Cr; 1.289 + offset_to_next_row = (priv->width*3*2) - 16*3; 1.290 + for (i=0; i<8; i++) { 1.291 + 1.292 + for (j=0; j<8; j++) { 1.293 + 1.294 + int y, cb, cr; 1.295 + int add_r, add_g, add_b; 1.296 + int r, g , b; 1.297 + 1.298 + cb = *Cb++ - 128; 1.299 + cr = *Cr++ - 128; 1.300 + add_r = FIX(1.40200) * cr + ONE_HALF; 1.301 + add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; 1.302 + add_b = FIX(1.77200) * cb + ONE_HALF; 1.303 + 1.304 + y = (*Y++) << SCALEBITS; 1.305 + r = (y + add_r) >> SCALEBITS; 1.306 + *p++ = clamp(r); 1.307 + g = (y + add_g) >> SCALEBITS; 1.308 + *p++ = clamp(g); 1.309 + b = (y + add_b) >> SCALEBITS; 1.310 + *p++ = clamp(b); 1.311 + 1.312 + y = (*Y++) << SCALEBITS; 1.313 + r = (y + add_r) >> SCALEBITS; 1.314 + *p++ = clamp(r); 1.315 + g = (y + add_g) >> SCALEBITS; 1.316 + *p++ = clamp(g); 1.317 + b = (y + add_b) >> SCALEBITS; 1.318 + *p++ = clamp(b); 1.319 + 1.320 + y = (Y[16-2]) << SCALEBITS; 1.321 + r = (y + add_r) >> SCALEBITS; 1.322 + *p2++ = clamp(r); 1.323 + g = (y + add_g) >> SCALEBITS; 1.324 + *p2++ = clamp(g); 1.325 + b = (y + add_b) >> SCALEBITS; 1.326 + *p2++ = clamp(b); 1.327 + 1.328 + y = (Y[16-1]) << SCALEBITS; 1.329 + r = (y + add_r) >> SCALEBITS; 1.330 + *p2++ = clamp(r); 1.331 + g = (y + add_g) >> SCALEBITS; 1.332 + *p2++ = clamp(g); 1.333 + b = (y + add_b) >> SCALEBITS; 1.334 + *p2++ = clamp(b); 1.335 + } 1.336 + Y += 16; 1.337 + p += offset_to_next_row; 1.338 + p2 += offset_to_next_row; 1.339 + } 1.340 +} 1.341 + 1.342 +/* 1.343 + * Decode a 2x2 1.344 + * .-------. 1.345 + * | 1 | 2 | 1.346 + * |---+---| 1.347 + * | 3 | 4 | 1.348 + * `-------' 1.349 + */ 1.350 +static int decode_MCU_2x2_3planes(struct jdec_private *priv) 1.351 +{ 1.352 + // Y 1.353 + if(process_Huffman_data_unit(priv, cY)) 1.354 + return -1; 1.355 + IDCT(&priv->component_infos[cY], priv->Y, 16); 1.356 + if(process_Huffman_data_unit(priv, cY)) 1.357 + return -1; 1.358 + IDCT(&priv->component_infos[cY], priv->Y+8, 16); 1.359 + if(process_Huffman_data_unit(priv, cY)) 1.360 + return -1; 1.361 + IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); 1.362 + if(process_Huffman_data_unit(priv, cY)) 1.363 + return -1; 1.364 + IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); 1.365 + 1.366 + // Cb 1.367 + if(process_Huffman_data_unit(priv, cCb)) 1.368 + return -1; 1.369 + IDCT(&priv->component_infos[cCb], priv->Cb, 8); 1.370 + 1.371 + // Cr 1.372 + if(process_Huffman_data_unit(priv, cCr)) 1.373 + return -1; 1.374 + IDCT(&priv->component_infos[cCr], priv->Cr, 8); 1.375 + 1.376 + return 0; 1.377 +} 1.378 + 1.379 +static void resync(struct jdec_private *priv) 1.380 +{ 1.381 + int i; 1.382 + 1.383 + /* Init DC coefficients */ 1.384 + for (i=0; i<COMPONENTS; i++) 1.385 + priv->component_infos[i].previous_DC = 0; 1.386 + 1.387 + priv->reservoir = 0; 1.388 + priv->nbits_in_reservoir = 0; 1.389 +} 1.390 + 1.391 +static int find_next_rst_marker(struct jdec_private *priv) 1.392 +{ 1.393 + int rst_marker_found = 0; 1.394 + int marker; 1.395 + const unsigned char *stream = priv->stream; 1.396 + 1.397 + /* Parse marker */ 1.398 + while (!rst_marker_found) 1.399 + { 1.400 + while (*stream++ != 0xff) 1.401 + { 1.402 + if (stream >= priv->stream_end) 1.403 + error("EOF while search for a RST marker."); 1.404 + } 1.405 + /* Skip any padding ff byte (this is normal) */ 1.406 + while (*stream == 0xff) 1.407 + stream++; 1.408 + 1.409 + marker = *stream++; 1.410 + if ((RST+priv->last_rst_marker_seen) == marker) 1.411 + rst_marker_found = 1; 1.412 + else if (marker >= RST && marker <= RST7) 1.413 + error("Wrong Reset marker found, abording"); 1.414 + else if (marker == EOI) 1.415 + return 0; 1.416 + } 1.417 + trace("RST Marker %d found at offset %ld\n", priv->last_rst_marker_seen, stream - priv->stream_begin); 1.418 + 1.419 + priv->stream = stream; 1.420 + priv->last_rst_marker_seen++; 1.421 + priv->last_rst_marker_seen &= 7; 1.422 + 1.423 + return 0; 1.424 +} 1.425 + 1.426 +/******************************************************************************* 1.427 + * 1.428 + * Functions exported of the library. 1.429 + * 1.430 + * Note: Some applications can access directly to internal pointer of the 1.431 + * structure. It's is not recommended, but if you have many images to 1.432 + * uncompress with the same parameters, some functions can be called to speedup 1.433 + * the decoding. 1.434 + * 1.435 + ******************************************************************************/ 1.436 + 1.437 +/** 1.438 + * Allocate a new tinyjpeg decoder object. 1.439 + * 1.440 + * Before calling any other functions, an object need to be called. 1.441 + */ 1.442 +struct jdec_private *tinyjpeg_init(void) 1.443 +{ 1.444 + struct jdec_private *priv; 1.445 + 1.446 + priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private)); 1.447 + if (priv == NULL) 1.448 + return NULL; 1.449 + return priv; 1.450 +} 1.451 + 1.452 +/** 1.453 + * Free a tinyjpeg object. 1.454 + * 1.455 + * No others function can be called after this one. 1.456 + */ 1.457 +void tinyjpeg_free(struct jdec_private *priv) 1.458 +{ 1.459 + free(priv); 1.460 +} 1.461 + 1.462 + 1.463 +/** 1.464 + * Create a new JPEG decode task 1.465 + * 1.466 + */ 1.467 +struct jdec_private *create_jdec_priv_task(struct jdec_private *priv, int tasknum) 1.468 +{ 1.469 + struct jdec_private *jdec_task; 1.470 + 1.471 + jdec_task = tinyjpeg_init(); 1.472 + resync(priv); 1.473 + if (tasknum > 0){ 1.474 + find_next_rst_marker(priv); 1.475 + } 1.476 + memcpy(jdec_task, priv, sizeof(struct jdec_private)); 1.477 + 1.478 + jdec_task->mcus_posx = (tasknum * priv->restart_interval) % priv->mcus_in_width; 1.479 + jdec_task->mcus_posy = (tasknum * priv->restart_interval) / priv->mcus_in_width; 1.480 + 1.481 + return jdec_task; 1.482 +} 1.483 + 1.484 +/** 1.485 + * Initialize the tinyjpeg object and prepare the decoding of the stream. 1.486 + * 1.487 + * Check if the jpeg can be decoded with this jpeg decoder. 1.488 + * Fill some table used for preprocessing. 1.489 + */ 1.490 +int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size) 1.491 +{ 1.492 + int ret; 1.493 + 1.494 + /* Identify the file */ 1.495 + if ((buf[0] != 0xFF) || (buf[1] != SOI)) 1.496 + error("Not a JPG file ?\n"); 1.497 + 1.498 + priv->stream_begin = buf+2; 1.499 + priv->stream_length = size-2; 1.500 + priv->stream_end = priv->stream_begin + priv->stream_length; 1.501 + 1.502 + ret = parse_JFIF(priv, priv->stream_begin); 1.503 + 1.504 + return ret; 1.505 +} 1.506 + 1.507 +/** 1.508 + * Decode and convert the jpeg image 1.509 + * 1.510 + * Note: components will be automaticaly allocated if no memory is attached. 1.511 + */ 1.512 +void tinyjpeg_decode_task(void *data, SlaveVP *animatingSlv ) 1.513 +{ 1.514 + //struct jdec_private *priv, uint8_t* context 1.515 + tinyjpeg_decode_task_args* args = (tinyjpeg_decode_task_args*) data; 1.516 + 1.517 + struct jdec_private *priv = args->priv; 1.518 + uint8_t* context = args->context; 1.519 + 1.520 + // Make OmpSs not complain while compiling 1.521 + //(void) context; 1.522 + 1.523 + unsigned int x, xstride_by_mcu, ystride_by_mcu; 1.524 + unsigned int bytes_per_blocklines, bytes_per_mcu; 1.525 + decode_MCU_fct decode_MCU; 1.526 + convert_colorspace_fct convert_to_pixfmt; 1.527 + 1.528 + bytes_per_blocklines = priv->width * RGB_DEPTH; 1.529 + bytes_per_mcu = RGB_DEPTH*8; 1.530 + 1.531 + // Only 2x2 CU sizes are supported in this simple decoder 1.532 + decode_MCU = decode_MCU_2x2_3planes; 1.533 + convert_to_pixfmt = YCrCB_to_RGB24_2x2; 1.534 + xstride_by_mcu = MCU_X_STRIDE; 1.535 + ystride_by_mcu = MCU_Y_STRIDE; 1.536 + 1.537 + bytes_per_blocklines *= ystride_by_mcu; 1.538 + bytes_per_mcu *= xstride_by_mcu/8; 1.539 + 1.540 + /* Just the decode the image by macroblock */ 1.541 + 1.542 + priv->plane = priv->components[0] + (priv->mcus_posy * bytes_per_blocklines) + (priv->mcus_posx * bytes_per_mcu); 1.543 + 1.544 + for (x=0; x < priv->restart_interval; x++) { 1.545 + if(decode_MCU(priv)) { 1.546 + fprintf(stderr, "%s\n", error_string); 1.547 + } 1.548 + convert_to_pixfmt(priv); 1.549 + 1.550 + priv->plane += bytes_per_mcu; 1.551 + priv->mcus_posx++; 1.552 + if (priv->mcus_posx >= priv->mcus_in_width){ 1.553 + priv->mcus_posy++; 1.554 + priv->mcus_posx = 0; 1.555 + priv->plane += (bytes_per_blocklines - priv->width*3); 1.556 + } 1.557 + } 1.558 + return; 1.559 +} 1.560 + 1.561 +const char *tinyjpeg_get_errorstring() 1.562 +{ 1.563 + return error_string; 1.564 +} 1.565 + 1.566 +void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height) 1.567 +{ 1.568 + *width = priv->width; 1.569 + *height = priv->height; 1.570 +} 1.571 + 1.572 +int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components) 1.573 +{ 1.574 + int i; 1.575 + for (i=0; priv->components[i] && i<COMPONENTS; i++) 1.576 + components[i] = priv->components[i]; 1.577 + return 0; 1.578 +} 1.579 \ No newline at end of file
