os/ossrv/genericopenlibs/liboil/tsrc/examples/jpeg/src/jpeg.c
changeset 0 bde4ae8d615e
     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 +