home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-02 | 53.7 KB | 1,771 lines |
- Newsgroups: comp.sources.misc
- From: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Subject: REPOST: v29i011: jpeg - JPEG image compression, Part11/18
- Message-ID: <1992Mar28.211945.29008@sparky.imd.sterling.com>
- X-Md4-Signature: 66459c7452d01d21bea1bd244039f9d4
- Date: Sat, 28 Mar 1992 21:19:45 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Posting-number: Volume 29, Issue 11
- Archive-name: jpeg/part11
- Environment: UNIX, VMS, MS-DOS, Mac, Amiga, Cray
-
- [ Reposted due to a propagation problem. -Kent+ ]
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: jchuff.c jcmain.c jrdgif.c makljpeg.cf
- # Wrapped by kent@sparky on Mon Mar 23 16:02:49 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 11 (of 18)."'
- if test -f 'jchuff.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jchuff.c'\"
- else
- echo shar: Extracting \"'jchuff.c'\" \(20071 characters\)
- sed "s/^X//" >'jchuff.c' <<'END_OF_FILE'
- X/*
- X * jchuff.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains Huffman entropy encoding routines.
- X * These routines are invoked via the methods entropy_encode,
- X * entropy_encoder_init/term, and entropy_optimize.
- X */
- X
- X#include "jinclude.h"
- X
- X
- X/* Static variables to avoid passing 'round extra parameters */
- X
- Xstatic compress_info_ptr cinfo;
- X
- Xstatic INT32 huff_put_buffer; /* current bit-accumulation buffer */
- Xstatic int huff_put_bits; /* # of bits now in it */
- X
- Xstatic char * output_buffer; /* output buffer */
- Xstatic int bytes_in_buffer;
- X
- X
- X
- XLOCAL void
- Xfix_huff_tbl (HUFF_TBL * htbl)
- X/* Compute derived values for a Huffman table */
- X{
- X int p, i, l, lastp, si;
- X char huffsize[257];
- X UINT16 huffcode[257];
- X UINT16 code;
- X
- X /* Figure C.1: make table of Huffman code length for each symbol */
- X /* Note that this is in code-length order. */
- X
- X p = 0;
- X for (l = 1; l <= 16; l++) {
- X for (i = 1; i <= (int) htbl->bits[l]; i++)
- X huffsize[p++] = (char) l;
- X }
- X huffsize[p] = 0;
- X lastp = p;
- X
- X /* Figure C.2: generate the codes themselves */
- X /* Note that this is in code-length order. */
- X
- X code = 0;
- X si = huffsize[0];
- X p = 0;
- X while (huffsize[p]) {
- X while (((int) huffsize[p]) == si) {
- X huffcode[p++] = code;
- X code++;
- X }
- X code <<= 1;
- X si++;
- X }
- X
- X /* Figure C.3: generate encoding tables */
- X /* These are code and size indexed by symbol value */
- X
- X /* Set any codeless symbols to have code length 0;
- X * this allows emit_bits to detect any attempt to emit such symbols.
- X */
- X MEMZERO((void *) htbl->ehufsi, SIZEOF(htbl->ehufsi));
- X
- X for (p = 0; p < lastp; p++) {
- X htbl->ehufco[htbl->huffval[p]] = huffcode[p];
- X htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
- X }
- X
- X /* We don't bother to fill in the decoding tables mincode[], maxcode[], */
- X /* and valptr[], since they are not used for encoding. */
- X}
- X
- X
- X/* Outputting bytes to the file */
- X
- XLOCAL void
- Xflush_bytes (void)
- X{
- X if (bytes_in_buffer)
- X (*cinfo->methods->entropy_output) (cinfo, output_buffer, bytes_in_buffer);
- X bytes_in_buffer = 0;
- X}
- X
- X
- X#define emit_byte(val) \
- X MAKESTMT( if (bytes_in_buffer >= JPEG_BUF_SIZE) \
- X flush_bytes(); \
- X output_buffer[bytes_in_buffer++] = (char) (val); )
- X
- X
- X
- X/* Outputting bits to the file */
- X
- X/* Only the right 24 bits of huff_put_buffer are used; the valid bits are
- X * left-justified in this part. At most 16 bits can be passed to emit_bits
- X * in one call, and we never retain more than 7 bits in huff_put_buffer
- X * between calls, so 24 bits are sufficient.
- X */
- X
- XLOCAL void
- Xemit_bits (UINT16 code, int size)
- X{
- X /* This routine is heavily used, so it's worth coding tightly. */
- X register INT32 put_buffer = code;
- X register int put_bits = huff_put_bits;
- X
- X /* if size is 0, caller used an invalid Huffman table entry */
- X if (size == 0)
- X ERREXIT(cinfo->emethods, "Missing Huffman code table entry");
- X
- X put_buffer &= (((INT32) 1) << size) - 1; /* Mask off any excess bits in code */
- X
- X put_bits += size; /* new number of bits in buffer */
- X
- X put_buffer <<= 24 - put_bits; /* align incoming bits */
- X
- X put_buffer |= huff_put_buffer; /* and merge with old buffer contents */
- X
- X while (put_bits >= 8) {
- X int c = (int) ((put_buffer >> 16) & 0xFF);
- X
- X emit_byte(c);
- X if (c == 0xFF) { /* need to stuff a zero byte? */
- X emit_byte(0);
- X }
- X put_buffer <<= 8;
- X put_bits -= 8;
- X }
- X
- X huff_put_buffer = put_buffer; /* Update global variables */
- X huff_put_bits = put_bits;
- X}
- X
- X
- XLOCAL void
- Xflush_bits (void)
- X{
- X emit_bits((UINT16) 0x7F, 7); /* fill any partial byte with ones */
- X huff_put_buffer = 0; /* and reset bit-buffer to empty */
- X huff_put_bits = 0;
- X}
- X
- X
- X
- X/* Encode a single block's worth of coefficients */
- X/* Note that the DC coefficient has already been converted to a difference */
- X
- XLOCAL void
- Xencode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
- X{
- X register int temp, temp2;
- X register int nbits;
- X register int k, r, i;
- X
- X /* Encode the DC coefficient difference per section F.1.2.1 */
- X
- X temp = temp2 = block[0];
- X
- X if (temp < 0) {
- X temp = -temp; /* temp is abs value of input */
- X /* For a negative input, want temp2 = bitwise complement of abs(input) */
- X /* This code assumes we are on a two's complement machine */
- X temp2--;
- X }
- X
- X /* Find the number of bits needed for the magnitude of the coefficient */
- X nbits = 0;
- X while (temp) {
- X nbits++;
- X temp >>= 1;
- X }
- X
- X /* Emit the Huffman-coded symbol for the number of bits */
- X emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]);
- X
- X /* Emit that number of bits of the value, if positive, */
- X /* or the complement of its magnitude, if negative. */
- X if (nbits) /* emit_bits rejects calls with size 0 */
- X emit_bits((UINT16) temp2, nbits);
- X
- X /* Encode the AC coefficients per section F.1.2.2 */
- X
- X r = 0; /* r = run length of zeros */
- X
- X for (k = 1; k < DCTSIZE2; k++) {
- X if ((temp = block[k]) == 0) {
- X r++;
- X } else {
- X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
- X while (r > 15) {
- X emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]);
- X r -= 16;
- X }
- X
- X temp2 = temp;
- X if (temp < 0) {
- X temp = -temp; /* temp is abs value of input */
- X /* This code assumes we are on a two's complement machine */
- X temp2--;
- X }
- X
- X /* Find the number of bits needed for the magnitude of the coefficient */
- X nbits = 1; /* there must be at least one 1 bit */
- X while (temp >>= 1)
- X nbits++;
- X
- X /* Emit Huffman symbol for run length / number of bits */
- X i = (r << 4) + nbits;
- X emit_bits(actbl->ehufco[i], actbl->ehufsi[i]);
- X
- X /* Emit that number of bits of the value, if positive, */
- X /* or the complement of its magnitude, if negative. */
- X emit_bits((UINT16) temp2, nbits);
- X
- X r = 0;
- X }
- X }
- X
- X /* If the last coef(s) were zero, emit an end-of-block code */
- X if (r > 0)
- X emit_bits(actbl->ehufco[0], actbl->ehufsi[0]);
- X}
- X
- X
- X
- X/*
- X * Initialize for a Huffman-compressed scan.
- X * This is invoked after writing the SOS marker.
- X * The pipeline controller must establish the entropy_output method pointer
- X * before calling this routine.
- X */
- X
- XMETHODDEF void
- Xhuff_init (compress_info_ptr xinfo)
- X{
- X short ci;
- X jpeg_component_info * compptr;
- X
- X /* Initialize static variables */
- X cinfo = xinfo;
- X huff_put_buffer = 0;
- X huff_put_bits = 0;
- X
- X /* Initialize the output buffer */
- X output_buffer = (char *) (*cinfo->emethods->alloc_small)
- X ((size_t) JPEG_BUF_SIZE);
- X bytes_in_buffer = 0;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X /* Make sure requested tables are present */
- X if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
- X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
- X ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
- X /* Compute derived values for Huffman tables */
- X /* We may do this more than once for same table, but it's not a big deal */
- X fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
- X fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
- X /* Initialize DC predictions to 0 */
- X cinfo->last_dc_val[ci] = 0;
- X }
- X
- X /* Initialize restart stuff */
- X cinfo->restarts_to_go = cinfo->restart_interval;
- X cinfo->next_restart_num = 0;
- X}
- X
- X
- X/*
- X * Emit a restart marker & resynchronize predictions.
- X */
- X
- XLOCAL void
- Xemit_restart (compress_info_ptr cinfo)
- X{
- X short ci;
- X
- X flush_bits();
- X
- X emit_byte(0xFF);
- X emit_byte(RST0 + cinfo->next_restart_num);
- X
- X /* Re-initialize DC predictions to 0 */
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- X cinfo->last_dc_val[ci] = 0;
- X
- X /* Update restart state */
- X cinfo->restarts_to_go = cinfo->restart_interval;
- X cinfo->next_restart_num++;
- X cinfo->next_restart_num &= 7;
- X}
- X
- X
- X/*
- X * Encode and output one MCU's worth of Huffman-compressed coefficients.
- X */
- X
- XMETHODDEF void
- Xhuff_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
- X{
- X short blkn, ci;
- X jpeg_component_info * compptr;
- X JCOEF temp;
- X
- X /* Account for restart interval, emit restart marker if needed */
- X if (cinfo->restart_interval) {
- X if (cinfo->restarts_to_go == 0)
- X emit_restart(cinfo);
- X cinfo->restarts_to_go--;
- X }
- X
- X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- X ci = cinfo->MCU_membership[blkn];
- X compptr = cinfo->cur_comp_info[ci];
- X /* Convert DC value to difference, update last_dc_val */
- X temp = MCU_data[blkn][0];
- X MCU_data[blkn][0] -= cinfo->last_dc_val[ci];
- X cinfo->last_dc_val[ci] = temp;
- X encode_one_block(MCU_data[blkn],
- X cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
- X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
- X }
- X}
- X
- X
- X/*
- X * Finish up at the end of a Huffman-compressed scan.
- X */
- X
- XMETHODDEF void
- Xhuff_term (compress_info_ptr cinfo)
- X{
- X /* Flush out the last data */
- X flush_bits();
- X flush_bytes();
- X /* Release the I/O buffer */
- X (*cinfo->emethods->free_small) ((void *) output_buffer);
- X}
- X
- X
- X
- X
- X/*
- X * Huffman coding optimization.
- X *
- X * This actually is optimization, in the sense that we find the best possible
- X * Huffman table(s) for the given data. We first scan the supplied data and
- X * count the number of uses of each symbol that is to be Huffman-coded.
- X * (This process must agree with the code above.) Then we build an
- X * optimal Huffman coding tree for the observed counts.
- X */
- X
- X#ifdef ENTROPY_OPT_SUPPORTED
- X
- X
- X/* These are static so htest_one_block can find 'em */
- Xstatic long * dc_count_ptrs[NUM_HUFF_TBLS];
- Xstatic long * ac_count_ptrs[NUM_HUFF_TBLS];
- X
- X
- XLOCAL void
- Xgen_huff_coding (compress_info_ptr cinfo, HUFF_TBL *htbl, long freq[])
- X/* Generate the optimal coding for the given counts */
- X{
- X#define MAX_CLEN 32 /* assumed maximum initial code length */
- X UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
- X short codesize[257]; /* codesize[k] = code length of symbol k */
- X short others[257]; /* next symbol in current branch of tree */
- X int c1, c2;
- X int p, i, j;
- X long v;
- X
- X /* This algorithm is explained in section K.2 of the JPEG standard */
- X
- X MEMZERO((void *) bits, SIZEOF(bits));
- X MEMZERO((void *) codesize, SIZEOF(codesize));
- X for (i = 0; i < 257; i++)
- X others[i] = -1; /* init links to empty */
- X
- X freq[256] = 1; /* make sure there is a nonzero count */
- X /* including the pseudo-symbol 256 in the Huffman procedure guarantees
- X * that no real symbol is given code-value of all ones, because 256
- X * will be placed in the largest codeword category.
- X */
- X
- X /* Huffman's basic algorithm to assign optimal code lengths to symbols */
- X
- X for (;;) {
- X /* Find the smallest nonzero frequency, set c1 = its symbol */
- X /* In case of ties, take the larger symbol number */
- X c1 = -1;
- X v = 1000000000L;
- X for (i = 0; i <= 256; i++) {
- X if (freq[i] && freq[i] <= v) {
- X v = freq[i];
- X c1 = i;
- X }
- X }
- X
- X /* Find the next smallest nonzero frequency, set c2 = its symbol */
- X /* In case of ties, take the larger symbol number */
- X c2 = -1;
- X v = 1000000000L;
- X for (i = 0; i <= 256; i++) {
- X if (freq[i] && freq[i] <= v && i != c1) {
- X v = freq[i];
- X c2 = i;
- X }
- X }
- X
- X /* Done if we've merged everything into one frequency */
- X if (c2 < 0)
- X break;
- X
- X /* Else merge the two counts/trees */
- X freq[c1] += freq[c2];
- X freq[c2] = 0;
- X
- X /* Increment the codesize of everything in c1's tree branch */
- X codesize[c1]++;
- X while (others[c1] >= 0) {
- X c1 = others[c1];
- X codesize[c1]++;
- X }
- X
- X others[c1] = c2; /* chain c2 onto c1's tree branch */
- X
- X /* Increment the codesize of everything in c2's tree branch */
- X codesize[c2]++;
- X while (others[c2] >= 0) {
- X c2 = others[c2];
- X codesize[c2]++;
- X }
- X }
- X
- X /* Now count the number of symbols of each code length */
- X for (i = 0; i <= 256; i++) {
- X if (codesize[i]) {
- X /* The JPEG standard seems to think that this can't happen, */
- X /* but I'm paranoid... */
- X if (codesize[i] > MAX_CLEN)
- X ERREXIT(cinfo->emethods, "Huffman code size table overflow");
- X
- X bits[codesize[i]]++;
- X }
- X }
- X
- X /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
- X * Huffman procedure assigned any such lengths, we must adjust the coding.
- X * Here is what the JPEG spec says about how this next bit works:
- X * Since symbols are paired for the longest Huffman code, the symbols are
- X * removed from this length category two at a time. The prefix for the pair
- X * (which is one bit shorter) is allocated to one of the pair; then,
- X * skipping the BITS entry for that prefix length, a code word from the next
- X * shortest nonzero BITS entry is converted into a prefix for two code words
- X * one bit longer.
- X */
- X
- X for (i = MAX_CLEN; i > 16; i--) {
- X while (bits[i] > 0) {
- X j = i - 2; /* find length of new prefix to be used */
- X while (bits[j] == 0)
- X j--;
- X
- X bits[i] -= 2; /* remove two symbols */
- X bits[i-1]++; /* one goes in this length */
- X bits[j+1] += 2; /* two new symbols in this length */
- X bits[j]--; /* symbol of this length is now a prefix */
- X }
- X }
- X
- X /* Remove the count for the pseudo-symbol 256 from the largest codelength */
- X while (bits[i] == 0) /* find largest codelength still in use */
- X i--;
- X bits[i]--;
- X
- X /* Return final symbol counts (only for lengths 0..16) */
- X memcpy((void *) htbl->bits, (void *) bits, SIZEOF(htbl->bits));
- X
- X /* Return a list of the symbols sorted by code length */
- X /* It's not real clear to me why we don't need to consider the codelength
- X * changes made above, but the JPEG spec seems to think this works.
- X */
- X p = 0;
- X for (i = 1; i <= MAX_CLEN; i++) {
- X for (j = 0; j <= 255; j++) {
- X if (codesize[j] == i) {
- X htbl->huffval[p] = (UINT8) j;
- X p++;
- X }
- X }
- X }
- X}
- X
- X
- X/* Process a single block's worth of coefficients */
- X/* Note that the DC coefficient has already been converted to a difference */
- X
- XLOCAL void
- Xhtest_one_block (JBLOCK block, JCOEF block0,
- X long dc_counts[], long ac_counts[])
- X{
- X register INT32 temp;
- X register int nbits;
- X register int k, r;
- X
- X /* Encode the DC coefficient difference per section F.1.2.1 */
- X
- X /* Find the number of bits needed for the magnitude of the coefficient */
- X temp = block0;
- X if (temp < 0) temp = -temp;
- X
- X for (nbits = 0; temp; nbits++)
- X temp >>= 1;
- X
- X /* Count the Huffman symbol for the number of bits */
- X dc_counts[nbits]++;
- X
- X /* Encode the AC coefficients per section F.1.2.2 */
- X
- X r = 0; /* r = run length of zeros */
- X
- X for (k = 1; k < DCTSIZE2; k++) {
- X if ((temp = block[k]) == 0) {
- X r++;
- X } else {
- X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
- X while (r > 15) {
- X ac_counts[0xF0]++;
- X r -= 16;
- X }
- X
- X /* Find the number of bits needed for the magnitude of the coefficient */
- X if (temp < 0) temp = -temp;
- X
- X for (nbits = 0; temp; nbits++)
- X temp >>= 1;
- X
- X /* Count Huffman symbol for run length / number of bits */
- X ac_counts[(r << 4) + nbits]++;
- X
- X r = 0;
- X }
- X }
- X
- X /* If the last coef(s) were zero, emit an end-of-block code */
- X if (r > 0)
- X ac_counts[0]++;
- X}
- X
- X
- X
- X/*
- X * Trial-encode one MCU's worth of Huffman-compressed coefficients.
- X */
- X
- XLOCAL void
- Xhtest_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
- X{
- X short blkn, ci;
- X jpeg_component_info * compptr;
- X
- X /* Take care of restart intervals if needed */
- X if (cinfo->restart_interval) {
- X if (cinfo->restarts_to_go == 0) {
- X /* Re-initialize DC predictions to 0 */
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- X cinfo->last_dc_val[ci] = 0;
- X /* Update restart state */
- X cinfo->restarts_to_go = cinfo->restart_interval;
- X }
- X cinfo->restarts_to_go--;
- X }
- X
- X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- X ci = cinfo->MCU_membership[blkn];
- X compptr = cinfo->cur_comp_info[ci];
- X /* NB: unlike the real entropy encoder, we may not change the input data */
- X htest_one_block(MCU_data[blkn],
- X (JCOEF) (MCU_data[blkn][0] - cinfo->last_dc_val[ci]),
- X dc_count_ptrs[compptr->dc_tbl_no],
- X ac_count_ptrs[compptr->ac_tbl_no]);
- X cinfo->last_dc_val[ci] = MCU_data[blkn][0];
- X }
- X}
- X
- X
- X
- X/*
- X * Find the best coding parameters for a Huffman-coded scan.
- X * When called, the scan data has already been converted to a sequence of
- X * MCU groups of quantized coefficients, which are stored in a "big" array.
- X * The source_method knows how to iterate through that array.
- X * On return, the MCU data is unmodified, but the Huffman tables referenced
- X * by the scan components may have been altered.
- X */
- X
- XMETHODDEF void
- Xhuff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
- X/* Optimize Huffman-coding parameters (Huffman symbol table) */
- X{
- X int i, tbl;
- X HUFF_TBL **htblptr;
- X
- X /* Allocate and zero the count tables */
- X /* Note that gen_huff_coding expects 257 entries in each table! */
- X
- X for (i = 0; i < NUM_HUFF_TBLS; i++) {
- X dc_count_ptrs[i] = NULL;
- X ac_count_ptrs[i] = NULL;
- X }
- X
- X for (i = 0; i < cinfo->comps_in_scan; i++) {
- X /* Create DC table */
- X tbl = cinfo->cur_comp_info[i]->dc_tbl_no;
- X if (dc_count_ptrs[tbl] == NULL) {
- X dc_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
- X (257 * SIZEOF(long));
- X MEMZERO((void *) dc_count_ptrs[tbl], 257 * SIZEOF(long));
- X }
- X /* Create AC table */
- X tbl = cinfo->cur_comp_info[i]->ac_tbl_no;
- X if (ac_count_ptrs[tbl] == NULL) {
- X ac_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
- X (257 * SIZEOF(long));
- X MEMZERO((void *) ac_count_ptrs[tbl], 257 * SIZEOF(long));
- X }
- X }
- X
- X /* Initialize DC predictions to 0 */
- X for (i = 0; i < cinfo->comps_in_scan; i++) {
- X cinfo->last_dc_val[i] = 0;
- X }
- X /* Initialize restart stuff */
- X cinfo->restarts_to_go = cinfo->restart_interval;
- X
- X /* Scan the MCU data, count symbol uses */
- X (*source_method) (cinfo, htest_encode);
- X
- X /* Now generate optimal Huffman tables */
- X for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {
- X if (dc_count_ptrs[tbl] != NULL) {
- X htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
- X if (*htblptr == NULL)
- X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
- X /* Set sent_table FALSE so updated table will be written to JPEG file. */
- X (*htblptr)->sent_table = FALSE;
- X /* Compute the optimal Huffman encoding */
- X gen_huff_coding(cinfo, *htblptr, dc_count_ptrs[tbl]);
- X /* Release the count table */
- X (*cinfo->emethods->free_small) ((void *) dc_count_ptrs[tbl]);
- X }
- X if (ac_count_ptrs[tbl] != NULL) {
- X htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
- X if (*htblptr == NULL)
- X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
- X /* Set sent_table FALSE so updated table will be written to JPEG file. */
- X (*htblptr)->sent_table = FALSE;
- X /* Compute the optimal Huffman encoding */
- X gen_huff_coding(cinfo, *htblptr, ac_count_ptrs[tbl]);
- X /* Release the count table */
- X (*cinfo->emethods->free_small) ((void *) ac_count_ptrs[tbl]);
- X }
- X }
- X}
- X
- X
- X#endif /* ENTROPY_OPT_SUPPORTED */
- X
- X
- X/*
- X * The method selection routine for Huffman entropy encoding.
- X */
- X
- XGLOBAL void
- Xjselchuffman (compress_info_ptr cinfo)
- X{
- X if (! cinfo->arith_code) {
- X cinfo->methods->entropy_encoder_init = huff_init;
- X cinfo->methods->entropy_encode = huff_encode;
- X cinfo->methods->entropy_encoder_term = huff_term;
- X#ifdef ENTROPY_OPT_SUPPORTED
- X cinfo->methods->entropy_optimize = huff_optimize;
- X /* The standard Huffman tables are only valid for 8-bit data precision.
- X * If the precision is higher, force optimization on so that usable
- X * tables will be computed. This test can be removed if default tables
- X * are supplied that are valid for the desired precision.
- X */
- X if (cinfo->data_precision > 8)
- X cinfo->optimize_coding = TRUE;
- X if (cinfo->optimize_coding)
- X cinfo->total_passes++; /* one pass needed for entropy optimization */
- X#endif
- X }
- X}
- END_OF_FILE
- if test 20071 -ne `wc -c <'jchuff.c'`; then
- echo shar: \"'jchuff.c'\" unpacked with wrong size!
- fi
- # end of 'jchuff.c'
- fi
- if test -f 'jcmain.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jcmain.c'\"
- else
- echo shar: Extracting \"'jcmain.c'\" \(9991 characters\)
- sed "s/^X//" >'jcmain.c' <<'END_OF_FILE'
- X/*
- X * jcmain.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains a trivial test user interface for the JPEG compressor.
- X * It should work on any system with Unix- or MS-DOS-style command lines.
- X *
- X * Two different command line styles are permitted, depending on the
- X * compile-time switch TWO_FILE_COMMANDLINE:
- X * cjpeg [options] inputfile outputfile
- X * cjpeg [options] [inputfile]
- X * In the second style, output is always to standard output, which you'd
- X * normally redirect to a file or pipe to some other program. Input is
- X * either from a named file or from standard input (typically redirected).
- X * The second style is convenient on Unix but is unhelpful on systems that
- X * don't support pipes. Also, you MUST use the first style if your system
- X * doesn't do binary I/O to stdin/stdout.
- X */
- X
- X#include "jinclude.h"
- X#ifdef INCLUDES_ARE_ANSI
- X#include <stdlib.h> /* to declare exit() */
- X#endif
- X#ifdef NEED_SIGNAL_CATCHER
- X#include <signal.h> /* to declare signal() */
- X#endif
- X
- X#ifdef THINK_C
- X#include <console.h> /* command-line reader for Macintosh */
- X#endif
- X
- X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
- X#define READ_BINARY "r"
- X#define WRITE_BINARY "w"
- X#else
- X#define READ_BINARY "rb"
- X#define WRITE_BINARY "wb"
- X#endif
- X
- X#ifndef EXIT_FAILURE /* define exit() codes if not provided */
- X#define EXIT_FAILURE 1
- X#endif
- X#ifndef EXIT_SUCCESS
- X#ifdef VMS
- X#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
- X#else
- X#define EXIT_SUCCESS 0
- X#endif
- X#endif
- X
- X
- X#include "jversion.h" /* for version message */
- X
- X
- X/*
- X * PD version of getopt(3).
- X */
- X
- X#include "egetopt.c"
- X
- X
- X/*
- X * This routine determines what format the input file is,
- X * and selects the appropriate input-reading module.
- X *
- X * To determine which family of input formats the file belongs to,
- X * we may look only at the first byte of the file, since C does not
- X * guarantee that more than one character can be pushed back with ungetc.
- X * Looking at additional bytes would require one of these approaches:
- X * 1) assume we can fseek() the input file (fails for piped input);
- X * 2) assume we can push back more than one character (works in
- X * some C implementations, but unportable);
- X * 3) provide our own buffering as is done in djpeg (breaks input readers
- X * that want to use stdio directly, such as the RLE library);
- X * or 4) don't put back the data, and modify the input_init methods to assume
- X * they start reading after the start of file (also breaks RLE library).
- X * #1 is attractive for MS-DOS but is untenable on Unix.
- X *
- X * The most portable solution for file types that can't be identified by their
- X * first byte is to make the user tell us what they are. This is also the
- X * only approach for "raw" file types that contain only arbitrary values.
- X * We presently apply this method for Targa files. Most of the time Targa
- X * files start with 0x00, so we recognize that case. Potentially, however,
- X * a Targa file could start with any byte value (byte 0 is the length of the
- X * seldom-used ID field), so we accept a -T switch to force Targa input mode.
- X */
- X
- Xstatic boolean is_targa; /* records user -T switch */
- X
- X
- XLOCAL void
- Xselect_file_type (compress_info_ptr cinfo)
- X{
- X int c;
- X
- X if (is_targa) {
- X#ifdef TARGA_SUPPORTED
- X jselrtarga(cinfo);
- X#else
- X ERREXIT(cinfo->emethods, "Targa support was not compiled");
- X#endif
- X return;
- X }
- X
- X if ((c = getc(cinfo->input_file)) == EOF)
- X ERREXIT(cinfo->emethods, "Empty input file");
- X
- X switch (c) {
- X#ifdef GIF_SUPPORTED
- X case 'G':
- X jselrgif(cinfo);
- X break;
- X#endif
- X#ifdef PPM_SUPPORTED
- X case 'P':
- X jselrppm(cinfo);
- X break;
- X#endif
- X#ifdef RLE_SUPPORTED
- X case 'R':
- X jselrrle(cinfo);
- X break;
- X#endif
- X#ifdef TARGA_SUPPORTED
- X case 0x00:
- X jselrtarga(cinfo);
- X break;
- X#endif
- X default:
- X#ifdef TARGA_SUPPORTED
- X ERREXIT(cinfo->emethods, "Unrecognized input file format --- did you forget -T ?");
- X#else
- X ERREXIT(cinfo->emethods, "Unrecognized input file format");
- X#endif
- X break;
- X }
- X
- X if (ungetc(c, cinfo->input_file) == EOF)
- X ERREXIT(cinfo->emethods, "ungetc failed");
- X}
- X
- X
- X/*
- X * This routine gets control after the input file header has been read.
- X * It must determine what output JPEG file format is to be written,
- X * and make any other compression parameter changes that are desirable.
- X */
- X
- XMETHODDEF void
- Xc_ui_method_selection (compress_info_ptr cinfo)
- X{
- X /* If the input is gray scale, generate a monochrome JPEG file. */
- X if (cinfo->in_color_space == CS_GRAYSCALE)
- X j_monochrome_default(cinfo);
- X /* For now, always select JFIF output format. */
- X#ifdef JFIF_SUPPORTED
- X jselwjfif(cinfo);
- X#else
- X You shoulda defined JFIF_SUPPORTED. /* deliberate syntax error */
- X#endif
- X}
- X
- X
- X/*
- X * Signal catcher to ensure that temporary files are removed before aborting.
- X * NB: for Amiga Manx C this is actually a global routine named _abort();
- X * see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
- X */
- X
- X#ifdef NEED_SIGNAL_CATCHER
- X
- Xstatic external_methods_ptr emethods; /* for access to free_all */
- X
- XGLOBAL void
- Xsignal_catcher (int signum)
- X{
- X emethods->trace_level = 0; /* turn off trace output */
- X (*emethods->free_all) (); /* clean up memory allocation & temp files */
- X exit(EXIT_FAILURE);
- X}
- X
- X#endif
- X
- X
- XLOCAL void
- Xusage (char * progname)
- X/* complain about bad command line */
- X{
- X fprintf(stderr, "usage: %s ", progname);
- X fprintf(stderr, "[-Q quality 0..100] [-o] [-T] [-I] [-a] [-d] [-m mem]");
- X#ifdef TWO_FILE_COMMANDLINE
- X fprintf(stderr, " inputfile outputfile\n");
- X#else
- X fprintf(stderr, " [inputfile]\n");
- X#endif
- X exit(EXIT_FAILURE);
- X}
- X
- X
- X/*
- X * The main program.
- X */
- X
- XGLOBAL int
- Xmain (int argc, char **argv)
- X{
- X struct compress_info_struct cinfo;
- X struct compress_methods_struct c_methods;
- X struct external_methods_struct e_methods;
- X int c;
- X
- X /* On Mac, fetch a command line. */
- X#ifdef THINK_C
- X argc = ccommand(&argv);
- X#endif
- X
- X /* Initialize the system-dependent method pointers. */
- X cinfo.methods = &c_methods;
- X cinfo.emethods = &e_methods;
- X jselerror(&e_methods); /* error/trace message routines */
- X jselmemmgr(&e_methods); /* memory allocation routines */
- X c_methods.c_ui_method_selection = c_ui_method_selection;
- X
- X /* Now OK to enable signal catcher. */
- X#ifdef NEED_SIGNAL_CATCHER
- X emethods = &e_methods;
- X signal(SIGINT, signal_catcher);
- X#ifdef SIGTERM /* not all systems have SIGTERM */
- X signal(SIGTERM, signal_catcher);
- X#endif
- X#endif
- X
- X /* Set up default JPEG parameters. */
- X j_c_defaults(&cinfo, 75, FALSE); /* default quality level = 75 */
- X is_targa = FALSE;
- X
- X /* Scan command line options, adjust parameters */
- X
- X while ((c = egetopt(argc, argv, "IQ:Taom:d")) != EOF)
- X switch (c) {
- X case 'I': /* Create noninterleaved file. */
- X#ifdef MULTISCAN_FILES_SUPPORTED
- X cinfo.interleave = FALSE;
- X#else
- X fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
- X argv[0]);
- X exit(EXIT_FAILURE);
- X#endif
- X break;
- X case 'Q': /* Quality factor. */
- X { int val;
- X if (optarg == NULL)
- X usage(argv[0]);
- X if (sscanf(optarg, "%d", &val) != 1)
- X usage(argv[0]);
- X /* Note: for now, we make force_baseline FALSE.
- X * This means non-baseline JPEG files can be created with low Q values.
- X * To ensure only baseline files are generated, pass TRUE instead.
- X */
- X j_set_quality(&cinfo, val, FALSE);
- X }
- X break;
- X case 'T': /* Input file is Targa format. */
- X is_targa = TRUE;
- X break;
- X case 'a': /* Use arithmetic coding. */
- X#ifdef ARITH_CODING_SUPPORTED
- X cinfo.arith_code = TRUE;
- X#else
- X fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
- X argv[0]);
- X exit(EXIT_FAILURE);
- X#endif
- X break;
- X case 'o': /* Enable entropy parm optimization. */
- X#ifdef ENTROPY_OPT_SUPPORTED
- X cinfo.optimize_coding = TRUE;
- X#else
- X fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
- X argv[0]);
- X exit(EXIT_FAILURE);
- X#endif
- X break;
- X case 'm': /* Maximum memory in Kb (or Mb with 'm'). */
- X { long lval;
- X char ch = 'x';
- X
- X if (optarg == NULL)
- X usage(argv[0]);
- X if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
- X usage(argv[0]);
- X if (ch == 'm' || ch == 'M')
- X lval *= 1000L;
- X e_methods.max_memory_to_use = lval * 1000L;
- X }
- X break;
- X case 'd': /* Debugging. */
- X e_methods.trace_level++;
- X break;
- X case '?':
- X default:
- X usage(argv[0]);
- X break;
- X }
- X
- X /* If -d appeared, print version identification */
- X if (e_methods.trace_level > 0)
- X fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
- X JVERSION, JCOPYRIGHT);
- X
- X /* Select the input and output files */
- X
- X#ifdef TWO_FILE_COMMANDLINE
- X
- X if (optind != argc-2) {
- X fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
- X usage(argv[0]);
- X }
- X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
- X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
- X exit(EXIT_FAILURE);
- X }
- X if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
- X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
- X exit(EXIT_FAILURE);
- X }
- X
- X#else /* not TWO_FILE_COMMANDLINE -- use Unix style */
- X
- X cinfo.input_file = stdin; /* default input file */
- X cinfo.output_file = stdout; /* always the output file */
- X
- X if (optind < argc-1) {
- X fprintf(stderr, "%s: only one input file\n", argv[0]);
- X usage(argv[0]);
- X }
- X if (optind < argc) {
- X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
- X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
- X exit(EXIT_FAILURE);
- X }
- X }
- X
- X#endif /* TWO_FILE_COMMANDLINE */
- X
- X /* Figure out the input file format, and set up to read it. */
- X select_file_type(&cinfo);
- X
- X /* Do it to it! */
- X jpeg_compress(&cinfo);
- X
- X /* All done. */
- X exit(EXIT_SUCCESS);
- X return 0; /* suppress no-return-value warnings */
- X}
- END_OF_FILE
- if test 9991 -ne `wc -c <'jcmain.c'`; then
- echo shar: \"'jcmain.c'\" unpacked with wrong size!
- fi
- # end of 'jcmain.c'
- fi
- if test -f 'jrdgif.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jrdgif.c'\"
- else
- echo shar: Extracting \"'jrdgif.c'\" \(19830 characters\)
- sed "s/^X//" >'jrdgif.c' <<'END_OF_FILE'
- X/*
- X * jrdgif.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains routines to read input images in GIF format.
- X *
- X * These routines may need modification for non-Unix environments or
- X * specialized applications. As they stand, they assume input from
- X * an ordinary stdio stream. They further assume that reading begins
- X * at the start of the file; input_init may need work if the
- X * user interface has already read some data (e.g., to determine that
- X * the file is indeed GIF format).
- X *
- X * These routines are invoked via the methods get_input_row
- X * and input_init/term.
- X */
- X
- X/*
- X * This code is loosely based on giftoppm from the PBMPLUS distribution
- X * of Feb. 1991. That file contains the following copyright notice:
- X * +-------------------------------------------------------------------+
- X * | Copyright 1990, David Koblas. |
- X * | Permission to use, copy, modify, and distribute this software |
- X * | and its documentation for any purpose and without fee is hereby |
- X * | granted, provided that the above copyright notice appear in all |
- X * | copies and that both that copyright notice and this permission |
- X * | notice appear in supporting documentation. This software is |
- X * | provided "as is" without express or implied warranty. |
- X * +-------------------------------------------------------------------+
- X *
- X * We are also required to state that
- X * "The Graphics Interchange Format(c) is the Copyright property of
- X * CompuServe Incorporated. GIF(sm) is a Service Mark property of
- X * CompuServe Incorporated."
- X */
- X
- X#include "jinclude.h"
- X
- X#ifdef GIF_SUPPORTED
- X
- X
- X#define MAXCOLORMAPSIZE 256 /* max # of colors in a GIF colormap */
- X#define NUMCOLORS 3 /* # of colors */
- X#define CM_RED 0 /* color component numbers */
- X#define CM_GREEN 1
- X#define CM_BLUE 2
- X
- Xstatic JSAMPARRAY colormap; /* the colormap to use */
- X/* colormap[i][j] = value of i'th color component for pixel value j */
- X
- X#define MAX_LZW_BITS 12 /* maximum LZW code size */
- X#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
- X
- X/* Macros for extracting header data --- note we assume chars may be signed */
- X
- X#define LM_to_uint(a,b) ((((b)&0xFF) << 8) | ((a)&0xFF))
- X
- X#define BitSet(byte, bit) ((byte) & (bit))
- X#define INTERLACE 0x40 /* mask for bit signifying interlaced image */
- X#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
- X
- X#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
- X
- X/* Static vars for GetCode and LZWReadByte */
- X
- Xstatic char code_buf[256+4]; /* current input data block */
- Xstatic int last_byte; /* # of bytes in code_buf */
- Xstatic int last_bit; /* # of bits in code_buf */
- Xstatic int cur_bit; /* next bit index to read */
- Xstatic boolean out_of_blocks; /* TRUE if hit terminator data block */
- X
- Xstatic int input_code_size; /* codesize given in GIF file */
- Xstatic int clear_code,end_code; /* values for Clear and End codes */
- X
- Xstatic int code_size; /* current actual code size */
- Xstatic int limit_code; /* 2^code_size */
- Xstatic int max_code; /* first unused code value */
- Xstatic boolean first_time; /* flags first call to LZWReadByte */
- X
- X/* LZW decompression tables:
- X * symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
- X * symbol_tail[K] = suffix byte of any LZW symbol K (0..LZW_TABLE_SIZE-1)
- X * Note that entries 0..end_code of the above tables are not used,
- X * since those symbols represent raw bytes or special codes.
- X *
- X * The stack represents the not-yet-used expansion of the last LZW symbol.
- X * In the worst case, a symbol could expand to as many bytes as there are
- X * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
- X * (This is conservative since that number includes the raw-byte symbols.)
- X *
- X * The tables are allocated from FAR heap space since they would use up
- X * rather a lot of the near data space in a PC.
- X */
- X
- Xstatic UINT16 FAR *symbol_head; /* => table of prefix symbols */
- Xstatic UINT8 FAR *symbol_tail; /* => table of suffix bytes */
- Xstatic UINT8 FAR *symbol_stack; /* stack for symbol expansions */
- Xstatic UINT8 FAR *sp; /* stack pointer */
- X
- X/* Static state for interlaced image processing */
- X
- Xstatic boolean is_interlaced; /* TRUE if have interlaced image */
- Xstatic big_sarray_ptr interlaced_image; /* full image in interlaced order */
- Xstatic long cur_row_number; /* need to know actual row number */
- Xstatic long pass2_offset; /* # of pixel rows in pass 1 */
- Xstatic long pass3_offset; /* # of pixel rows in passes 1&2 */
- Xstatic long pass4_offset; /* # of pixel rows in passes 1,2,3 */
- X
- X
- X/* Forward declarations */
- XMETHODDEF void load_interlaced_image PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
- XMETHODDEF void get_interlaced_row PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
- X
- X
- X
- XLOCAL int
- XReadByte (compress_info_ptr cinfo)
- X/* Read next byte from GIF file */
- X{
- X register FILE * infile = cinfo->input_file;
- X int c;
- X
- X if ((c = getc(infile)) == EOF)
- X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
- X return c;
- X}
- X
- X
- XLOCAL int
- XGetDataBlock (compress_info_ptr cinfo, char *buf)
- X/* Read a GIF data block, which has a leading count byte */
- X/* A zero-length block marks the end of a data block sequence */
- X{
- X int count;
- X
- X count = ReadByte(cinfo);
- X if (count > 0) {
- X if (! ReadOK(cinfo->input_file, buf, count))
- X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
- X }
- X return count;
- X}
- X
- X
- XLOCAL void
- XSkipDataBlocks (compress_info_ptr cinfo)
- X/* Skip a series of data blocks, until a block terminator is found */
- X{
- X char buf[256];
- X
- X while (GetDataBlock(cinfo, buf) > 0)
- X /* skip */;
- X}
- X
- X
- XLOCAL void
- XReInitLZW (void)
- X/* (Re)initialize LZW state; shared code for startup and Clear processing */
- X{
- X code_size = input_code_size+1;
- X limit_code = clear_code << 1; /* 2^code_size */
- X max_code = clear_code + 2; /* first unused code value */
- X sp = symbol_stack; /* init stack to empty */
- X}
- X
- X
- XLOCAL void
- XInitLZWCode (void)
- X/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
- X{
- X /* GetCode initialization */
- X last_byte = 2; /* make safe to "recopy last two bytes" */
- X last_bit = 0; /* nothing in the buffer */
- X cur_bit = 0; /* force buffer load on first call */
- X out_of_blocks = FALSE;
- X
- X /* LZWReadByte initialization */
- X clear_code = 1 << input_code_size; /* compute special code values */
- X end_code = clear_code + 1; /* note that these do not change */
- X first_time = TRUE;
- X ReInitLZW();
- X}
- X
- X
- XLOCAL int
- XGetCode (compress_info_ptr cinfo)
- X/* Fetch the next code_size bits from the GIF data */
- X/* We assume code_size is less than 16 */
- X{
- X register INT32 accum;
- X int offs, ret, count;
- X
- X if ( (cur_bit+code_size) > last_bit) {
- X /* Time to reload the buffer */
- X if (out_of_blocks) {
- X TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
- X return end_code; /* fake something useful */
- X }
- X /* preserve last two bytes of what we have -- assume code_size <= 16 */
- X code_buf[0] = code_buf[last_byte-2];
- X code_buf[1] = code_buf[last_byte-1];
- X /* Load more bytes; set flag if we reach the terminator block */
- X if ((count = GetDataBlock(cinfo, &code_buf[2])) == 0) {
- X out_of_blocks = TRUE;
- X TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
- X return end_code; /* fake something useful */
- X }
- X /* Reset counters */
- X cur_bit = (cur_bit - last_bit) + 16;
- X last_byte = 2 + count;
- X last_bit = last_byte * 8;
- X }
- X
- X /* Form up next 24 bits in accum */
- X offs = cur_bit >> 3; /* byte containing cur_bit */
- X#ifdef CHAR_IS_UNSIGNED
- X accum = code_buf[offs+2];
- X accum <<= 8;
- X accum |= code_buf[offs+1];
- X accum <<= 8;
- X accum |= code_buf[offs];
- X#else
- X accum = code_buf[offs+2] & 0xFF;
- X accum <<= 8;
- X accum |= code_buf[offs+1] & 0xFF;
- X accum <<= 8;
- X accum |= code_buf[offs] & 0xFF;
- X#endif
- X
- X /* Right-align cur_bit in accum, then mask off desired number of bits */
- X accum >>= (cur_bit & 7);
- X ret = ((int) accum) & ((1 << code_size) - 1);
- X
- X cur_bit += code_size;
- X return ret;
- X}
- X
- X
- XLOCAL int
- XLZWReadByte (compress_info_ptr cinfo)
- X/* Read an LZW-compressed byte */
- X{
- X static int oldcode; /* previous LZW symbol */
- X static int firstcode; /* first byte of oldcode's expansion */
- X register int code; /* current working code */
- X int incode; /* saves actual input code */
- X
- X /* First time, just eat the expected Clear code(s) and return next code, */
- X /* which is assumed to be a raw byte. */
- X if (first_time) {
- X first_time = FALSE;
- X do {
- X code = GetCode(cinfo);
- X } while (code == clear_code);
- X firstcode = oldcode = code; /* make firstcode, oldcode valid! */
- X return code;
- X }
- X
- X /* If any codes are stacked from a previously read symbol, return them */
- X if (sp > symbol_stack)
- X return (int) *(--sp);
- X
- X code = GetCode(cinfo);
- X
- X if (code == clear_code) {
- X /* Reinit static state, swallow any extra Clear codes, and return */
- X ReInitLZW();
- X do {
- X code = GetCode(cinfo);
- X } while (code == clear_code);
- X firstcode = oldcode = code; /* gotta reinit these too */
- X return code;
- X }
- X
- X if (code == end_code) {
- X /* Skip the rest of the image, unless GetCode already read terminator */
- X if (! out_of_blocks)
- X SkipDataBlocks(cinfo);
- X return -1;
- X }
- X
- X /* Normal raw byte or LZW symbol */
- X incode = code; /* save for a moment */
- X
- X if (code >= max_code) { /* special case for not-yet-defined symbol */
- X *sp++ = (UINT8) firstcode; /* it will be defined as oldcode/firstcode */
- X code = oldcode;
- X }
- X
- X /* If it's a symbol, expand it into the stack */
- X while (code >= clear_code) {
- X *sp++ = symbol_tail[code]; /* tail of symbol: a simple byte value */
- X code = symbol_head[code]; /* head of symbol: another LZW symbol */
- X }
- X /* At this point code just represents a raw byte */
- X firstcode = code; /* save for possible future use */
- X
- X /* If there's room in table, */
- X if ((code = max_code) < LZW_TABLE_SIZE) {
- X /* Define a new symbol = prev sym + head of this sym's expansion */
- X symbol_head[code] = oldcode;
- X symbol_tail[code] = (UINT8) firstcode;
- X max_code++;
- X /* Is it time to increase code_size? */
- X if ((max_code >= limit_code) && (code_size < MAX_LZW_BITS)) {
- X code_size++;
- X limit_code <<= 1; /* keep equal to 2^code_size */
- X }
- X }
- X
- X oldcode = incode; /* save last input symbol for future use */
- X return firstcode; /* return first byte of symbol's expansion */
- X}
- X
- X
- XLOCAL void
- XReadColorMap (compress_info_ptr cinfo, int cmaplen, JSAMPARRAY cmap)
- X/* Read a GIF colormap */
- X{
- X int i;
- X
- X for (i = 0; i < cmaplen; i++) {
- X cmap[CM_RED][i] = (JSAMPLE) ReadByte(cinfo);
- X cmap[CM_GREEN][i] = (JSAMPLE) ReadByte(cinfo);
- X cmap[CM_BLUE][i] = (JSAMPLE) ReadByte(cinfo);
- X }
- X}
- X
- X
- XLOCAL void
- XDoExtension (compress_info_ptr cinfo)
- X/* Process an extension block */
- X/* Currently we ignore 'em all */
- X{
- X int extlabel;
- X
- X /* Read extension label byte */
- X extlabel = ReadByte(cinfo);
- X TRACEMS1(cinfo->emethods, 1, "Ignoring GIF extension block of type 0x%02x",
- X extlabel);
- X /* Skip the data block(s) associated with the extension */
- X SkipDataBlocks(cinfo);
- X}
- X
- X
- X/*
- X * Read the file header; return image size and component count.
- X */
- X
- XMETHODDEF void
- Xinput_init (compress_info_ptr cinfo)
- X{
- X char hdrbuf[10]; /* workspace for reading control blocks */
- X UINT16 width, height; /* image dimensions */
- X int colormaplen, aspectRatio;
- X int c;
- X
- X /* Allocate space to store the colormap */
- X colormap = (*cinfo->emethods->alloc_small_sarray)
- X ((long) MAXCOLORMAPSIZE, (long) NUMCOLORS);
- X
- X /* Read and verify GIF Header */
- X if (! ReadOK(cinfo->input_file, hdrbuf, 6))
- X ERREXIT(cinfo->emethods, "Not a GIF file");
- X if (strncmp(hdrbuf, "GIF", 3) != 0)
- X ERREXIT(cinfo->emethods, "Not a GIF file");
- X /* Check for expected version numbers.
- X * If unknown version, give warning and try to process anyway;
- X * this is per recommendation in GIF89a standard.
- X */
- X if ((strncmp(hdrbuf+3, "87a", 3) != 0) &&
- X (strncmp(hdrbuf+3, "89a", 3) != 0))
- X TRACEMS3(cinfo->emethods, 1,
- X "Warning: unexpected GIF version number '%c%c%c'",
- X hdrbuf[3], hdrbuf[4], hdrbuf[5]);
- X
- X /* Read and decipher Logical Screen Descriptor */
- X if (! ReadOK(cinfo->input_file, hdrbuf, 7))
- X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
- X width = LM_to_uint(hdrbuf[0],hdrbuf[1]);
- X height = LM_to_uint(hdrbuf[2],hdrbuf[3]);
- X colormaplen = 2 << (hdrbuf[4] & 0x07);
- X /* we ignore the color resolution, sort flag, and background color index */
- X aspectRatio = hdrbuf[6] & 0xFF;
- X if (aspectRatio != 0 && aspectRatio != 49)
- X TRACEMS(cinfo->emethods, 1, "Warning: nonsquare pixels in input");
- X
- X /* Read global colormap if header indicates it is present */
- X if (BitSet(hdrbuf[4], COLORMAPFLAG))
- X ReadColorMap(cinfo, colormaplen, colormap);
- X
- X /* Scan until we reach start of desired image.
- X * We don't currently support skipping images, but could add it easily.
- X */
- X for (;;) {
- X c = ReadByte(cinfo);
- X
- X if (c == ';') /* GIF terminator?? */
- X ERREXIT(cinfo->emethods, "Too few images in GIF file");
- X
- X if (c == '!') { /* Extension */
- X DoExtension(cinfo);
- X continue;
- X }
- X
- X if (c != ',') { /* Not an image separator? */
- X TRACEMS1(cinfo->emethods, 1, "Bogus input char 0x%02x, ignoring", c);
- X continue;
- X }
- X
- X /* Read and decipher Local Image Descriptor */
- X if (! ReadOK(cinfo->input_file, hdrbuf, 9))
- X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
- X /* we ignore top/left position info, also sort flag */
- X width = LM_to_uint(hdrbuf[4],hdrbuf[5]);
- X height = LM_to_uint(hdrbuf[6],hdrbuf[7]);
- X is_interlaced = BitSet(hdrbuf[8], INTERLACE);
- X colormaplen = 2 << (hdrbuf[8] & 0x07);
- X
- X /* Read local colormap if header indicates it is present */
- X /* Note: if we wanted to support skipping images, */
- X /* we'd need to skip rather than read colormap for ignored images */
- X if (BitSet(hdrbuf[8], COLORMAPFLAG))
- X ReadColorMap(cinfo, colormaplen, colormap);
- X
- X input_code_size = ReadByte(cinfo); /* get minimum-code-size byte */
- X if (input_code_size < 2 || input_code_size >= MAX_LZW_BITS)
- X ERREXIT1(cinfo->emethods, "Bogus codesize %d", input_code_size);
- X
- X /* Reached desired image, so break out of loop */
- X /* If we wanted to skip this image, */
- X /* we'd call SkipDataBlocks and then continue the loop */
- X break;
- X }
- X
- X /* Prepare to read selected image: first initialize LZW decompressor */
- X symbol_head = (UINT16 FAR *) (*cinfo->emethods->alloc_medium)
- X (LZW_TABLE_SIZE * SIZEOF(UINT16));
- X symbol_tail = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
- X (LZW_TABLE_SIZE * SIZEOF(UINT8));
- X symbol_stack = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
- X (LZW_TABLE_SIZE * SIZEOF(UINT8));
- X InitLZWCode();
- X
- X /*
- X * If image is interlaced, we read it into a full-size sample array,
- X * decompressing as we go; then get_input_row selects rows from the
- X * sample array in the proper order.
- X */
- X if (is_interlaced) {
- X /* We request the big array now, but can't access it until the pipeline
- X * controller causes all the big arrays to be allocated. Hence, the
- X * actual work of reading the image is postponed until the first call
- X * of get_input_row.
- X */
- X interlaced_image = (*cinfo->emethods->request_big_sarray)
- X ((long) width, (long) height, 1L);
- X cinfo->methods->get_input_row = load_interlaced_image;
- X cinfo->total_passes++; /* count file reading as separate pass */
- X }
- X
- X /* Return info about the image. */
- X cinfo->input_components = NUMCOLORS;
- X cinfo->in_color_space = CS_RGB;
- X cinfo->image_width = width;
- X cinfo->image_height = height;
- X cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
- X}
- X
- X
- X/*
- X * Read one row of pixels.
- X * This version is used for noninterlaced GIF images:
- X * we read directly from the GIF file.
- X */
- X
- XMETHODDEF void
- Xget_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
- X{
- X register JSAMPROW ptr0, ptr1, ptr2;
- X register long col;
- X register int c;
- X
- X ptr0 = pixel_row[0];
- X ptr1 = pixel_row[1];
- X ptr2 = pixel_row[2];
- X for (col = cinfo->image_width; col > 0; col--) {
- X if ((c = LZWReadByte(cinfo)) < 0)
- X ERREXIT(cinfo->emethods, "Premature end of GIF image");
- X *ptr0++ = colormap[CM_RED][c];
- X *ptr1++ = colormap[CM_GREEN][c];
- X *ptr2++ = colormap[CM_BLUE][c];
- X }
- X}
- X
- X
- X/*
- X * Read one row of pixels.
- X * This version is used for the first call on get_input_row when
- X * reading an interlaced GIF file: we read the whole image into memory.
- X */
- X
- XMETHODDEF void
- Xload_interlaced_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
- X{
- X JSAMPARRAY image_ptr;
- X register JSAMPROW sptr;
- X register long col;
- X register int c;
- X long row;
- X
- X /* Read the interlaced image into the big array we've created. */
- X for (row = 0; row < cinfo->image_height; row++) {
- X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
- X image_ptr = (*cinfo->emethods->access_big_sarray)
- X (interlaced_image, row, TRUE);
- X sptr = image_ptr[0];
- X for (col = cinfo->image_width; col > 0; col--) {
- X if ((c = LZWReadByte(cinfo)) < 0)
- X ERREXIT(cinfo->emethods, "Premature end of GIF image");
- X *sptr++ = (JSAMPLE) c;
- X }
- X }
- X cinfo->completed_passes++;
- X
- X /* Replace method pointer so subsequent calls don't come here. */
- X cinfo->methods->get_input_row = get_interlaced_row;
- X /* Initialize for get_interlaced_row, and perform first call on it. */
- X cur_row_number = 0;
- X pass2_offset = (cinfo->image_height + 7L) / 8L;
- X pass3_offset = pass2_offset + (cinfo->image_height + 3L) / 8L;
- X pass4_offset = pass3_offset + (cinfo->image_height + 1L) / 4L;
- X
- X get_interlaced_row(cinfo, pixel_row);
- X}
- X
- X
- X/*
- X * Read one row of pixels.
- X * This version is used for interlaced GIF images:
- X * we read from the big in-memory image.
- X */
- X
- XMETHODDEF void
- Xget_interlaced_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
- X{
- X JSAMPARRAY image_ptr;
- X register JSAMPROW sptr, ptr0, ptr1, ptr2;
- X register long col;
- X register int c;
- X long irow;
- X
- X /* Figure out which row of interlaced image is needed, and access it. */
- X switch ((int) (cur_row_number & 7L)) {
- X case 0: /* first-pass row */
- X irow = cur_row_number >> 3;
- X break;
- X case 4: /* second-pass row */
- X irow = (cur_row_number >> 3) + pass2_offset;
- X break;
- X case 2: /* third-pass row */
- X case 6:
- X irow = (cur_row_number >> 2) + pass3_offset;
- X break;
- X default: /* fourth-pass row */
- X irow = (cur_row_number >> 1) + pass4_offset;
- X break;
- X }
- X image_ptr = (*cinfo->emethods->access_big_sarray)
- X (interlaced_image, irow, FALSE);
- X /* Scan the row, expand colormap, and output */
- X sptr = image_ptr[0];
- X ptr0 = pixel_row[0];
- X ptr1 = pixel_row[1];
- X ptr2 = pixel_row[2];
- X for (col = cinfo->image_width; col > 0; col--) {
- X c = GETJSAMPLE(*sptr++);
- X *ptr0++ = colormap[CM_RED][c];
- X *ptr1++ = colormap[CM_GREEN][c];
- X *ptr2++ = colormap[CM_BLUE][c];
- X }
- X cur_row_number++; /* for next time */
- X}
- X
- X
- X/*
- X * Finish up at the end of the file.
- X */
- X
- XMETHODDEF void
- Xinput_term (compress_info_ptr cinfo)
- X{
- X /* no work (we let free_all release the workspace) */
- X}
- X
- X
- X/*
- X * The method selection routine for GIF format input.
- X * Note that this must be called by the user interface before calling
- X * jpeg_compress. If multiple input formats are supported, the
- X * user interface is responsible for discovering the file format and
- X * calling the appropriate method selection routine.
- X */
- X
- XGLOBAL void
- Xjselrgif (compress_info_ptr cinfo)
- X{
- X cinfo->methods->input_init = input_init;
- X cinfo->methods->get_input_row = get_input_row; /* assume uninterlaced */
- X cinfo->methods->input_term = input_term;
- X}
- X
- X#endif /* GIF_SUPPORTED */
- END_OF_FILE
- if test 19830 -ne `wc -c <'jrdgif.c'`; then
- echo shar: \"'jrdgif.c'\" unpacked with wrong size!
- fi
- # end of 'jrdgif.c'
- fi
- if test -f 'makljpeg.cf' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makljpeg.cf'\"
- else
- echo shar: Extracting \"'makljpeg.cf'\" \(439 characters\)
- sed "s/^X//" >'makljpeg.cf' <<'END_OF_FILE'
- Xjcmaster.mix,jcdeflts.mix,jcarith.mix,jccolor.mix,jcexpand.mix,jchuff.mix
- Xjcmcu.mix,jcpipe.mix,jcsample.mix,jfwddct.mix,jwrjfif.mix,jrdgif.mix
- Xjrdppm.mix,jrdrle.mix,jrdtarga.mix,jdmaster.mix,jddeflts.mix,jbsmooth.mix
- Xjdarith.mix,jdcolor.mix,jdhuff.mix,jdmcu.mix,jdpipe.mix,jdsample.mix
- Xjquant1.mix,jquant2.mix,jrevdct.mix,jrdjfif.mix,jwrgif.mix,jwrppm.mix
- Xjwrrle.mix,jwrtarga.mix,jutils.mix,jerror.mix,jmemmgr.mix,jmemsys.mix
- Xjmemdosa.mix
- END_OF_FILE
- if test 439 -ne `wc -c <'makljpeg.cf'`; then
- echo shar: \"'makljpeg.cf'\" unpacked with wrong size!
- fi
- # end of 'makljpeg.cf'
- fi
- echo shar: End of archive 11 \(of 18\).
- cp /dev/null ark11isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- exit 0 # Just in case...
-