📄 gif_lzw.c
字号:
else
{
ucGifParameter->uReInfor->ucVersion = VERSION89;
}
/* Read and decipher Logical Screen Descriptor */
if( !readFromBuffer(7 , hdrbuf))
{
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_LOGICAL_SCREEN_DESCRIPTOR,FileError);
#endif
InsertError(ERROR_LOGICAL_SCREEN_DESCRIPTOR);
return FALSE;
}
*log_width = LM_to_uint(hdrbuf[0],hdrbuf[1]);
*log_height = LM_to_uint(hdrbuf[2],hdrbuf[3]);
ucGifParameter->uReInfor->usSorImageHigh = *log_height;
ucGifParameter->uReInfor->usSorImageWidth = *log_width;
colorResolution = hdrbuf[4] & 0x07;
colormaplen = 2 << (colorResolution);
if( (colorResolution + 1) > ucGifParameter->ucOutColorResolution )
{
cinfo->quantize_colors = TRUE;
}
else
{
if(ucGifParameter->ucDitherMethod != GIF_NONE_DITHER)
cinfo->quantize_colors = TRUE;
}
/* Read global colormap if header indicates it is present */
/* we ignore the color resolution, sort flag, and background color index */
aspectRatio = hdrbuf[6] & 0xFF;
if (aspectRatio != 0 && aspectRatio != 49)
{
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_NONSQUARE_PIXELS,FileError);
#endif
InsertError(ERROR_NONSQUARE_PIXELS);
}
if (BitSet(hdrbuf[4], COLORMAPFLAG))
{
if(!ReadColorMap(cinfo, colormaplen, colormap))
{
InsertError(ERROR_READ_BYTE_ERROR);
return FALSE;
}
}
c = ReadByte();
if((c != ';') && (c != '!') && (c != ','))
{
return FALSE;
}
SetBufferCur( GetDataBufferCur() - 1);
if(ucGifParameter->ucGetFileHeader == TRUE)
{
//start calculate the count of picture
PictureCount = 0;
for(;;)
{
c = ReadByte();
if( (c !=';')&& (c!= '!') && (c != ','))
{
InsertError(ERROR_FILE_DATA_ERROR);
return FALSE;
}
if(c == EOF)
{
return FALSE;
}
if (c == ';')
{
break;
}
if (c == '!')
{ /* Extension */
c = ReadByte();
if(c == COMMENT_EXTENSION)
{
if(ucGifParameter->ucCommentFlag != GIF_NO_COMMENT)
{
if(CommentCount == ucGifParameter->ucCommentFlag)
{
c = ReadByte();
if(c == 0)
continue;
if (c > ucGifParameter->ulCommentBufLen )
{
readFromBuffer(ucGifParameter->ulCommentBufLen ,ucGifParameter->uReInfor->ucCommentBuf);
SetBufferCur(GetDataBufferCur() + c - ucGifParameter->ulCommentBufLen);
ucGifParameter->uReInfor->ulCommentBufLen = ucGifParameter->ulCommentBufLen;
SkipDataBlocks ();
}
else
{
ucGifParameter->uReInfor->ulCommentBufLen = c;
readFromBuffer(c,ucGifParameter->uReInfor->ucCommentBuf);
SkipDataBlocks ();
//we only get the frist block of comment
}
}
else
{
CommentCount++;
SkipDataBlocks ();
}
}else
{
SkipDataBlocks ();
}
}
else
{
if(c == EOF)
{
return FALSE;
}
SkipDataBlocks();
}
continue;
}
if (c == ',')
{
PictureCount++;
if(! skipFrame())
{
return FALSE;
}
}
}
ucGifParameter->uReInfor->ucImageSum = (uchar)PictureCount;
return TRUE;
}
//start decide whether zoom
/* Scan until we reach start of desired image.
* We don't currently support skipping images, but could add it easily.
*/
//image index in gif buffer
playback = ucGifParameter->ucPlayback;
if( playback < 0)
{
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_IMAGE_NUMBER_ERROR,FileError);
#endif
InsertError(ERROR_IMAGE_NUMBER_ERROR);
return FALSE;
}
PictureCount = 0;
for (;;)
{
c = ReadByte();
if( (c !=';')&& (c!= '!') && (c != ','))
return FALSE;
if(c == EOF)
{
return FALSE;
}
if (c == ';') /* GIF terminator?? */
{
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_IMAGE_NUMBER_FEW,FileError);
#endif
InsertError(ERROR_IMAGE_NUMBER_FEW);
return FALSE;
}
if (c == '!')
{ /* Extension */
if(!DoExtension(ucGifParameter))
{
InsertError(ERROR_READ_BYTE_ERROR);
return FALSE;
}
continue;
}
if (c != ',')
{ /* Not an image separator? */
continue;
}
else
{
if( PictureCount != playback )
{
//readFromBuffer( 9,hdrbuf );
if(!skipFrame())
{
InsertError(ERROR_READ_BYTE_ERROR);
return FALSE;
}
PictureCount ++;
continue;
}
//else start decode the image//
}
/* Read and decipher Local Image Descriptor */
if (! readFromBuffer( 9,hdrbuf ))
{
InsertError(ERROR_LOCAL_IMAGE_DESCRIPTOR);
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_LOCAL_IMAGE_DESCRIPTOR,FileError);
#endif
return FALSE;
}
/* we ignore top/left position info, also sort flag */
*width = LM_to_uint(hdrbuf[4],hdrbuf[5]);
*height = LM_to_uint(hdrbuf[6],hdrbuf[7]);
if((*width > MAXWIDTH)||(*height > MAXHEIGHT))
{
InsertError(ERROR_SIZE_OVERTOP);
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_SIZE_OVERTOP,FileError);
#endif
return FALSE;
}
ucGifParameter->uReInfor->usXPOS = LM_to_uint( hdrbuf[0], hdrbuf[1] );
ucGifParameter->uReInfor->usYPOS = LM_to_uint( hdrbuf[2], hdrbuf[3] );
ZoomSize = ucGifParameter->ucScale & 0xffff;
if( *g_ZoomType == IMAGE_GEOMETRY_NO_INTERPOLATE )
{
if((ZoomSize & 0xff )!= ((ZoomSize & 0xff00)>> 8))
{
*zoomflag = TRUE;
memset(width_record, 0, 4096);
memset(height_record,0 , 4096);
switch(((ZoomSize & 0xff00)>> 8))
{
case 1:
scale_width = *width;
scale_height = *height;
break;
case 2:
scale_width =(*width)/2;
scale_height = (*height)/2 ;
ucGifParameter->uReInfor->usXPOS = (ucGifParameter->uReInfor->usXPOS)/2;
ucGifParameter->uReInfor->usYPOS = (ucGifParameter->uReInfor->usYPOS)/2;
break;
case 4:
scale_width =(*width)/4;
scale_height = (*height)/4 ;
ucGifParameter->uReInfor->usXPOS = ucGifParameter->uReInfor->usXPOS/4;
ucGifParameter->uReInfor->usYPOS = ucGifParameter->uReInfor->usYPOS/4;
break;
case 8:
scale_width =(*width)/8;
scale_height = (*height)/8 ;
ucGifParameter->uReInfor->usXPOS = ucGifParameter->uReInfor->usXPOS/8;
ucGifParameter->uReInfor->usYPOS = ucGifParameter->uReInfor->usYPOS/8;
break;
case 16:
scale_width =(*width)/16;
scale_height = (*height)/16 ;
ucGifParameter->uReInfor->usXPOS = ucGifParameter->uReInfor->usXPOS/16;
ucGifParameter->uReInfor->usYPOS = ucGifParameter->uReInfor->usYPOS/16;
break;
case 32:
scale_width =(*width)/32;
scale_height = (*height)/32 ;
ucGifParameter->uReInfor->usXPOS = ucGifParameter->uReInfor->usXPOS/32;
ucGifParameter->uReInfor->usYPOS = ucGifParameter->uReInfor->usYPOS/32;
break;
default:
scale_width = *width;
scale_height = *height;
break;
}
StrechPixels((*width), scale_width , width_record);
StrechPixels((*height), scale_height , height_record);
cinfo->image_height = scale_height;
cinfo->image_width = scale_width;
cinfo->output_height = scale_height;
cinfo->output_width = scale_width;
}
else
{
cinfo->image_height = *height;
cinfo->image_width = *width;
cinfo->output_height = *height;
cinfo->output_width = *width;
}
}else
{
cinfo->image_height = *height;
cinfo->image_width = *width;
cinfo->output_height = *height;
cinfo->output_width = *width;
}
if( (cinfo->image_height == 0 ) ||( cinfo->image_width == 0))
{
InsertError( ERROR_ZOOM_OVERTOP );
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_ZOOM_OVERTOP, FileError);
#endif
return FALSE;
}
*is_interlaced = BitSet(hdrbuf[8], INTERLACE);
/* Read local colormap if header indicates it is present */
/* Note: if we wanted to support skipping images, */
/* we'd need to skip rather than read colormap for ignored images */
if (BitSet(hdrbuf[8], COLORMAPFLAG))
{
colormaplen = 2 << (hdrbuf[8] & 0x07);
if(!ReadColorMap(cinfo, colormaplen, colormap))
{
InsertError(ERROR_READ_BYTE_ERROR);
return FALSE;
}
}
*input_code_size = ReadByte(); /* get minimum-code-size byte */
if (*input_code_size < 2 || *input_code_size >= MAX_LZW_BITS)
{
InsertError( ERROR_BOGUS_CODE_SIZE );
#ifdef PCVER
WriteToErrorFile("input_init",ERROR_BOGUS_CODE_SIZE,FileError);
#endif
return FALSE;
}
/* Reached desired image, so break out of loop */
/* If we wanted to skip this image, */
/* we'd call SkipDataBlocks and then continue the loop */
break;
}
ucGifParameter->uReInfor->ucSorColorResolution = TWENTY_FOUR_BIT_COLOR;
ucGifParameter->uReInfor->ulDataOutBufLen = NUMCOLORS * cinfo->image_height * cinfo->image_width;
InitLZWCode();
return TRUE;
}
//only for test//
#ifdef PCVER
void openErrorFile()
{
FileError = fopen("c:\\error.bin","wb");
}
void WriteToErrorFile(const char* ErrorFunc,ulong ErrorCode, FILE* f)
{
fwrite((uchar*)(&ErrorCode),1, 4,f);
}
void closeFile()
{
fclose(FileError);
}
#endif
//
#endif /* GIF_SUPPORTED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -