📄 gui_gif.c
字号:
default:
return 1;
}
} while (Introducer != GIF_INTRO_TERMINATOR); /* We do not support more than one image, so stop when the first terminator has been read */
pInfo->NumImages = ImageCnt;
return 0;
}
/*********************************************************************
*
* _GetImageInfo
*/
static int _GetImageInfo(const U8 * pData, U32 NumBytes, GUI_GIF_IMAGE_INFO * pInfo, int Index) {
U8 Flags, Introducer;
int NumColors, ImageCnt;
/* Initialize decoding and get size and global color table */
if (_GetSizeAndColorTable(pData, NumBytes, NULL, NULL, &NumColors)) {
return 1; /* Error */
}
ImageCnt = 0;
/* Iterate over the blocks */
do {
Introducer = _ReadU8();
switch (Introducer) {
case GIF_INTRO_IMAGE:
if (Index == ImageCnt) {
pInfo->xPos = _ReadU16();
pInfo->xPos = _ReadU16();
pInfo->xSize = _ReadU16();
pInfo->ySize = _ReadU16();
return 0;
}
_SkipBytes(8); /* Skip the first 8 bytes of the image descriptor */
Flags = _ReadU8(); /* Only 'Flags' are intresting */
if (Flags & 0x80) {
_SkipBytes(NumColors * 3); /* Skip local color table */
}
_SkipBytes(1); /* Skip codesize */
while (_GetDataBlock(0) > 0); /* Skip data blocks */
ImageCnt++;
break;
case GIF_INTRO_TERMINATOR:
break;
case GIF_INTRO_EXTENSION:
if (_ReadExtension(NULL, (Index == ImageCnt) ? pInfo : NULL, NULL)) {
return 1;
}
break;
default:
return 1;
}
} while (Introducer != GIF_INTRO_TERMINATOR); /* We do not support more than one image, so stop when the first terminator has been read */
return 0;
}
/*********************************************************************
*
* _GetGIFComment
*
* Purpose:
* Returns the given comment of the GIF image.
*
* Parameters:
* pData - Pointer to start of the GIF file
* NumBytes - Number of bytes in the file
* pBuffer - Pointer to buffer to be filled by the routine
* MaxSize - Number of bytes in buffer
* Index - Index of the comment to be returned
*
* Return value:
* 0 on success, 1 on error
*/
static int _GetGIFComment(const U8 * pData, U32 NumBytes, U8 * pBuffer, int MaxSize, int Index) {
U8 Flags, Introducer;
int NumColors, CommentCnt, Size;
/* Initialize decoding and skip size and global color table */
if (_GetSizeAndColorTable(pData, NumBytes, NULL, NULL, &NumColors)) {
return 1; /* Error */
}
CommentCnt = Size = 0;
/* Iterate over the blocks */
do {
Introducer = _ReadU8();
switch (Introducer) {
case GIF_INTRO_IMAGE:
_SkipBytes(8); /* Skip the first 8 bytes of the image descriptor */
Flags = _ReadU8(); /* Only 'Flags' are intresting */
if (Flags & 0x80) {
_SkipBytes(NumColors * 3); /* Skip local color table */
}
_SkipBytes(1); /* Skip codesize */
while (_GetDataBlock(0) > 0); /* Skip data blocks */
break;
case GIF_INTRO_TERMINATOR:
break;
case GIF_INTRO_EXTENSION:
_ReadComment((Index == CommentCnt) ? pBuffer : NULL, MaxSize, &Size);
if ((Size) && (Index == CommentCnt)) {
return 0;
}
break;
default:
return 1;
}
} while (Introducer != GIF_INTRO_TERMINATOR); /* We do not support more than one image, so stop when the first terminator has been read */
return 1;
}
/*********************************************************************
*
* _ClearUnusedPixels
*
* Purpose:
* Clears the pixels between the border of the previous drawn image and
* the current image.
*/
static void _ClearUnusedPixels(int x0, int y0, IMAGE_DESCRIPTOR * pDescriptor, GUI_GIF_IMAGE_INFO * pInfo) {
LCD_SetColorIndex(LCD_GetBkColorIndex());
if (pDescriptor->YPos > pInfo->yPos) {
LCD_FillRect(x0 + pInfo->xPos,
y0 + pInfo->yPos,
x0 + pInfo->xPos + pInfo->xSize - 1,
y0 + pDescriptor->YPos - 1);
}
if (pDescriptor->XPos > pInfo->xPos) {
LCD_FillRect(x0 + pInfo->xPos,
y0 + pInfo->yPos,
x0 + pDescriptor->XPos - 1,
y0 + pInfo->yPos + pInfo->ySize - 1);
}
if ((pDescriptor->YPos + pDescriptor->YSize) < (pInfo->yPos + pInfo->ySize)) {
LCD_FillRect(x0 + pInfo->xPos,
y0 + pDescriptor->YPos + pDescriptor->YSize - 1,
x0 + pInfo->xPos + pInfo->xSize - 1,
y0 + pInfo->yPos + pInfo->ySize - 1);
}
if ((pDescriptor->XPos + pDescriptor->XSize) < (pInfo->xPos + pInfo->xSize)) {
LCD_FillRect(x0 + pDescriptor->XPos + pDescriptor->XSize - 1,
y0 + pInfo->yPos,
x0 + pInfo->xPos + pInfo->xSize - 1,
y0 + pInfo->yPos + pInfo->ySize - 1);
}
}
/*********************************************************************
*
* _DrawGIFImage
*
* Purpose:
* Draws the given sub image of a GIF file.
*
* Parameters:
* pData - Pointer to start of the GIF file
* NumBytes - Number of bytes in the file
* x0 - Drawing position x
* y0 - Drawing position y
* Index - Index of sub image to be drawn
*
* Return value:
* 0 on success, 1 on error
*/
static int _DrawGIFImage(const U8 * pData, U32 NumBytes, int x0, int y0, int Index) {
U8 Disposal;
int XSize, YSize, TransIndex, ImageCnt;
IMAGE_DESCRIPTOR Descriptor = {0};
GUI_GIF_IMAGE_INFO Info = {0};
U8 Introducer;
ImageCnt = 0;
TransIndex = -1;
/* Initialize decoding and get size and global color table */
if (_GetSizeAndColorTable(pData, NumBytes, &XSize, &YSize, &Descriptor.NumColors)) {
return 1; /* Error */
}
/* Iterate over the blocks */
do {
Introducer = _ReadU8();
switch (Introducer) {
case GIF_INTRO_IMAGE:
/* Read image descriptor */
Descriptor.XPos = _ReadU16();
Descriptor.YPos = _ReadU16();
Descriptor.XSize = _ReadU16();
Descriptor.YSize = _ReadU16();
Descriptor.Flags = _ReadU8 ();
if (_Source.RemBytes < 0) {
return 1; /* Error */
}
if (Descriptor.Flags & 0x80) {
/* Read local color table */
if (_ReadColorMap(Descriptor.NumColors)) {
return 1; /* Error */
}
}
if (ImageCnt == Index - 1) {
Info.xPos = Descriptor.XPos;
Info.yPos = Descriptor.YPos;
Info.xSize = Descriptor.XSize;
Info.ySize = Descriptor.YSize;
}
if (Index == ImageCnt) {
if (Disposal == 2) {
_ClearUnusedPixels(x0, y0, &Descriptor, &Info);
}
if (_DispGIFImage(&Descriptor, x0 + Descriptor.XPos, y0 + Descriptor.YPos, TransIndex, Disposal)) {
return 1; /* Error */
}
if (_ReadU8() != 0) {
return 1; /* Error */
}
return 0;
} else {
_ReadU8(); /* Skip codesize */
while (_GetDataBlock(0) > 0); /* Skip data blocks */
}
ImageCnt++;
break;
case GIF_INTRO_TERMINATOR:
break;
case GIF_INTRO_EXTENSION:
/* Read image extension */
if (_ReadExtension(&TransIndex, (Index == ImageCnt) ? &Info : NULL, (Index == ImageCnt) ? &Disposal : NULL)) {
return 1;
}
break;
default:
return 1;
}
} while (Introducer != GIF_INTRO_TERMINATOR); /* We do not support more than one image, so stop when the first terminator has been read */
return 0;
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_GIF_GetXSize
*
* Purpose:
* Returns the XSize of the given GIF image without further tests.
*/
int GUI_GIF_GetXSize(const void * pGIF) {
const U8 * pSrc;
if (!pGIF) {
return 0;
}
pSrc = (const U8 *)pGIF + 6;
return GUI__Read16(&pSrc);
}
/*********************************************************************
*
* GUI_GIF_GetYSize
*
* Purpose:
* Returns the YSize of the given GIF image without further tests.
*/
int GUI_GIF_GetYSize(const void * pGIF) {
const U8 * pSrc;
if (!pGIF) {
return 0;
}
pSrc = (const U8 *)pGIF + 8;
return GUI__Read16(&pSrc);
}
/*********************************************************************
*
* GUI_GIF_DrawEx
*/
int GUI_GIF_DrawEx(const void * pGIF, U32 NumBytes, int x0, int y0, int Index) {
const U8 * pSrc;
int Result, OldColorIndex;
#if (GUI_WINSUPPORT)
int Width, Height;
GUI_RECT r;
Width = GUI_GIF_GetXSize(pGIF);
Height = GUI_GIF_GetYSize(pGIF);
#endif
GUI_LOCK();
OldColorIndex = LCD_GetColorIndex();
pSrc = (const U8 *)pGIF;
#if (GUI_WINSUPPORT)
WM_ADDORG(x0,y0);
r.x1 = (r.x0 = x0) + Width - 1;
r.y1 = (r.y0 = y0) + Height - 1;
WM_ITERATE_START(&r) {
#endif
Result = _DrawGIFImage(pSrc, NumBytes, x0, y0, Index);
#if (GUI_WINSUPPORT)
} WM_ITERATE_END();
#endif
LCD_SetColorIndex(OldColorIndex);
GUI_UNLOCK();
return Result;
}
/*********************************************************************
*
* GUI_GIF_Draw
*/
int GUI_GIF_Draw(const void * pGIF, U32 NumBytes, int x0, int y0) {
return GUI_GIF_DrawEx(pGIF, NumBytes, x0, y0, 0);
}
/*********************************************************************
*
* GUI_GIF_GetInfo
*/
int GUI_GIF_GetInfo(const void * pGIF, U32 NumBytes, GUI_GIF_INFO * pInfo) {
const U8 * pSrc;
pSrc = (const U8 *)pGIF;
if (_GetGIFInfo(pSrc, NumBytes, pInfo)) {
return 1;
}
return 0;
}
/*********************************************************************
*
* GUI_GIF_GetImageInfo
*/
int GUI_GIF_GetImageInfo(const void * pGIF, U32 NumBytes, GUI_GIF_IMAGE_INFO * pInfo, int Index) {
const U8 * pSrc;
pSrc = (const U8 *)pGIF;
if (_GetImageInfo(pSrc, NumBytes, pInfo, Index)) {
return 1;
}
return 0;
}
/*********************************************************************
*
* GUI_GIF_GetComment
*/
int GUI_GIF_GetComment(const void * pGIF, U32 NumBytes, U8 * pBuffer, int MaxSize, int Index) {
const U8 * pSrc;
pSrc = (const U8 *)pGIF;
if (_GetGIFComment(pSrc, NumBytes, pBuffer, MaxSize, Index)) {
return 1;
}
return 0;
}
/*************************** End of file ****************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -