📄 gif_lzw.c
字号:
//----------------------------------------------------------------------
// File Name : giflzw.c
// Project : gsm_gprs
// Module :
// Memo :
// Author Date Description
// -----------------------------------------------
// dts 2004.3.10
//
//----------------------------------------------------------------------
#include "gif_error.h"
#include "gif_var_offset.h"
#include "gif_extension.h"
#include "gif_interface.h"
#include "gif_dither.h"
#ifdef GIF_SUPPORTED
//#define FLOAT_SURPORT
uchar* colormap; /* the colormap to use */
/* Static vars for GetCode and LZWReadByte */
static char* code_buf; /* 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 Bool* out_of_blocks; /* TRUE if hit terminator data block */
int *input_code_size; /* codesize given in GIF file */
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 uchar* first_time; /* flags first call to LZWReadByte */
int* width, *height,*log_width,*log_height;
/* 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 *symbol_stack; /* stack for symbol expansions */
static UINT8 FAR *sp; /* stack pointer */
Bool* zoomflag;
int* BgIndex;
int *width_record;
int *height_record;
/* Static state for interlaced image processing */
uchar* is_interlaced; /* TRUE if have interlaced image */
static uchar* Image;
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 */
decompress_info_ptr cinfo;
ulong* g_ZoomType;
extern NODE_TYPE* node;
ulong* g_workingIndex;
uchar* g_workingbuffer;
ulong* g_maxWorkingLen;
#define MAXWIDTH 1024
/* Forward declarations */
LOCAL void ReInitLZW (void);
#ifdef PCVER
FILE *FileError = NULL;
#endif
//====================================================================================
// Function Name: Bool InitWorkingBuf(GIFParameter* ucGifParameter)
// Purpose : initlize the global variable pointer
// Parameter :
// Return : sucessful return true otherwise return false
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
Bool InitWorkingBuf(GIFParameter* ucGifParameter)
{
uint point = 0;
char* pBuf;
if(ucGifParameter->ulMaxMemory<30)
{
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_MEMEOR_TOO_FEW,FileError);
#endif
return FALSE;
}
pBuf = ucGifParameter->ucWorkingBuf;
(char*)g_workingbuffer = pBuf +point;
point += 1;
(char*)clear_code = pBuf +point;
point += INTSIZE ;
(char*)end_code = pBuf +point;
point += INTSIZE ;
(char*)last_bit = pBuf +point;
point += INTSIZE ;
(char*)last_byte = pBuf +point;
point += INTSIZE ;
(char*)code_size = pBuf +point;
point += INTSIZE ;
(char*)cur_bit = pBuf +point;
point += INTSIZE ;
(char*)width = pBuf +point;
point += INTSIZE;
(char*)height = pBuf +point;
point += INTSIZE;
(char*)log_height = pBuf +point;
point += INTSIZE;
(char*)log_width = pBuf +point;
point += INTSIZE;
(char*)input_code_size = pBuf +point;
point += INTSIZE ;
(char*)limit_code = pBuf +point;
point += INTSIZE ;
(char*)max_code = pBuf +point;
point += INTSIZE ;
(char*)out_of_blocks = pBuf +point;
point += 1;
(char*)first_time = pBuf +point;
point += 1;
(char*)is_interlaced = pBuf +point;
point += 1;
(char*)zoomflag = pBuf +point;
point += 1;
(char*)pass3_offset = pBuf +point;
point += LONGSIZE ;
(char*)pass2_offset = pBuf +point;
point += LONGSIZE ;
(char*)pass4_offset = pBuf +point;
point += LONGSIZE ;
(char*)cur_row_number = pBuf +point;
point += LONGSIZE ;
(char*)g_ZoomType = pBuf +point;
point += LONGSIZE ;
(char*)code_buf = pBuf +point;
point += CODE_BUFFER_LEN ;
//START ALLOC symbol buffer//
(char*)symbol_head = pBuf +point;
point += SYMBOL_HEAD_LEN;
(char*)symbol_tail = pBuf +point;
point += SYMBOL_TAIL_LEN;
(char*)symbol_stack = pBuf +point;
point += SYMBOL_STACK_LEN ;
(char*)colormap = pBuf +point;
point += COLORMAP_LEN ;
(char*)g_workingIndex = pBuf +point;
point += LONGSIZE ;
(char*)BgIndex = pBuf +point;
point += INTSIZE ;
(char*)width_record = pBuf +point;
point += PICTURE_WIDTH_RECORD ;
(char*)height_record = pBuf +point;
point += PICTURE_HEIGHT_RECORD ;
//
(char*)(struct Compress_info_struct *)cinfo = pBuf +point;
point += sizeof(struct Decompress_info_struct);
//error stack
(char*)node = pBuf +point;
point += STACK_LEN;
(char*)g_maxWorkingLen = pBuf +point;
point += LONGSIZE;
if(point > ucGifParameter->ulMaxMemory*1024)
return FALSE;
g_workingbuffer = pBuf;
*g_workingIndex = point;
*g_maxWorkingLen = ucGifParameter->ulMaxMemory*1024;
return TRUE;
}
//====================================================================================
// Function Name: Bool gif_alloc_memr(len,char* buf)
// Purpose : malloc a block memeory
// Parameter :
// Return : sucessful return true otherwise return false
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
uchar* gif_alloc_buf(ulong MemorySize)
{
uchar* result;
result = g_workingbuffer + *g_workingIndex;
*g_workingIndex += MemorySize;
if(*g_workingIndex > *g_maxWorkingLen)
{
InsertError(ERROR_MEMEOR_TOO_FEW);
return NULL;
}
return result;
}
//====================================================================================
// Function Name: uchar** gif_alloc_memr(ulong width, ulong height)
// Purpose : alloc memory and return a block of width*height memory
// Parameter : width:the memory width ;height: the memory height
// Return :
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
uchar** gif_alloc_memr(ulong width, ulong height)
{
ulong index_width;
uchar** temp;
uchar** result;
temp =(uchar**) gif_alloc_buf (width*4);
result = temp;
if(result == NULL)
return NULL;
for(index_width = 0; index_width < width; index_width++)
{
result[index_width] = g_workingbuffer + *g_workingIndex;
*g_workingIndex += height;
}
if(*g_workingIndex > *g_maxWorkingLen)
{
InsertError(ERROR_MEMEOR_TOO_FEW);
return NULL;
}
return result;
}
//====================================================================================
// Function Name: void InitLZWCode (void)
// Purpose : initlize lzw code
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
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();
}
//====================================================================================
// Function Name: LOCAL int GetCode (compress_info_ptr cinfo)
// Purpose : Fetch the next code_size bits from the GIF data
// We assume code_size is less than 16
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
LOCAL int GetCode (decompress_info_ptr cinfo)
{
register INT32 accum;
int offs, ret, count;
if ( (*cur_bit+ *code_size) > *last_bit)
{
/* Time to reload the buffer */
if (*out_of_blocks)
{
#ifdef PCVER
WriteToErrorFile("GetCode",ERROR_RANGE_OUT_BIT,FileError);
#endif
InsertError(ERROR_RANGE_OUT_BIT);
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(&code_buf[2])) == 0)
{
*out_of_blocks = TRUE;
#ifdef PCVER
WriteToErrorFile("GetCode",ERROR_RANGE_OUT_BIT,FileError);
#endif
InsertError(ERROR_RANGE_OUT_BIT);
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 << *code_size) - 1);
*cur_bit += *code_size;
return ret;
}
//====================================================================================
// Function Name: int LZWReadByte (decompress_info_ptr cinfo)
// Purpose : Read an LZW-compressed byte
// Parameter :
// Return : none
// Remarks :
// Change Log :
// Author Date Description
// -----------------------------------------------
//=====================================================================================
int LZWReadByte (decompress_info_ptr cinfo)
{
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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -