1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/liboil/tsrc/examples/jpeg/src/jpeg.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1130 @@
1.4 +/*
1.5 +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +#include <sys/stat.h>
1.22 +#include <fcntl.h>
1.23 +#include <unistd.h>
1.24 +#include <stdlib.h>
1.25 +#include <stdio.h>
1.26 +#include <string.h>
1.27 +#include <ctype.h>
1.28 +#include <limits.h>
1.29 +#include <liboil/liboil-stdint.h>
1.30 +#include <liboil/liboil.h>
1.31 +#include <liboil/liboildebug.h>
1.32 +#include <stdarg.h>
1.33 +
1.34 +#include "jpeg_internal.h"
1.35 +#include <liboil/globals.h>
1.36 +
1.37 +#define MAX(a,b) ((a)>(b) ? (a) : (b))
1.38 +
1.39 +
1.40 +extern uint8_t jpeg_standard_tables[];
1.41 +extern int jpeg_standard_tables_size;
1.42 +
1.43 +void jpeg_decoder_error(JpegDecoder *dec, char *fmt, ...);
1.44 +
1.45 +void jpeg_decoder_define_huffman_tables (JpegDecoder * dec);
1.46 +void jpeg_decoder_define_arithmetic_conditioning (JpegDecoder *dec);
1.47 +void jpeg_decoder_define_quantization_tables (JpegDecoder *dec);
1.48 +void jpeg_decoder_define_restart_interval (JpegDecoder *dec);
1.49 +void jpeg_decoder_start_of_frame (JpegDecoder * dec, int marker);
1.50 +void jpeg_decoder_start_of_scan (JpegDecoder * dec);
1.51 +
1.52 +
1.53 +/* misc helper function declarations */
1.54 +
1.55 +static void dumpbits (JpegBits * bits);
1.56 +static char *sprintbits (char *str, unsigned int bits, int n);
1.57 +
1.58 +static void huffman_table_load_std_jpeg (JpegDecoder * dec);
1.59 +
1.60 +static void jpeg_decoder_verify_header (JpegDecoder *dec);
1.61 +static void jpeg_decoder_init_decoder (JpegDecoder *dec);
1.62 +
1.63 +
1.64 +
1.65 +static void
1.66 +jpeg_decoder_verify_header (JpegDecoder *dec)
1.67 +{
1.68 + int max_quant_table = 0;
1.69 + int i;
1.70 +
1.71 + if (dec->sof_type != JPEG_MARKER_SOF_0) {
1.72 + OIL_ERROR("only handle baseline DCT");
1.73 + dec->error = TRUE;
1.74 + }
1.75 +
1.76 + if (dec->width < 1) {
1.77 + OIL_ERROR("height can't be 0");
1.78 + dec->error = TRUE;
1.79 + }
1.80 +
1.81 + switch (dec->sof_type) {
1.82 + case JPEG_MARKER_SOF_0:
1.83 + /* baseline DCT */
1.84 + max_quant_table = 3;
1.85 + if (dec->depth != 8) {
1.86 + OIL_ERROR("depth must be 8 (%d)", dec->depth);
1.87 + dec->error = TRUE;
1.88 + }
1.89 + break;
1.90 + case JPEG_MARKER_SOF_1:
1.91 + /* extended DCT */
1.92 + max_quant_table = 3;
1.93 + if (dec->depth != 8 && dec->depth != 12) {
1.94 + OIL_ERROR("depth must be 8 or 12 (%d)", dec->depth);
1.95 + dec->error = TRUE;
1.96 + }
1.97 + break;
1.98 + case JPEG_MARKER_SOF_2:
1.99 + /* progressive DCT */
1.100 + max_quant_table = 3;
1.101 + if (dec->depth != 8 && dec->depth != 12) {
1.102 + OIL_ERROR("depth must be 8 or 12 (%d)", dec->depth);
1.103 + dec->error = TRUE;
1.104 + }
1.105 + break;
1.106 + case JPEG_MARKER_SOF_3:
1.107 + /* lossless DCT */
1.108 + max_quant_table = 0;
1.109 + if (dec->depth < 2 || dec->depth > 16) {
1.110 + OIL_ERROR("depth must be between 2 and 16 (%d)", dec->depth);
1.111 + dec->error = TRUE;
1.112 + }
1.113 + break;
1.114 + default:
1.115 + break;
1.116 + }
1.117 +
1.118 + if (dec->n_components < 0 || dec->n_components > 255) {
1.119 + OIL_ERROR("n_components must be in the range 0-255 (%d)",
1.120 + dec->n_components);
1.121 + dec->error = TRUE;
1.122 + }
1.123 + if (dec->sof_type == JPEG_MARKER_SOF_2 && dec->n_components > 4) {
1.124 + OIL_ERROR("n_components must be <= 4 for progressive DCT (%d)",
1.125 + dec->n_components);
1.126 + dec->error = TRUE;
1.127 + }
1.128 +
1.129 + for (i = 0; i < dec->n_components; i++) {
1.130 + if (dec->components[i].id < 0 || dec->components[i].id > 255) {
1.131 + OIL_ERROR("component ID out of range");
1.132 + dec->error = TRUE;
1.133 + break;
1.134 + }
1.135 + if (dec->components[i].h_sample < 1 || dec->components[i].h_sample > 4 ||
1.136 + dec->components[i].v_sample < 1 || dec->components[i].v_sample > 4) {
1.137 + OIL_ERROR("sample factor(s) for component %d out of range %d %d",
1.138 + i, dec->components[i].h_sample, dec->components[i].v_sample);
1.139 + dec->error = TRUE;
1.140 + break;
1.141 + }
1.142 + if (dec->components[i].quant_table < 0 ||
1.143 + dec->components[i].quant_table > max_quant_table) {
1.144 + OIL_ERROR("quant table for component %d out of range (%d)",
1.145 + i, dec->components[i].quant_table);
1.146 + dec->error = TRUE;
1.147 + break;
1.148 + }
1.149 + }
1.150 +}
1.151 +
1.152 +static void
1.153 +jpeg_decoder_init_decoder (JpegDecoder *dec)
1.154 +{
1.155 + int max_h_sample = 0;
1.156 + int max_v_sample = 0;
1.157 + int i;
1.158 +
1.159 + /* decoder limitations */
1.160 + if (dec->n_components != 3) {
1.161 + jpeg_decoder_error(dec, "wrong number of components %d", dec->n_components);
1.162 + return;
1.163 + }
1.164 + if (dec->sof_type != JPEG_MARKER_SOF_0) {
1.165 + jpeg_decoder_error(dec, "only handle baseline DCT");
1.166 + return;
1.167 + }
1.168 +
1.169 +
1.170 +
1.171 +
1.172 + for (i=0; i < dec->n_components; i++) {
1.173 + max_h_sample = MAX (max_h_sample, dec->components[i].h_sample);
1.174 + max_v_sample = MAX (max_v_sample, dec->components[i].v_sample);
1.175 + }
1.176 +
1.177 + dec->width_blocks =
1.178 + (dec->width + 8 * max_h_sample - 1) / (8 * max_h_sample);
1.179 + dec->height_blocks =
1.180 + (dec->height + 8 * max_v_sample - 1) / (8 * max_v_sample);
1.181 + for (i = 0; i < dec->n_components; i++) {
1.182 + int rowstride;
1.183 + int image_size;
1.184 +
1.185 + dec->components[i].h_subsample = max_h_sample /
1.186 + dec->components[i].h_sample;
1.187 + dec->components[i].v_subsample = max_v_sample /
1.188 + dec->components[i].v_sample;
1.189 +
1.190 + rowstride = dec->width_blocks * 8 * max_h_sample /
1.191 + dec->components[i].h_subsample;
1.192 + image_size = rowstride *
1.193 + (dec->height_blocks * 8 * max_v_sample /
1.194 + dec->components[i].v_subsample);
1.195 + dec->components[i].rowstride = rowstride;
1.196 + dec->components[i].image = malloc (image_size);
1.197 + }
1.198 +}
1.199 +
1.200 +
1.201 +void
1.202 +generate_code_table (int *huffsize)
1.203 +{
1.204 + int code;
1.205 + int i;
1.206 + int j;
1.207 + int k;
1.208 + char str[33];
1.209 +
1.210 + //int l;
1.211 +
1.212 + code = 0;
1.213 + k = 0;
1.214 + for (i = 0; i < 16; i++) {
1.215 + for (j = 0; j < huffsize[i]; j++) {
1.216 + OIL_DEBUG ("huffcode[%d] = %s", k,
1.217 + sprintbits (str, code >> (15 - i), i + 1));
1.218 + code++;
1.219 + k++;
1.220 + }
1.221 + code <<= 1;
1.222 + }
1.223 +
1.224 +}
1.225 +
1.226 +int
1.227 +huffman_table_init_jpeg (HuffmanTable *table, JpegBits * bits)
1.228 +{
1.229 + int n_symbols;
1.230 + int huffsize[16];
1.231 + int i, j, k;
1.232 + unsigned int symbol;
1.233 + int n = 0;
1.234 +
1.235 + huffman_table_init (table);
1.236 +
1.237 + /* huffsize[i] is the number of symbols that have length
1.238 + * (i+1) bits. Maximum bit length is 16 bits, so there are
1.239 + * 16 entries. */
1.240 + n_symbols = 0;
1.241 + for (i = 0; i < 16; i++) {
1.242 + huffsize[i] = jpeg_bits_get_u8 (bits);
1.243 + n++;
1.244 + n_symbols += huffsize[i];
1.245 + }
1.246 +
1.247 + /* Build up the symbol table. The first symbol is all 0's, with
1.248 + * the number of bits determined by the first non-zero entry in
1.249 + * huffsize[]. Subsequent symbols with the same bit length are
1.250 + * incremented by 1. Increasing the bit length shifts the
1.251 + * symbol 1 bit to the left. */
1.252 + symbol = 0;
1.253 + k = 0;
1.254 + for (i = 0; i < 16; i++) {
1.255 + for (j = 0; j < huffsize[i]; j++) {
1.256 + huffman_table_add (table, symbol, i + 1, jpeg_bits_get_u8 (bits));
1.257 + n++;
1.258 + symbol++;
1.259 + k++;
1.260 + }
1.261 + /* This checks that our symbol is actually less than the
1.262 + * number of bits we think it is. This is only triggered
1.263 + * for bad huffsize[] arrays. */
1.264 + if (symbol >= (1 << (i + 1))) {
1.265 + /* FIXME jpeg_decoder_error() */
1.266 + OIL_DEBUG ("bad huffsize[] array");
1.267 + return -1;
1.268 + }
1.269 +
1.270 + symbol <<= 1;
1.271 + }
1.272 +
1.273 + huffman_table_dump (table);
1.274 +
1.275 + return n;
1.276 +}
1.277 +
1.278 +static void
1.279 +dumpbits (JpegBits * bits)
1.280 +{
1.281 + int i;
1.282 + int j;
1.283 + unsigned char *p;
1.284 + char s[40];
1.285 +
1.286 + p = bits->ptr;
1.287 + for (i = 0; i < 8; i++) {
1.288 + sprintf (s, "%02x %02x %02x %02x %02x %02x %02x %02x ........",
1.289 + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1.290 + for (j = 0; j < 8; j++) {
1.291 + s[j + 24] = (isprint (p[j])) ? p[j] : '.';
1.292 + }
1.293 + OIL_DEBUG ("%s", s);
1.294 + p += 8;
1.295 + }
1.296 +
1.297 +}
1.298 +
1.299 +int
1.300 +jpeg_decoder_find_component_by_id (JpegDecoder * dec, int id)
1.301 +{
1.302 + int i;
1.303 +
1.304 + for (i = 0; i < dec->n_components; i++) {
1.305 + if (dec->components[i].id == id)
1.306 + return i;
1.307 + }
1.308 + OIL_DEBUG ("undefined component id %d", id);
1.309 + return 0;
1.310 +}
1.311 +
1.312 +int
1.313 +jpeg_decoder_application0 (JpegDecoder * dec, JpegBits * bits)
1.314 +{
1.315 + int length;
1.316 +
1.317 + OIL_DEBUG ("app0");
1.318 +
1.319 + length = get_be_u16 (bits);
1.320 + OIL_DEBUG ("length=%d", length);
1.321 +
1.322 + if (memcmp (bits->ptr, "JFIF", 4) == 0 && bits->ptr[4] == 0) {
1.323 + int version;
1.324 + int units;
1.325 + int x_density;
1.326 + int y_density;
1.327 + int x_thumbnail;
1.328 + int y_thumbnail;
1.329 +
1.330 + OIL_DEBUG ("JFIF");
1.331 + bits->ptr += 5;
1.332 +
1.333 + version = get_be_u16 (bits);
1.334 + units = get_u8 (bits);
1.335 + x_density = get_be_u16 (bits);
1.336 + y_density = get_be_u16 (bits);
1.337 + x_thumbnail = get_u8 (bits);
1.338 + y_thumbnail = get_u8 (bits);
1.339 +
1.340 + OIL_DEBUG ("version = %04x", version);
1.341 + OIL_DEBUG ("units = %d", units);
1.342 + OIL_DEBUG ("x_density = %d", x_density);
1.343 + OIL_DEBUG ("y_density = %d", y_density);
1.344 + OIL_DEBUG ("x_thumbnail = %d", x_thumbnail);
1.345 + OIL_DEBUG ("y_thumbnail = %d", y_thumbnail);
1.346 +
1.347 + }
1.348 +
1.349 + if (memcmp (bits->ptr, "JFXX", 4) == 0 && bits->ptr[4] == 0) {
1.350 + OIL_DEBUG ("JFIF extension (not handled)");
1.351 + bits->ptr += length - 2;
1.352 + }
1.353 +
1.354 + return length;
1.355 +}
1.356 +
1.357 +int
1.358 +jpeg_decoder_application_misc (JpegDecoder * dec, JpegBits * bits)
1.359 +{
1.360 + int length;
1.361 +
1.362 + OIL_DEBUG ("appX");
1.363 +
1.364 + length = get_be_u16 (bits);
1.365 + OIL_DEBUG ("length=%d", length);
1.366 +
1.367 + OIL_DEBUG ("JPEG application tag X ignored");
1.368 + dumpbits (bits);
1.369 +
1.370 + bits->ptr += length - 2;
1.371 +
1.372 + return length;
1.373 +}
1.374 +
1.375 +int
1.376 +jpeg_decoder_comment (JpegDecoder * dec, JpegBits * bits)
1.377 +{
1.378 + int length;
1.379 +
1.380 + OIL_DEBUG ("comment");
1.381 +
1.382 + length = get_be_u16 (bits);
1.383 + OIL_DEBUG ("length=%d", length);
1.384 +
1.385 + dumpbits (bits);
1.386 +
1.387 + bits->ptr += length - 2;
1.388 +
1.389 + return length;
1.390 +}
1.391 +
1.392 +int
1.393 +jpeg_decoder_restart_interval (JpegDecoder * dec, JpegBits * bits)
1.394 +{
1.395 + int length;
1.396 +
1.397 + OIL_DEBUG ("comment");
1.398 +
1.399 + length = get_be_u16 (bits);
1.400 + OIL_DEBUG ("length=%d", length);
1.401 +
1.402 + dec->restart_interval = get_be_u16 (bits);
1.403 + OIL_DEBUG ("restart_interval=%d", dec->restart_interval);
1.404 +
1.405 + return length;
1.406 +}
1.407 +
1.408 +int
1.409 +jpeg_decoder_restart (JpegDecoder * dec, JpegBits * bits)
1.410 +{
1.411 + OIL_DEBUG ("restart");
1.412 +
1.413 + return 0;
1.414 +}
1.415 +
1.416 +void
1.417 +jpeg_decoder_decode_entropy_segment (JpegDecoder * dec)
1.418 +{
1.419 + JpegBits * bits = &dec->bits;
1.420 + JpegBits b2, *bits2 = &b2;
1.421 + short block[64];
1.422 + short block2[64];
1.423 + unsigned char *newptr;
1.424 + int len;
1.425 + int j;
1.426 + int i;
1.427 + int go;
1.428 + int x, y;
1.429 + int n;
1.430 + int ret;
1.431 +
1.432 + len = 0;
1.433 + j = 0;
1.434 + while (1) {
1.435 + if (bits->ptr[len] == 0xff && bits->ptr[len + 1] != 0x00) {
1.436 + break;
1.437 + }
1.438 + len++;
1.439 + }
1.440 + OIL_DEBUG ("entropy length = %d", len);
1.441 +
1.442 + /* we allocate extra space, since the getbits() code can
1.443 + * potentially read past the end of the buffer */
1.444 + newptr = malloc (len + 2);
1.445 + for (i = 0; i < len; i++) {
1.446 + newptr[j] = bits->ptr[i];
1.447 + j++;
1.448 + if (bits->ptr[i] == 0xff)
1.449 + i++;
1.450 + }
1.451 + bits->ptr += len;
1.452 +
1.453 + bits2->ptr = newptr;
1.454 + bits2->idx = 0;
1.455 + bits2->end = newptr + j;
1.456 + newptr[j] = 0;
1.457 + newptr[j + 1] = 0;
1.458 +
1.459 + dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128 * 8;
1.460 + go = 1;
1.461 + x = dec->x;
1.462 + y = dec->y;
1.463 + n = dec->restart_interval;
1.464 + if (n == 0) n = INT_MAX;
1.465 + while (n-- > 0) {
1.466 + for (i = 0; i < dec->scan_list_length; i++) {
1.467 + int dc_table_index;
1.468 + int ac_table_index;
1.469 + int quant_index;
1.470 + unsigned char *ptr;
1.471 + int component_index;
1.472 +
1.473 + OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d",
1.474 + x, y,
1.475 + dec->scan_list[i].component_index,
1.476 + dec->scan_list[i].dc_table, dec->scan_list[i].ac_table);
1.477 +
1.478 + component_index = dec->scan_list[i].component_index;
1.479 + dc_table_index = dec->scan_list[i].dc_table;
1.480 + ac_table_index = dec->scan_list[i].ac_table;
1.481 + quant_index = dec->scan_list[i].quant_table;
1.482 +
1.483 + ret = huffman_table_decode_macroblock (block,
1.484 + &dec->dc_huff_table[dc_table_index],
1.485 + &dec->ac_huff_table[ac_table_index], bits2);
1.486 + if (ret < 0) {
1.487 + OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d",
1.488 + x, y,
1.489 + dec->scan_list[i].component_index,
1.490 + dec->scan_list[i].dc_table, dec->scan_list[i].ac_table);
1.491 + n = 0;
1.492 + break;
1.493 + }
1.494 +
1.495 + OIL_DEBUG ("using quant table %d", quant_index);
1.496 + oil_mult8x8_s16 (block2, block, dec->quant_tables[quant_index].quantizer,
1.497 + sizeof (short) * 8, sizeof(short) * 8, sizeof (short) * 8);
1.498 + dec->dc[component_index] += block2[0];
1.499 + block2[0] = dec->dc[component_index];
1.500 + oil_unzigzag8x8_s16 (block, sizeof (short) * 8, block2,
1.501 + sizeof (short) * 8);
1.502 + oil_idct8x8_s16 (block2, sizeof (short) * 8, block, sizeof (short) * 8);
1.503 + oil_trans8x8_s16 (block, sizeof (short) * 8, block2, sizeof (short) * 8);
1.504 +
1.505 + ptr = dec->components[component_index].image +
1.506 + x * dec->components[component_index].h_sample +
1.507 + dec->scan_list[i].offset +
1.508 + dec->components[component_index].rowstride * y *
1.509 + dec->components[component_index].v_sample;
1.510 +
1.511 + oil_clipconv8x8_u8_s16 (ptr,
1.512 + dec->components[component_index].rowstride,
1.513 + block, sizeof (short) * 8);
1.514 + }
1.515 + x += 8;
1.516 + if (x * dec->scan_h_subsample >= dec->width) {
1.517 + x = 0;
1.518 + y += 8;
1.519 + }
1.520 + if (y * dec->scan_v_subsample >= dec->height) {
1.521 + go = 0;
1.522 + }
1.523 + }
1.524 + dec->x = x;
1.525 + dec->y = y;
1.526 + free (newptr);
1.527 +}
1.528 +
1.529 +
1.530 +
1.531 +JpegDecoder *
1.532 +jpeg_decoder_new (void)
1.533 +{
1.534 + JpegDecoder *dec;
1.535 +
1.536 + oil_init ();
1.537 +
1.538 + dec = malloc (sizeof(JpegDecoder));
1.539 + memset (dec, 0, sizeof(JpegDecoder));
1.540 +
1.541 + huffman_table_load_std_jpeg (dec);
1.542 +
1.543 + return dec;
1.544 +}
1.545 +
1.546 +void
1.547 +jpeg_decoder_free (JpegDecoder * dec)
1.548 +{
1.549 + int i;
1.550 +
1.551 + for (i = 0; i < JPEG_MAX_COMPONENTS; i++) {
1.552 + if (dec->components[i].image)
1.553 + free (dec->components[i].image);
1.554 + }
1.555 +
1.556 + if (dec->data)
1.557 + free (dec->data);
1.558 +
1.559 + free (dec);
1.560 +}
1.561 +
1.562 +void
1.563 +jpeg_decoder_error(JpegDecoder *dec, char *fmt, ...)
1.564 +{
1.565 + va_list varargs;
1.566 +
1.567 + if (dec->error) return;
1.568 +
1.569 + va_start (varargs, fmt);
1.570 +#if 0
1.571 + vasprintf(&dec->error_message, fmt, varargs);
1.572 +#else
1.573 + dec->error_message = malloc(100);
1.574 + vsnprintf(dec->error_message, 100, fmt, varargs);
1.575 +#endif
1.576 + va_end (varargs);
1.577 +
1.578 + OIL_ERROR("decoder error: %s", dec->error_message);
1.579 + abort();
1.580 + dec->error = TRUE;
1.581 +}
1.582 +
1.583 +int
1.584 +jpeg_decoder_get_marker (JpegDecoder *dec, int *marker)
1.585 +{
1.586 + int a,b;
1.587 + JpegBits *bits = &dec->bits;
1.588 +
1.589 + if (jpeg_bits_available(bits) < 2) {
1.590 + return FALSE;
1.591 + }
1.592 +
1.593 + a = jpeg_bits_get_u8(bits);
1.594 + if (a != 0xff) {
1.595 + jpeg_decoder_error(dec, "expected marker, not 0x%02x", a);
1.596 + return FALSE;
1.597 + }
1.598 +
1.599 + do {
1.600 + b = jpeg_bits_get_u8 (bits);
1.601 + } while (b == 0xff && jpeg_bits_error(bits));
1.602 +
1.603 + *marker = b;
1.604 + return TRUE;
1.605 +}
1.606 +
1.607 +void
1.608 +jpeg_decoder_skip (JpegDecoder *dec)
1.609 +{
1.610 + int length;
1.611 +
1.612 + length = jpeg_bits_get_u16_be (&dec->bits);
1.613 + jpeg_bits_skip (&dec->bits, length - 2);
1.614 +}
1.615 +
1.616 +int
1.617 +jpeg_decoder_decode (JpegDecoder *dec)
1.618 +{
1.619 + JpegBits *bits;
1.620 + int marker;
1.621 +
1.622 + dec->error = FALSE;
1.623 +
1.624 + bits = &dec->bits;
1.625 +
1.626 + /* Note: The spec is ambiguous as to whether fill bytes can preceed
1.627 + * the first marker. We'll assume yes. */
1.628 + if (!jpeg_decoder_get_marker (dec, &marker)) {
1.629 + return FALSE;
1.630 + }
1.631 + if (marker != JPEG_MARKER_SOI) {
1.632 + jpeg_decoder_error(dec, "not a JPEG image");
1.633 + return FALSE;
1.634 + }
1.635 +
1.636 + /* Interpret markers up to the start of frame */
1.637 + while (!dec->error) {
1.638 + if (!jpeg_decoder_get_marker (dec, &marker)) {
1.639 + return FALSE;
1.640 + }
1.641 +
1.642 + if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) {
1.643 + jpeg_decoder_define_huffman_tables (dec);
1.644 + } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) {
1.645 + jpeg_decoder_define_arithmetic_conditioning (dec);
1.646 + } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) {
1.647 + jpeg_decoder_define_quantization_tables (dec);
1.648 + } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) {
1.649 + jpeg_decoder_define_restart_interval (dec);
1.650 + } else if (JPEG_MARKER_IS_APP(marker)) {
1.651 + /* FIXME decode app segment */
1.652 + jpeg_decoder_skip (dec);
1.653 + } else if (marker == JPEG_MARKER_COMMENT) {
1.654 + jpeg_decoder_skip (dec);
1.655 + } else if (JPEG_MARKER_IS_START_OF_FRAME(marker)) {
1.656 + break;
1.657 + } else {
1.658 + jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker);
1.659 + return FALSE;
1.660 + }
1.661 + }
1.662 +
1.663 + jpeg_decoder_start_of_frame(dec, marker);
1.664 +
1.665 + jpeg_decoder_verify_header (dec);
1.666 + if (dec->error) {
1.667 + return FALSE;
1.668 + }
1.669 +
1.670 + jpeg_decoder_init_decoder (dec);
1.671 + if (dec->error) {
1.672 + return FALSE;
1.673 + }
1.674 +
1.675 + /* In this section, we loop over parse units until we reach the end
1.676 + * of the image. */
1.677 + while (!dec->error) {
1.678 + if (!jpeg_decoder_get_marker (dec, &marker)) {
1.679 + return FALSE;
1.680 + }
1.681 +
1.682 + if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) {
1.683 + jpeg_decoder_define_huffman_tables (dec);
1.684 + } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) {
1.685 + jpeg_decoder_define_arithmetic_conditioning (dec);
1.686 + } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) {
1.687 + jpeg_decoder_define_quantization_tables (dec);
1.688 + } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) {
1.689 + jpeg_decoder_define_restart_interval (dec);
1.690 + } else if (JPEG_MARKER_IS_APP(marker)) {
1.691 + jpeg_decoder_skip (dec);
1.692 + } else if (marker == JPEG_MARKER_COMMENT) {
1.693 + jpeg_decoder_skip (dec);
1.694 + } else if (marker == JPEG_MARKER_SOS) {
1.695 + jpeg_decoder_start_of_scan (dec);
1.696 + jpeg_decoder_decode_entropy_segment (dec);
1.697 + } else if (JPEG_MARKER_IS_RESET(marker)) {
1.698 + jpeg_decoder_decode_entropy_segment (dec);
1.699 + } else if (marker == JPEG_MARKER_EOI) {
1.700 + break;
1.701 + } else {
1.702 + jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker);
1.703 + return FALSE;
1.704 + }
1.705 + }
1.706 +
1.707 + return TRUE;
1.708 +}
1.709 +
1.710 +/* handle markers */
1.711 +
1.712 +void
1.713 +jpeg_decoder_define_huffman_tables (JpegDecoder * dec)
1.714 +{
1.715 + JpegBits *bits = &dec->bits;
1.716 + int length;
1.717 + int tc;
1.718 + int th;
1.719 + int x;
1.720 + HuffmanTable *hufftab;
1.721 +
1.722 + OIL_DEBUG ("define huffman tables");
1.723 +
1.724 + length = jpeg_bits_get_u16_be (bits);
1.725 + if (length < 2) {
1.726 + jpeg_decoder_error(dec, "length too short");
1.727 + return;
1.728 + }
1.729 + length -= 2;
1.730 +
1.731 + while (length > 0) {
1.732 + x = jpeg_bits_get_u8 (bits);
1.733 + length--;
1.734 +
1.735 + tc = x >> 4;
1.736 + th = x & 0xf;
1.737 +
1.738 + OIL_DEBUG ("huff table type %d (%s) index %d", tc, tc ? "ac" : "dc", th);
1.739 + if (tc > 1 || th > 3) {
1.740 + jpeg_decoder_error(dec, "huffman table type or index out of range");
1.741 + return;
1.742 + }
1.743 +
1.744 + if (tc) {
1.745 + hufftab = &dec->ac_huff_table[th];
1.746 + length -= huffman_table_init_jpeg (hufftab, bits);
1.747 + } else {
1.748 + hufftab = &dec->dc_huff_table[th];
1.749 + length -= huffman_table_init_jpeg (hufftab, bits);
1.750 + }
1.751 + }
1.752 + if (length < 0) {
1.753 + jpeg_decoder_error(dec, "huffman table overran available bytes");
1.754 + return;
1.755 + }
1.756 +}
1.757 +
1.758 +void
1.759 +jpeg_decoder_define_quantization_tables (JpegDecoder *dec)
1.760 +{
1.761 + JpegBits *bits = &dec->bits;
1.762 + JpegQuantTable *table;
1.763 + int length;
1.764 + int pq;
1.765 + int tq;
1.766 + int i;
1.767 +
1.768 + OIL_INFO ("define quantization table");
1.769 +
1.770 + length = jpeg_bits_get_u16_be (bits);
1.771 + if (length < 2) {
1.772 + jpeg_decoder_error(dec, "length too short");
1.773 + return;
1.774 + }
1.775 + length -= 2;
1.776 +
1.777 + while (length > 0) {
1.778 + int x;
1.779 +
1.780 + x = jpeg_bits_get_u8 (bits);
1.781 + length--;
1.782 + pq = x >> 4;
1.783 + tq = x & 0xf;
1.784 +
1.785 + if (pq > 1) {
1.786 + jpeg_decoder_error (dec, "bad pq value");
1.787 + return;
1.788 + }
1.789 + if (tq > 3) {
1.790 + jpeg_decoder_error (dec, "bad tq value");
1.791 + return;
1.792 + }
1.793 +
1.794 + table = &dec->quant_tables[tq];
1.795 + if (pq) {
1.796 + for (i = 0; i < 64; i++) {
1.797 + table->quantizer[i] = jpeg_bits_get_u16_be (bits);
1.798 + length -= 2;
1.799 + }
1.800 + } else {
1.801 + for (i = 0; i < 64; i++) {
1.802 + table->quantizer[i] = jpeg_bits_get_u8 (bits);
1.803 + length -= 1;
1.804 + }
1.805 + }
1.806 + }
1.807 + if (length < 0) {
1.808 + jpeg_decoder_error(dec, "quantization table overran available bytes");
1.809 + return;
1.810 + }
1.811 +}
1.812 +
1.813 +void
1.814 +jpeg_decoder_define_restart_interval (JpegDecoder *dec)
1.815 +{
1.816 + JpegBits *bits = &dec->bits;
1.817 + int length;
1.818 +
1.819 + length = jpeg_bits_get_u16_be (bits);
1.820 + if (length != 4) {
1.821 + jpeg_decoder_error(dec, "length supposed to be 4 (%d)", length);
1.822 + return;
1.823 + }
1.824 +
1.825 + /* FIXME this needs to be checked somewhere */
1.826 + dec->restart_interval = jpeg_bits_get_u16_be (bits);
1.827 +}
1.828 +
1.829 +void
1.830 +jpeg_decoder_define_arithmetic_conditioning (JpegDecoder *dec)
1.831 +{
1.832 + /* we don't handle arithmetic coding, so skip it */
1.833 + jpeg_decoder_skip (dec);
1.834 +}
1.835 +
1.836 +void
1.837 +jpeg_decoder_start_of_frame (JpegDecoder * dec, int marker)
1.838 +{
1.839 + JpegBits *bits = &dec->bits;
1.840 + int i;
1.841 + int length;
1.842 +
1.843 + OIL_INFO ("start of frame");
1.844 +
1.845 + dec->sof_type = marker;
1.846 +
1.847 + length = jpeg_bits_get_u16_be (bits);
1.848 +
1.849 + if (jpeg_bits_available(bits) < length) {
1.850 + jpeg_decoder_error(dec, "not enough data for start_of_frame (%d < %d)",
1.851 + length, jpeg_bits_available(bits));
1.852 + return;
1.853 + }
1.854 +
1.855 + dec->depth = jpeg_bits_get_u8 (bits);
1.856 + dec->height = jpeg_bits_get_u16_be (bits);
1.857 + dec->width = jpeg_bits_get_u16_be (bits);
1.858 + dec->n_components = jpeg_bits_get_u8 (bits);
1.859 +
1.860 + OIL_DEBUG (
1.861 + "frame_length=%d depth=%d height=%d width=%d n_components=%d", length,
1.862 + dec->depth, dec->height, dec->width, dec->n_components);
1.863 +
1.864 + if (dec->n_components * 3 + 8 != length) {
1.865 + jpeg_decoder_error(dec, "inconsistent header");
1.866 + return;
1.867 + }
1.868 +
1.869 + for (i = 0; i < dec->n_components; i++) {
1.870 + dec->components[i].id = get_u8 (bits);
1.871 + dec->components[i].h_sample = getbits (bits, 4);
1.872 + dec->components[i].v_sample = getbits (bits, 4);
1.873 + dec->components[i].quant_table = get_u8 (bits);
1.874 +
1.875 + OIL_DEBUG (
1.876 + "[%d] id=%d h_sample=%d v_sample=%d quant_table=%d", i,
1.877 + dec->components[i].id, dec->components[i].h_sample,
1.878 + dec->components[i].v_sample, dec->components[i].quant_table);
1.879 + }
1.880 +}
1.881 +
1.882 +void
1.883 +jpeg_decoder_start_of_scan (JpegDecoder * dec)
1.884 +{
1.885 + JpegBits *bits = &dec->bits;
1.886 + int length;
1.887 + int i;
1.888 + int spectral_start;
1.889 + int spectral_end;
1.890 + int approx_high;
1.891 + int approx_low;
1.892 + int n;
1.893 + int tmp;
1.894 + int n_components;
1.895 +
1.896 + OIL_DEBUG ("start of scan");
1.897 +
1.898 + length = jpeg_bits_get_u16_be (bits);
1.899 + OIL_DEBUG ("length=%d", length);
1.900 +
1.901 + n_components = jpeg_bits_get_u8 (bits);
1.902 + n = 0;
1.903 + dec->scan_h_subsample = 0;
1.904 + dec->scan_v_subsample = 0;
1.905 + for (i = 0; i < n_components; i++) {
1.906 + int component_id;
1.907 + int dc_table;
1.908 + int ac_table;
1.909 + int x;
1.910 + int y;
1.911 + int index;
1.912 + int h_subsample;
1.913 + int v_subsample;
1.914 + int quant_index;
1.915 +
1.916 + component_id = jpeg_bits_get_u8 (bits);
1.917 + tmp = jpeg_bits_get_u8 (bits);
1.918 + dc_table = tmp >> 4;
1.919 + ac_table = tmp & 0xf;
1.920 + index = jpeg_decoder_find_component_by_id (dec, component_id);
1.921 +
1.922 + h_subsample = dec->components[index].h_sample;
1.923 + v_subsample = dec->components[index].v_sample;
1.924 + quant_index = dec->components[index].quant_table;
1.925 +
1.926 + for (y = 0; y < v_subsample; y++) {
1.927 + for (x = 0; x < h_subsample; x++) {
1.928 + dec->scan_list[n].component_index = index;
1.929 + dec->scan_list[n].dc_table = dc_table;
1.930 + dec->scan_list[n].ac_table = ac_table;
1.931 + dec->scan_list[n].quant_table = quant_index;
1.932 + dec->scan_list[n].x = x;
1.933 + dec->scan_list[n].y = y;
1.934 + dec->scan_list[n].offset =
1.935 + y * 8 * dec->components[index].rowstride + x * 8;
1.936 + n++;
1.937 + }
1.938 + }
1.939 +
1.940 + dec->scan_h_subsample = MAX (dec->scan_h_subsample, h_subsample);
1.941 + dec->scan_v_subsample = MAX (dec->scan_v_subsample, v_subsample);
1.942 +
1.943 + OIL_DEBUG ("component %d: index=%d dc_table=%d ac_table=%d n=%d",
1.944 + component_id, index, dc_table, ac_table, n);
1.945 + }
1.946 + dec->scan_list_length = n;
1.947 +
1.948 + spectral_start = jpeg_bits_get_u8 (bits);
1.949 + spectral_end = jpeg_bits_get_u8 (bits);
1.950 + OIL_DEBUG ("spectral range [%d,%d]", spectral_start, spectral_end);
1.951 + tmp = jpeg_bits_get_u8 (bits);
1.952 + approx_high = tmp >> 4;
1.953 + approx_low = tmp & 0xf;
1.954 + OIL_DEBUG ("approx range [%d,%d]", approx_low, approx_high);
1.955 +
1.956 + dec->x = 0;
1.957 + dec->y = 0;
1.958 + dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128 * 8;
1.959 +}
1.960 +
1.961 +
1.962 +
1.963 +
1.964 +
1.965 +
1.966 +
1.967 +
1.968 +
1.969 +
1.970 +
1.971 +
1.972 +int
1.973 +jpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len)
1.974 +{
1.975 + unsigned int offset;
1.976 +
1.977 + offset = dec->bits.ptr - dec->data;
1.978 +
1.979 + dec->data = realloc (dec->data, dec->data_len + len);
1.980 + memcpy (dec->data + dec->data_len, data, len);
1.981 + dec->data_len += len;
1.982 +
1.983 + dec->bits.ptr = dec->data + offset;
1.984 + dec->bits.end = dec->data + dec->data_len;
1.985 +
1.986 + return 0;
1.987 +}
1.988 +
1.989 +int
1.990 +jpeg_decoder_get_image_size (JpegDecoder * dec, int *width, int *height)
1.991 +{
1.992 + if (width)
1.993 + *width = dec->width;
1.994 + if (height)
1.995 + *height = dec->height;
1.996 +
1.997 + return 0;
1.998 +}
1.999 +
1.1000 +int
1.1001 +jpeg_decoder_get_component_ptr (JpegDecoder * dec, int id,
1.1002 + unsigned char **image, int *rowstride)
1.1003 +{
1.1004 + int i;
1.1005 +
1.1006 + i = jpeg_decoder_find_component_by_id (dec, id);
1.1007 + if (image)
1.1008 + *image = dec->components[i].image;
1.1009 + if (rowstride)
1.1010 + *rowstride = dec->components[i].rowstride;
1.1011 +
1.1012 + return 0;
1.1013 +}
1.1014 +
1.1015 +int
1.1016 +jpeg_decoder_get_component_size (JpegDecoder * dec, int id,
1.1017 + int *width, int *height)
1.1018 +{
1.1019 + int i;
1.1020 +
1.1021 + /* subsampling sizes are rounded up */
1.1022 +
1.1023 + i = jpeg_decoder_find_component_by_id (dec, id);
1.1024 + if (width)
1.1025 + *width = (dec->width - 1) / dec->components[i].h_subsample + 1;
1.1026 + if (height)
1.1027 + *height = (dec->height - 1) / dec->components[i].v_subsample + 1;
1.1028 +
1.1029 + return 0;
1.1030 +}
1.1031 +
1.1032 +int
1.1033 +jpeg_decoder_get_component_subsampling (JpegDecoder * dec, int id,
1.1034 + int *h_subsample, int *v_subsample)
1.1035 +{
1.1036 + int i;
1.1037 +
1.1038 + i = jpeg_decoder_find_component_by_id (dec, id);
1.1039 + if (h_subsample)
1.1040 + *h_subsample = dec->components[i].h_subsample;
1.1041 + if (v_subsample)
1.1042 + *v_subsample = dec->components[i].v_subsample;
1.1043 +
1.1044 + return 0;
1.1045 +}
1.1046 +
1.1047 +#if 0
1.1048 +int
1.1049 +jpeg_decoder_parse (JpegDecoder * dec)
1.1050 +{
1.1051 + JpegBits *bits = &dec->bits;
1.1052 + JpegBits b2;
1.1053 + unsigned int x;
1.1054 + unsigned int tag;
1.1055 + int i;
1.1056 +
1.1057 + while (bits->ptr < bits->end) {
1.1058 + x = get_u8 (bits);
1.1059 + if (x != 0xff) {
1.1060 + int n = 0;
1.1061 +
1.1062 + while (x != 0xff) {
1.1063 + x = get_u8 (bits);
1.1064 + n++;
1.1065 + }
1.1066 + OIL_DEBUG ("lost sync, skipped %d bytes", n);
1.1067 + }
1.1068 + while (x == 0xff) {
1.1069 + x = get_u8 (bits);
1.1070 + }
1.1071 + tag = x;
1.1072 + OIL_DEBUG ("tag %02x", tag);
1.1073 +
1.1074 + b2 = *bits;
1.1075 +
1.1076 + for (i = 0; i < n_jpeg_markers - 1; i++) {
1.1077 + if (tag == jpeg_markers[i].tag) {
1.1078 + break;
1.1079 + }
1.1080 + }
1.1081 + OIL_DEBUG ("tag: %s", jpeg_markers[i].name);
1.1082 + if (jpeg_markers[i].func) {
1.1083 + jpeg_markers[i].func (dec, &b2);
1.1084 + } else {
1.1085 + OIL_DEBUG ("unhandled or illegal JPEG marker (0x%02x)", tag);
1.1086 + dumpbits (&b2);
1.1087 + }
1.1088 + if (jpeg_markers[i].flags & JPEG_ENTROPY_SEGMENT) {
1.1089 + jpeg_decoder_decode_entropy_segment (dec, &b2);
1.1090 + }
1.1091 + syncbits (&b2);
1.1092 + bits->ptr = b2.ptr;
1.1093 + }
1.1094 +
1.1095 + return 0;
1.1096 +}
1.1097 +#endif
1.1098 +
1.1099 +
1.1100 +/* misc helper functins */
1.1101 +
1.1102 +static char *
1.1103 +sprintbits (char *str, unsigned int bits, int n)
1.1104 +{
1.1105 + int i;
1.1106 + int bit = 1 << (n - 1);
1.1107 +
1.1108 + for (i = 0; i < n; i++) {
1.1109 + str[i] = (bits & bit) ? '1' : '0';
1.1110 + bit >>= 1;
1.1111 + }
1.1112 + str[i] = 0;
1.1113 +
1.1114 + return str;
1.1115 +}
1.1116 +
1.1117 +static void
1.1118 +huffman_table_load_std_jpeg (JpegDecoder * dec)
1.1119 +{
1.1120 + JpegBits b, *bits = &b;
1.1121 +
1.1122 + bits->ptr = jpeg_standard_tables;
1.1123 + bits->idx = 0;
1.1124 + bits->end = jpeg_standard_tables + jpeg_standard_tables_size;
1.1125 +
1.1126 + huffman_table_init_jpeg (&dec->dc_huff_table[0], bits);
1.1127 + huffman_table_init_jpeg (&dec->ac_huff_table[0], bits);
1.1128 + huffman_table_init_jpeg (&dec->dc_huff_table[1], bits);
1.1129 + huffman_table_init_jpeg (&dec->ac_huff_table[1], bits);
1.1130 +}
1.1131 +
1.1132 +
1.1133 +