?? jrdgif.c
字號:
/*
* jrdgif.c
*
* 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.
*
* This file contains routines to read input images in GIF format.
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; input_init may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed GIF format).
*
* These routines are invoked via the methods get_input_row
* and input_init/term.
*/
/*
* This code is loosely based on giftoppm from the PBMPLUS distribution
* of Feb. 1991. That file contains the following copyright notice:
* +-------------------------------------------------------------------+
* | Copyright 1990, David Koblas. |
* | 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. |
* +-------------------------------------------------------------------+
*
* We are also required to state that
* "The Graphics Interchange Format(c) is the Copyright property of
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
* CompuServe Incorporated."
*/
/* This code was changed significantly to allow for the SWDS and host to
communicate. Christopher Chang, Summer 1993.
*/
#include "jinclude.h"
#ifdef GIF_SUPPORTED
#define MAXCOLORMAPSIZE 256 /* max # of colors in a GIF colormap */
#define NUMCOLORS 3 /* # of colors */
#define CM_RED 0 /* color component numbers */
#define CM_GREEN 1
#define CM_BLUE 2
static JSAMPARRAY colormap; /* the colormap to use */
/* colormap[i][j] = value of i'th color component for pixel value j */
#define MAX_LZW_BITS 12 /* maximum LZW code size */
#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
/* Macros for extracting header data --- note we assume chars may be signed */
#define LM_to_uint(a,b) ((((b)&0xFF) << 8) | ((a)&0xFF))
#define BitSet(byte, bit) ((byte) & (bit))
#define INTERLACE 0x40 /* mask for bit signifying interlaced image */
#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
#define ReadOK(file,buffer,len) (JFREAD(buffer,len) == ((size_t) (len)))
/* Static vars for GetCode and LZWReadByte */
static char code_buf[256+4]; /* current input data block */
static int last_byte; /* # of bytes in code_buf */
static int last_bit; /* # of bits in code_buf */
static int cur_bit; /* next bit index to read */
static boolean out_of_blocks; /* TRUE if hit terminator data block */
static int input_code_size; /* codesize given in GIF file */
static int clear_code,end_code; /* values for Clear and End codes */
static int code_size; /* current actual code size */
static int limit_code; /* 2^code_size */
static int max_code; /* first unused code value */
static boolean first_time; /* flags first call to LZWReadByte */
/* LZW decompression tables:
* symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
* symbol_tail[K] = suffix byte of any LZW symbol K (0..LZW_TABLE_SIZE-1)
* Note that entries 0..end_code of the above tables are not used,
* since those symbols represent raw bytes or special codes.
*
* The stack represents the not-yet-used expansion of the last LZW symbol.
* In the worst case, a symbol could expand to as many bytes as there are
* LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
* (This is conservative since that number includes the raw-byte symbols.)
*
* The tables are allocated from FAR heap space since they would use up
* rather a lot of the near data space in a PC.
*/
static UINT16 FAR *symbol_head; /* => table of prefix symbols */
static UINT8 FAR *symbol_tail; /* => table of suffix bytes */
static UINT8 FAR *symbol_stack; /* stack for symbol expansions */
static UINT8 FAR *sp; /* stack pointer */
/* Static state for interlaced image processing */
static boolean is_interlaced; /* TRUE if have interlaced image */
static big_sarray_ptr interlaced_image; /* full image in interlaced order */
static long cur_row_number; /* need to know actual row number */
static long pass2_offset; /* # of pixel rows in pass 1 */
static long pass3_offset; /* # of pixel rows in passes 1&2 */
static long pass4_offset; /* # of pixel rows in passes 1,2,3 */
/* Forward declarations */
METHODDEF void load_interlaced_image PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
METHODDEF void get_interlaced_row PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
LOCAL int
ReadByte (compress_info_ptr cinfo)
/* Read next byte from GIF file */
{
/*register FILE * infile = cinfo->input_file; */
int c;
send_command(SND); /* tells host to send data */
receive_command();
c = receive_data(); /* reads data from SWDS */
if (c == -1)
{
/* ERREXIT(cinfo->emethods, "Premature EOF in GIF file"); */
send_command(ERR1); /* eof error message */
exit();
}
return c;
}
LOCAL int
GetDataBlock (compress_info_ptr cinfo, char *buf)
/* Read a GIF data block, which has a leading count byte */
/* A zero-length block marks the end of a data block sequence */
{
int count;
count = ReadByte(cinfo);
if (count > 0) {
if (! ReadOK(cinfo->input_file, buf, count))
{
/* ERREXIT(cinfo->emethods, "Premature EOF in GIF file"); */
send_command(ERR1);
exit();
}
}
return count;
}
LOCAL void
SkipDataBlocks (compress_info_ptr cinfo)
/* Skip a series of data blocks, until a block terminator is found */
{
char buf[256];
while (GetDataBlock(cinfo, buf) > 0)
/* skip */;
}
LOCAL void
ReInitLZW (void)
/* (Re)initialize LZW state; shared code for startup and Clear processing */
{
code_size = input_code_size+1;
limit_code = clear_code << 1; /* 2^code_size */
max_code = clear_code + 2; /* first unused code value */
sp = symbol_stack; /* init stack to empty */
}
LOCAL void
InitLZWCode (void)
/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
{
/* GetCode initialization */
last_byte = 2; /* make safe to "recopy last two bytes" */
last_bit = 0; /* nothing in the buffer */
cur_bit = 0; /* force buffer load on first call */
out_of_blocks = FALSE;
/* LZWReadByte initialization */
clear_code = 1 << input_code_size; /* compute special code values */
end_code = clear_code + 1; /* note that these do not change */
first_time = TRUE;
ReInitLZW();
}
LOCAL int
GetCode (compress_info_ptr cinfo)
/* Fetch the next code_size bits from the GIF data */
/* We assume code_size is less than 16 */
{
register INT32 accum;
int offs, ret, count, tmp=code_size;
if ( (cur_bit+code_size) > last_bit) {
/* Time to reload the buffer */
if (out_of_blocks) {
/* WARNMS(cinfo->emethods, "Ran out of GIF bits"); */
send_command(ERR4); /* send error msg */
return end_code; /* fake something useful */
}
/* preserve last two bytes of what we have -- assume code_size <= 16 */
code_buf[0] = code_buf[last_byte-2];
code_buf[1] = code_buf[last_byte-1];
/* Load more bytes; set flag if we reach the terminator block */
if ((count = GetDataBlock(cinfo, &code_buf[2])) == 0) {
out_of_blocks = TRUE;
send_command(ERR4); /* send error msg */
/* WARNMS(cinfo->emethods, "Ran out of GIF bits"); */
return end_code; /* fake something useful */
}
/* Reset counters */
cur_bit = (cur_bit - last_bit) + 16;
last_byte = 2 + count;
last_bit = last_byte * 8;
}
/* Form up next 24 bits in accum */
offs = cur_bit >> 3; /* byte containing cur_bit */
#ifdef CHAR_IS_UNSIGNED
accum = code_buf[offs+2];
accum <<= 8;
accum |= code_buf[offs+1];
accum <<= 8;
accum |= code_buf[offs];
#else
accum = code_buf[offs+2] & 0xFF;
accum <<= 8;
accum |= code_buf[offs+1] & 0xFF;
accum <<= 8;
accum |= code_buf[offs] & 0xFF;
#endif
/* Right-align cur_bit in accum, then mask off desired number of bits */
accum >>= (cur_bit & 7);
/* ret = ((int) accum) & ((1 << tmp) - 1); */
ret = 1 << tmp;
ret = ret - 1;
ret &= (int) accum;
cur_bit += code_size;
return ret;
}
LOCAL int
LZWReadByte (compress_info_ptr cinfo)
/* Read an LZW-compressed byte */
{
static int oldcode; /* previous LZW symbol */
static int firstcode; /* first byte of oldcode's expansion */
register int code; /* current working code */
int incode; /* saves actual input code */
/* First time, just eat the expected Clear code(s) and return next code, */
/* which is expected to be a raw byte. */
if (first_time) {
first_time = FALSE;
code = clear_code; /* enables sharing code with Clear case */
} else {
/* If any codes are stacked from a previously read symbol, return them */
if (sp > symbol_stack)
return (int) *(--sp);
/* Time to read a new symbol */
code = GetCode(cinfo);
}
if (code == clear_code) {
/* Reinit static state, swallow any extra Clear codes, and */
/* return next code, which is expected to be a raw byte. */
ReInitLZW();
do {
code = GetCode(cinfo);
} while (code == clear_code);
if (code > clear_code) { /* make sure it is a raw byte */
send_command(ERR5); /* send error msg */
/* WARNMS(cinfo->emethods, "Corrupt data in GIF file"); */
code = 0; /* use something valid */
}
firstcode = oldcode = code; /* make firstcode, oldcode valid! */
return code;
}
if (code == end_code) {
/* Skip the rest of the image, unless GetCode already read terminator */
if (! out_of_blocks) {
SkipDataBlocks(cinfo);
out_of_blocks = TRUE;
}
/* Complain that there's not enough data */
send_command(ERR6); /* send error msg */
/* WARNMS(cinfo->emethods, "Premature end of GIF image"); */
/* Pad data with 0's */
return(0); /* fake something usable */
}
/* Got normal raw byte or LZW symbol */
incode = code; /* save for a moment */
if (code >= max_code) { /* special case for not-yet-defined symbol */
/* code == max_code is OK; anything bigger is bad data */
if (code > max_code) {
send_command(ERR5); /* send error msg */
/* WARNMS(cinfo->emethods, "Corrupt data in GIF file"); */
incode = 0; /* prevent creation of loops in symbol table */
}
*sp++ = (UINT8) firstcode; /* it will be defined as oldcode/firstcode */
code = oldcode;
}
/* If it's a symbol, expand it into the stack */
while (code >= clear_code) {
*sp++ = symbol_tail[code]; /* tail of symbol: a simple byte value */
code = symbol_head[code]; /* head of symbol: another LZW symbol */
}
/* At this point code just represents a raw byte */
firstcode = code; /* save for possible future use */
/* If there's room in table, */
if ((code = max_code) < LZW_TABLE_SIZE) {
/* Define a new symbol = prev sym + head of this sym's expansion */
symbol_head[code] = oldcode;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -