home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1992-1993 Michael Davidson.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation.
- *
- * This software is provided "as is" without express or implied warranty.
- */
-
- /*
- * This software is derived from the Independent JPEG Group's software
- *
- * Copyright (C) 1991, 1992 Thomas G. Lane.
- * This file is part of the Independent JPEG Group's software.
- *
- * For conditions of distribution and use, see the accompanying README file.
- */
-
- #include "jpeg.h"
-
- int
- jpegDHT(
- FILE *fp,
- JPEG_TABLES *tables
- )
- {
- int i;
- int count;
- int length;
- unsigned code;
- HUFF_TBL *htbl;
-
- length = jpegGetWord(fp) - 2;
-
- while (length > 0)
- {
- i = jpegGetByte(fp);
-
- htbl = (i & 0x10) ? tables->ac_huff_table : tables->dc_huff_table;
- i &= 0x0f;
-
- if (i >= NUM_HUFF_TBLS)
- return jpegError("illegal table index (%d) in DHT marker", i);
-
- htbl += i;
-
- htbl->huff_code[0].maxcode = -1;
- htbl->huff_code[0].codeptr = NULL;
-
- count = 0;
- code = 0;
- for (i = 1; i <= 16; i++)
- {
- int n;
-
- n = jpegGetByte(fp);
- if (n != 0)
- {
- htbl->huff_code[i].codeptr = & htbl->huffval[count - code];
- count += n;
- code += n;
- htbl->huff_code[i].maxcode = code-1;
- }
- else
- {
- htbl->huff_code[i].maxcode = -1;
- htbl->huff_code[i].codeptr = NULL;
- }
- code <<= 1;
- }
- htbl->huff_code[17].maxcode = 0xFFFFF;
- htbl->huff_code[17].codeptr = NULL;
-
- if (count > 256)
- return jpegError("more than 256 codes in DHT marker");
-
- for (i = 0; i < count; i++)
- htbl->huffval[i] = jpegGetByte(fp);
-
- length -= 1 + 16 + count;
- }
-
- if (length != 0)
- return jpegError("illegal marker length in DHT marker");
-
- return 0;
- }
-
-
- int
- jpegDQT (
- FILE *fp,
- JPEG_TABLES *tables
- )
- {
- int i;
- int length;
- int prec;
- QUANT_VAL *q;
-
- length = jpegGetWord(fp) - 2;
-
- while (length > 0)
- {
- i = jpegGetByte(fp);
- --length;
- prec = i >> 4;
- i &= 0x0F;
-
- if (i >= NUM_QUANT_TBLS)
- return jpegError("illegal table index (%d) in DQT marker", i);
-
- q = tables->quant_table[i].q;
-
- if (prec)
- {
- for (i = 0; i < DCTSIZE2; i++)
- q[i] = jpegGetWord(fp);
- length -= DCTSIZE2 * 2;
- }
- else
- {
- for (i = 0; i < DCTSIZE2; i++)
- q[i] = jpegGetByte(fp);
- length -= DCTSIZE2;
- }
- }
-
- if (length != 0)
- return jpegError("illegal marker length in DHT marker");
-
- return 0;
- }
-
- /*
- * unused bits are aligned at the most significant end of the
- * buffer
- */
- #define DECODE_BUF_SIZE 1024
-
- static unsigned char decode_buf[DECODE_BUF_SIZE + 32];
- static unsigned long db_offset;
-
- #if defined(ASM)
- unsigned char *db_ptr;
- unsigned char *db_end;
- unsigned long get_buffer; /* current bit-extraction buffer */
- int bits_left; /* # of unused bits in it */
- #else
- STATIC unsigned char *db_ptr;
- STATIC unsigned char *db_end;
- STATIC unsigned long get_buffer; /* current bit-extraction buffer */
- STATIC int bits_left; /* # of unused bits in it */
- #endif
-
- #define MORE_BITS(fp) \
- do \
- { \
- int c0, c1; \
- if ((c0 = *db_ptr++) == 0xff && (c1 = *db_ptr++) != 0)\
- { \
- if (db_ptr == db_end) \
- { \
- fill_decode_buf(fp); \
- continue; \
- } \
- db_ptr -= 2; \
- break; \
- } \
- bits_left += 8; \
- get_buffer |= (c0 << (32 - bits_left)); \
- } while (bits_left <= 24)
-
- check_marker(
- FILE *fp
- )
- {
- int c0, c1;
-
- if (db_ptr == db_end) /* end of buffer */
- {
- fill_decode_buf(fp);
- if ((c0 = *db_ptr++) == 0xff && (c1 = *db_ptr++) != 0)
- {
- db_ptr -= 2;
- return -1;
- }
- return c0;
- }
- db_ptr -= 2;
- return -1;
- }
-
- /*
- * fill_decode_buf()
- *
- * get another buffer of data for the Huffman decoder
- *
- * Since the Huffman decoder has to have a special check for
- * 0xff escape bytes we use a special 0xff 0xff sequence to
- * mark the end of the buffer. Whenever BORE_BITS() sees
- * something which looks like a marker (ie 0xff followed by
- * anything other than 0x00) it checks to see if it has
- * reached the end of the buffer.
- *
- * This technique eliminates the need for an explicit check
- * on the amount of data left in the buffer
- */
- fill_decode_buf(
- FILE *fp
- )
- {
- int nread;
-
- db_ptr = decode_buf;
- db_offset = ftell(fp);
- nread = fread(decode_buf, 1, 1024, fp);
-
- #if defined(DEBUG)
- fprintf(stderr, "fill_decode_buf: offset = %6ld, nbytes = %4d",
- db_offset, nread);
- #endif
- if (nread <= 0)
- {
- decode_buf[0] = 0xff;
- decode_buf[1] = 0xd9;
- decode_buf[2] = 0xff;
- decode_buf[3] = 0xff;
- db_end = &decode_buf[4];
- }
- else
- {
- db_end = decode_buf + nread;
- if (db_end[-1] == 0xff)
- {
- int c;
-
- while ((c = getc(fp)) == 0xff)
- continue;
-
- *db_end++ = c;
- }
- *db_end++ = 0xff;
- *db_end++ = 0xff;
- }
- #if defined(DEBUG)
- fprintf(stderr, " db_end = %08x\n", db_end);
- #endif
- }
-
- flush_decode_buf(
- FILE *fp
- )
- {
- long offset;
-
- offset = db_offset + (db_ptr - decode_buf);
- fseek(fp, offset, 0);
- }
-
- /*
- * Initialize for a Huffman-compressed scan.
- * This is invoked after reading the SOS marker.
- */
-
- void
- huff_decoder_init(
- FILE *fp
- )
- {
- /*
- * Initialize static variables
- */
- bits_left = 0;
- get_buffer = 0;
- fill_decode_buf(fp);
- }
-
- huff_decoder_term(
- FILE *fp
- )
- {
- flush_decode_buf(fp);
- }
-
- /*
- * Check for a restart marker & resynchronize decoder.
- */
-
- jpegCheckRestart(
- FILE *fp,
- int next
- )
- {
- int ret = 0;
- int c, nbytes;
-
- bits_left = 0;
- get_buffer = 0;
-
- nbytes = 0;
-
- do
- {
- do
- {
- c = *db_ptr++;
- } while (c != 0xff);
-
- do
- { /* skip any duplicate FFs */
- if (db_ptr == db_end)
- fill_decode_buf(fp);
- c = *db_ptr++;
- } while (c == 0xFF);
- } while (c == 0); /* repeat if it was a stuffed FF/00 */
-
- if (c != (RST0 + next))
- {
- imageWarning("Found 0x%02x marker instead of RST%d",
- c, next);
- ret = -1;
- }
-
- return ret;
- }
-
- int
- jpegDecodeMCU(
- FILE *fp,
- int MCU_blocks,
- DBLOCK_INFO MCU_info[]
- )
- {
- int i;
- int r;
- DBLOCK_INFO *d;
-
- for (i = 0, d = MCU_info; i < MCU_blocks; i++, d++)
- if ((r = jpegHuffDecode(fp, d->coeff_data, &d->dc_table->huff_code,
- &d->ac_table->huff_code, d->dc_prediction, d->quant_table)) != 0)
- return r;
- return 0;
- }
-
- #if !defined(ASM)
- /* ZAG[i] is the natural-order position of the i'th element of zigzag order.
- * If the incoming data is corrupted, huff_decode_mcu could attempt to
- * reference values beyond the end of the array. To avoid a wild store,
- * we put some extra zeroes after the real entries.
- */
-
- static const short ZAG[DCTSIZE2+16] = {
- 0, 1, 8, 16, 9, 2, 3, 10,
- 17, 24, 32, 25, 18, 11, 4, 5,
- 12, 19, 26, 33, 40, 48, 41, 34,
- 27, 20, 13, 6, 7, 14, 21, 28,
- 35, 42, 49, 56, 57, 50, 43, 36,
- 29, 22, 15, 23, 30, 37, 44, 51,
- 58, 59, 52, 45, 38, 31, 39, 46,
- 53, 60, 61, 54, 47, 55, 62, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
- 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- /*
- * Decode a single block's worth of coefficients
- */
- jpegHuffDecode(
- FILE *fp,
- JBLOCK *block,
- HUFF_CODE *dc,
- HUFF_CODE *ac,
- JCOEF *dcval,
- QUANT_VAL *quanttbl
- )
- {
- QUANT_VAL q0;
- int ret_code = 0;
-
- int s, k, r;
- int code;
- struct huff_code *hc;
-
- /*
- * Save the first entry in the quant table and set the table
- * entry to 1. This allows us to fix up the DC coefficient later
- */
- q0 = quanttbl[0];
- quanttbl[0] = 1;
-
- for (k = 0, hc = dc; k < DCTSIZE2; k++, hc = ac)
- {
- if (bits_left < 16)
- MORE_BITS(fp);
-
- for (code = 0; code > hc->maxcode; hc++)
- {
- code += code + (get_buffer >> 31);
- get_buffer <<= 1;
- --bits_left;
- }
-
- if (hc->codeptr == NULL || bits_left < 0)
- {
- ret_code = -1;
- break;
- }
-
- r = hc->codeptr[code];
- s = r & 15;
- r = r >> 4;
-
- if (s)
- {
- register int nbits = s;
-
- k += r;
-
- if (nbits > bits_left)
- MORE_BITS(fp);
-
- if (get_buffer & 0x80000000)
- s = get_buffer >> (32 - nbits);
- else
- s = (get_buffer >> (32 - nbits)) + (-1 << nbits) + 1;
-
- get_buffer <<= nbits;
- bits_left -= nbits;
-
- /*
- * Descale coefficient and output in natural order
- */
- (*block)[ZAG[k]] = (JCOEF) (((JCOEF) s) * quanttbl[k]);
- }
- else if (k != 0)
- {
- if (r != 15)
- break;
- k += 15;
- }
- }
-
- /*
- * fix quant table and DC coefficient
- */
- quanttbl[0] = q0;
- s = (*block)[0];
- *dcval += s;
- s = *dcval;
- (*block)[0] = (JCOEF) (((JCOEF) s) * q0);
-
- return ret_code;
- }
- #endif
-