⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeg.c

📁 swf 解码源程序, 纯C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (a != 0xff) {    jpeg_decoder_error(dec, "expected marker, not 0x%02x", a);    return FALSE;  }  do {    b = jpeg_bits_get_u8 (bits);  } while (b == 0xff && jpeg_bits_error(bits));  *marker = b;  return TRUE;}static voidjpeg_decoder_skip (JpegDecoder *dec){  int length;  length = jpeg_bits_get_u16_be (&dec->bits);  jpeg_bits_skip (&dec->bits, length - 2);}intjpeg_decoder_decode (JpegDecoder *dec){  JpegBits *bits;  int marker;  dec->error = FALSE;  bits = &dec->bits;  /* Note: The spec is ambiguous as to whether fill bytes can come   * before the first marker.  We'll assume yes. */  if (!jpeg_decoder_get_marker (dec, &marker)) {    return FALSE;  }  if (dec->strict && marker != JPEG_MARKER_SOI) {    jpeg_decoder_error(dec, "not a JPEG image");    return FALSE;  }  /* Interpret markers up to the start of frame */  while (!dec->error) {    if (!jpeg_decoder_get_marker (dec, &marker)) {      return FALSE;    }    if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) {      jpeg_decoder_define_huffman_tables (dec);    } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) {      jpeg_decoder_define_arithmetic_conditioning (dec);    } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) {      jpeg_decoder_define_quantization_tables (dec);    } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) {      jpeg_decoder_define_restart_interval (dec);    } else if (JPEG_MARKER_IS_APP(marker)) {      /* FIXME decode app segment */      jpeg_decoder_skip (dec);    } else if (marker == JPEG_MARKER_COMMENT) {      jpeg_decoder_skip (dec);    } else if (JPEG_MARKER_IS_START_OF_FRAME(marker)) {      break;    } else if (marker == JPEG_MARKER_SOI) {      if (dec->strict) {        jpeg_decoder_error (dec, "unexpected SOI");        return FALSE;      }    } else if (marker == JPEG_MARKER_EOI) {      if (dec->strict) {        jpeg_decoder_error (dec, "unexpected EOI");        return FALSE;      }    } else {      jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker);      return FALSE;    }  }  if (dec->error) {    return FALSE;  }  jpeg_decoder_start_of_frame(dec, marker);  jpeg_decoder_verify_header (dec);  if (dec->error) {    return FALSE;  }  jpeg_decoder_init_decoder (dec);  if (dec->error) {    return FALSE;  }  /* In this section, we loop over parse units until we reach the end   * of the image. */  while (!dec->error) {    if (!jpeg_decoder_get_marker (dec, &marker)) {      return FALSE;    }    if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) {      jpeg_decoder_define_huffman_tables (dec);    } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) {      jpeg_decoder_define_arithmetic_conditioning (dec);    } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) {      jpeg_decoder_define_quantization_tables (dec);    } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) {      jpeg_decoder_define_restart_interval (dec);    } else if (JPEG_MARKER_IS_APP(marker)) {      jpeg_decoder_skip (dec);    } else if (marker == JPEG_MARKER_COMMENT) {      jpeg_decoder_skip (dec);    } else if (marker == JPEG_MARKER_SOS) {      jpeg_decoder_start_of_scan (dec);      if (dec->error) {        return FALSE;      }      jpeg_decoder_decode_entropy_segment (dec);    } else if (JPEG_MARKER_IS_RESET(marker)) {      jpeg_decoder_decode_entropy_segment (dec);    } else if (marker == JPEG_MARKER_SOI) {      if (dec->strict) {        jpeg_decoder_error (dec, "unexpected SOI");        return FALSE;      }    } else if (marker == JPEG_MARKER_EOI) {      if (dec->strict) {        jpeg_decoder_error (dec, "unexpected EOI");        return FALSE;      } else {        break;      }    } else {      jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker);      return FALSE;    }  }  if (dec->error) {    return FALSE;  }  return TRUE;}/* handle markers */voidjpeg_decoder_define_huffman_tables (JpegDecoder * dec){  JpegBits *bits = &dec->bits;  int length;  int tc;  int th;  int x;  HuffmanTable *hufftab;  COG_DEBUG ("define huffman tables");  length = jpeg_bits_get_u16_be (bits);  if (length < 2) {    jpeg_decoder_error(dec, "length too short");    return;  }  length -= 2;  while (length > 0) {    x = jpeg_bits_get_u8 (bits);    length--;    tc = x >> 4;    th = x & 0xf;    COG_DEBUG ("huff table type %d (%s) idx %d", tc, tc ? "ac" : "dc", th);    if (tc > 1 || th > 3) {      jpeg_decoder_error(dec, "huffman table type or idx out of range");      return;    }    if (tc) {      hufftab = &dec->ac_huff_table[th];      length -= huffman_table_init_jpeg (dec, hufftab, bits);    } else {      hufftab = &dec->dc_huff_table[th];      length -= huffman_table_init_jpeg (dec, hufftab, bits);    }    if (dec->error) {      return;    }  }  if (length < 0) {    jpeg_decoder_error(dec, "huffman table overran available bytes");    return;  }}voidjpeg_decoder_define_quantization_tables (JpegDecoder *dec){  JpegBits *bits = &dec->bits;  JpegQuantTable *table;  int length;  int pq;  int tq;  int i;  COG_INFO ("define quantization table");  length = jpeg_bits_get_u16_be (bits);  if (length < 2) {    jpeg_decoder_error(dec, "length too short");    return;  }  length -= 2;  while (length > 0) {    int x;        x = jpeg_bits_get_u8 (bits);    length--;    pq = x >> 4;    tq = x & 0xf;    if (pq > 1) {      jpeg_decoder_error (dec, "bad pq value");      return;    }    if (tq > 3) {      jpeg_decoder_error (dec, "bad tq value");      return;    }    table = &dec->quant_tables[tq];    if (pq) {      for (i = 0; i < 64; i++) {        table->quantizer[i] = jpeg_bits_get_u16_be (bits);        length -= 2;      }    } else {      for (i = 0; i < 64; i++) {        table->quantizer[i] = jpeg_bits_get_u8 (bits);        length -= 1;      }    }  }  if (length < 0) {    jpeg_decoder_error(dec, "quantization table overran available bytes");    return;  }}voidjpeg_decoder_define_restart_interval (JpegDecoder *dec){  JpegBits *bits = &dec->bits;  int length;  length = jpeg_bits_get_u16_be (bits);  if (length != 4) {    jpeg_decoder_error(dec, "length supposed to be 4 (%d)", length);    return;  }  /* FIXME this needs to be checked somewhere */  dec->restart_interval = jpeg_bits_get_u16_be (bits);}voidjpeg_decoder_define_arithmetic_conditioning (JpegDecoder *dec){  /* we don't handle arithmetic coding, so skip it */  jpeg_decoder_skip (dec);}voidjpeg_decoder_start_of_frame (JpegDecoder * dec, int marker){  JpegBits *bits = &dec->bits;  int i;  int length;  COG_INFO ("start of frame");  dec->sof_type = marker;  length = jpeg_bits_get_u16_be (bits);  if (jpeg_bits_available(bits) < length) {    jpeg_decoder_error(dec, "not enough data for start_of_frame (%d < %d)",        length, jpeg_bits_available(bits));    return;  }  dec->depth = jpeg_bits_get_u8 (bits);  dec->height = jpeg_bits_get_u16_be (bits);  dec->width = jpeg_bits_get_u16_be (bits);  dec->n_components = jpeg_bits_get_u8 (bits);  COG_DEBUG (      "frame_length=%d depth=%d height=%d width=%d n_components=%d", length,      dec->depth, dec->height, dec->width, dec->n_components);  if (dec->n_components * 3 + 8 != length) {    jpeg_decoder_error(dec, "inconsistent header");    return;  }  for (i = 0; i < dec->n_components; i++) {    dec->components[i].id = get_u8 (bits);    dec->components[i].h_sample = getbits (bits, 4);    dec->components[i].v_sample = getbits (bits, 4);    dec->components[i].quant_table = get_u8 (bits);    COG_DEBUG (        "[%d] id=%d h_sample=%d v_sample=%d quant_table=%d", i,        dec->components[i].id, dec->components[i].h_sample,        dec->components[i].v_sample, dec->components[i].quant_table);  }}voidjpeg_decoder_start_of_scan (JpegDecoder * dec){  JpegBits *bits = &dec->bits;  int length;  int i;  int spectral_start;  int spectral_end;  int approx_high;  int approx_low;  int n;  int tmp;  int n_components;  COG_DEBUG ("start of scan");  length = jpeg_bits_get_u16_be (bits);  COG_DEBUG ("length=%d", length);  n_components = jpeg_bits_get_u8 (bits);  n = 0;  dec->scan_h_subsample = 0;  dec->scan_v_subsample = 0;  for (i = 0; i < n_components; i++) {    int component_id;    int dc_table;    int ac_table;    int x;    int y;    int idx;    int h_subsample;    int v_subsample;    int quant_index;    component_id = jpeg_bits_get_u8 (bits);    tmp = jpeg_bits_get_u8 (bits);    dc_table = tmp >> 4;    ac_table = tmp & 0xf;    idx = jpeg_decoder_find_component_by_id (dec, component_id);    h_subsample = dec->components[idx].h_sample;    v_subsample = dec->components[idx].v_sample;    quant_index = dec->components[idx].quant_table;    for (y = 0; y < v_subsample; y++) {      for (x = 0; x < h_subsample; x++) {        dec->scan_list[n].component_index = idx;        dec->scan_list[n].dc_table = dc_table;        dec->scan_list[n].ac_table = ac_table;        dec->scan_list[n].quant_table = quant_index;        dec->scan_list[n].x = x;        dec->scan_list[n].y = y;        dec->scan_list[n].offset =            y * 8 * dec->components[idx].rowstride + x * 8;        n++;        if (n > JPEG_LIMIT_SCAN_LIST_LENGTH) {          jpeg_decoder_error(dec, "scan list too long");          return;        }      }    }    dec->scan_h_subsample = MAX (dec->scan_h_subsample, h_subsample);    dec->scan_v_subsample = MAX (dec->scan_v_subsample, v_subsample);    COG_DEBUG ("component %d: idx=%d dc_table=%d ac_table=%d n=%d",        component_id, idx, dc_table, ac_table, n);  }  dec->scan_list_length = n;  spectral_start = jpeg_bits_get_u8 (bits);  spectral_end = jpeg_bits_get_u8 (bits);  COG_DEBUG ("spectral range [%d,%d]", spectral_start, spectral_end);  tmp = jpeg_bits_get_u8 (bits);  approx_high = tmp >> 4;  approx_low = tmp & 0xf;  COG_DEBUG ("approx range [%d,%d]", approx_low, approx_high);  dec->x = 0;  dec->y = 0;  dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128 * 8;}intjpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len){  unsigned int offset;  offset = dec->bits.ptr - dec->data;  dec->data = realloc (dec->data, dec->data_len + len);  memcpy (dec->data + dec->data_len, data, len);  dec->data_len += len;  dec->bits.ptr = dec->data + offset;  dec->bits.end = dec->data + dec->data_len;  return 0;}intjpeg_decoder_get_image_size (JpegDecoder * dec, int *width, int *height){  if (width)    *width = dec->width;  if (height)    *height = dec->height;  return 0;}intjpeg_decoder_get_component_ptr (JpegDecoder * dec, int id,    unsigned char **image, int *rowstride){  int i;  i = jpeg_decoder_find_component_by_id (dec, id);  if (image)    *image = dec->components[i].image;  if (rowstride)    *rowstride = dec->components[i].rowstride;  return 0;}intjpeg_decoder_get_component_size (JpegDecoder * dec, int id,    int *width, int *height){  int i;  /* subsampling sizes are rounded up */  i = jpeg_decoder_find_component_by_id (dec, id);  if (width)    *width = (dec->width - 1) / dec->components[i].h_subsample + 1;  if (height)    *height = (dec->height - 1) / dec->components[i].v_subsample + 1;  return 0;}intjpeg_decoder_get_component_subsampling (JpegDecoder * dec, int id,    int *h_subsample, int *v_subsample){  int i;  i = jpeg_decoder_find_component_by_id (dec, id);  if (h_subsample)    *h_subsample = dec->components[i].h_subsample;  if (v_subsample)    *v_subsample = dec->components[i].v_subsample;  return 0;}#if 0intjpeg_decoder_parse (JpegDecoder * dec){  JpegBits *bits = &dec->bits;  JpegBits b2;  unsigned int x;  unsigned int tag;  int i;  while (bits->ptr < bits->end) {    x = get_u8 (bits);    if (x != 0xff) {      int n = 0;      while (x != 0xff) {        x = get_u8 (bits);        n++;      }      OIL_DEBUG ("lost sync, skipped %d bytes", n);    }    while (x == 0xff) {      x = get_u8 (bits);    }    tag = x;    OIL_DEBUG ("tag %02x", tag);    b2 = *bits;    for (i = 0; i < n_jpeg_markers - 1; i++) {      if (tag == jpeg_markers[i].tag) {        break;      }    }    OIL_DEBUG ("tag: %s", jpeg_markers[i].name);    if (jpeg_markers[i].func) {      jpeg_markers[i].func (dec, &b2);    } else {      OIL_DEBUG ("unhandled or illegal JPEG marker (0x%02x)", tag);      dumpbits (&b2);    }    if (jpeg_markers[i].flags & JPEG_ENTROPY_SEGMENT) {      jpeg_decoder_decode_entropy_segment (dec, &b2);    }    syncbits (&b2);    bits->ptr = b2.ptr;  }  return 0;}#endif/* misc helper functins */static voidjpeg_load_standard_huffman_tables (JpegDecoder * dec){  JpegBits b, *bits = &b;  bits->ptr = jpeg_standard_tables;  bits->idx = 0;  bits->end = jpeg_standard_tables + jpeg_standard_tables_size;  huffman_table_init_jpeg (dec, &dec->dc_huff_table[0], bits);  huffman_table_init_jpeg (dec, &dec->ac_huff_table[0], bits);  huffman_table_init_jpeg (dec, &dec->dc_huff_table[1], bits);  huffman_table_init_jpeg (dec, &dec->ac_huff_table[1], bits);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -