📄 gif.cpp.svn-base
字号:
/***************************************************************************
*
* File Name giftobmp.cpp
*
* IMPORTANT NOTICE
*
* Please note that any and all title and/or intellectual property rights
* in and to this Software or any part of this (including without limitation
* any images, photographs, animations, video, audio, music, text and/or
* "applets," incorporated into the Software), herein mentioned to as
* "Software", the accompanying printed materials, and any copies of the
* Software, are owned by Jataayu Software Ltd., Bangalore ("Jataayu")
* or Jataayu's suppliers as the case may be. The Software is protected by
* copyright, including without limitation by applicable copyright laws,
* international treaty provisions, other intellectual property laws and
* applicable laws in the country in which the Software is being used.
* You shall not modify, adapt or translate the Software, without prior
* express written consent from Jataayu. You shall not reverse engineer,
* decompile, disassemble or otherwise alter the Software, except and
* only to the extent that such activity is expressly permitted by
* applicable law notwithstanding this limitation. Unauthorized reproduction
* or redistribution of this program or any portion of it may result in severe
* civil and criminal penalties and will be prosecuted to the maximum extent
* possible under the law. Jataayu reserves all rights not expressly granted.
*
* THIS SOFTWARE IS PROVIDED TO YOU "AS IS" WITHOUT WARRANTY OF ANY
* KIND AND ANY AND ALL REPRESENTATION AND WARRANTIES, EITHER EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY ACCURACY OF INFORMATIONAL CONTENT, AND/OR FITNESS
* FOR A PARTICULAR PURPOSE OR USE, TITLE OR INFRINGEMENT ARE EXPRESSLY
* DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. YOU ASSUME THE
* ENTIRE RISK AS TO THE ACCURACY AND THE USE OF THIS SOFTWARE. JATAAYU
* SHALL NOT BE LIABLE FOR ANY CONSEQUENTIAL, INCIDENTAL, INDIRECT,
* EXEMPLARY, SPECIAL OR PUNITIVE DAMAGES INCLUDING WITHOUT LIMITATION
* ANY LOSS OF DATA, OR; LOSS OF PROFIT, SAVINGS BUSINESS OR GOODWILL
* OR OTHER SIMILAR LOSS RESULTING FROM OR OUT OF THE USE OR INABILITY
* TO USE THIS SOFTWARE, EVEN IF JATAAYU HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE, OR FOR ANY CLAIM BY ANY THIRD PARTY.
***************************************************************************/
/***************************************************************************
* User Include Files
**************************************************************************/
#include "ddl.h"
#include "jcal.h"
#include "gif.h"
/***************************************************************************
* Macros
**************************************************************************/
#define GIF_DEFAULT_MIN_DELAY 60
#define GIF_LSCREEN_DESCRIPTOR 7
#define GIF_IMAGE_DISCRIPTOR 9
#define GIF_GRAPHICCTRL_EXT 5
#define LZW_BUFFER_SIZE (2 * 1024)
# define MAX_GIF_CODE_SIZE 4096
#ifdef MAX_VALUE
#undef MAX_VALUE
#endif
#define MAX_VALUE(a, b) ((a) > (b)? (a): (b))
#define MIN_VALUE(a, b) ((a) < (b)? (a): (b))
/***************************************************************************
* Local Function Prototypes
**************************************************************************/
typedef struct color
{
JC_UINT8 ucBlue;
JC_UINT8 ucGreen;
JC_UINT8 ucRed;
JC_UINT8 ucAlpha;
}ST_COLOR;
typedef struct gif_image_descriptor{
JC_UINT16 uhXPos;
JC_UINT16 uhYPos;
JC_UINT16 uhWidth;
JC_UINT16 uhHeight;
JC_UINT8 ucPackedFields;
}ST_GIF_IMAGE_DISCRIPTOR;
typedef struct gif_graphicctrl_ext
{
JC_UINT8 ucBlockSize;
JC_UINT8 ucPackedFields;
JC_UINT16 uhDelay;
JC_UINT8 ucTransparent;
}ST_GIF_GRAPHICCTRL_EXT;
typedef struct gif_logicalscreen_descriptor{
JC_UINT16 uhScreenWidth;
JC_UINT16 uhScreenHeight;
JC_UINT8 ucPackedFields;
JC_UINT8 ucBackground;
JC_UINT8 ucPixelAspectRatio;
}ST_GIF_LOGICALSCREEN_DESCRIPTOR;
typedef struct lzw_mgr
{
JDD_FILE vFilePointer ;
JC_UINT8* pucBuf;
JC_INT32 iCurFileOffset;
JC_INT32 iLeftOverBlockSize;
JC_INT32 iStartIndex;
}ST_LZW_MGR;
static JC_RETCODE GifGetLongEx(ST_LZW_MGR* pBufMgr, JC_INT32 iIndex, JC_INT32* pLong);
static JC_RETCODE GifLoadLZWBuffer(ST_LZW_MGR* pBufMgr, JC_INT32 iOffset);
static JC_INT32 GifFrameInit( ST_FRAME_ATTRIBUTE* pstFrameAttribute, JC_INT32 iWidth, JC_INT32 iHeight) ;
static JC_INT32 LZWDecoder (JDD_FILE vFilePtr, JC_INT8 *pucbufOut, JC_INT16 hInitCodeSize, JC_INT32 iAlignedWidth, JC_INT32 iWidth, JC_INT32 iHeight, const JC_INT32 iInterlace);
static JC_INT32 GifGetLong (JC_INT8 *pcbuf);
static JC_INT32 GifAddFrame (ST_GIF_ATTRIBUTE* pstGifAttribute, ST_FRAME_ATTRIBUTE* pstFrameAttribute);
static void GifConvertRGBtoRGBA(unsigned char* pRGB, unsigned char* pRGBA, JC_INT32 iNumColor);
/***************************************************************************
* All Local Function Definitions
**************************************************************************/
static JC_INT32 LZWDecoder (JDD_FILE vFilePtr/*JC_INT8 * pcBufIn*/, JC_INT8 * pcBufOut,
JC_INT16 hInitCodeSize, JC_INT32 iAlignedWidth,
JC_INT32 iWidth, JC_INT32 iHeight, const JC_INT32 iInterlace)
{
JC_INT32 iNum;
JC_INT32 iRow=0, iCol=0; /* used to point output if interlaced*/
JC_INT32 iPixels = 0, imaxPixels = 0; /* Output pixel counter*/
JC_INT16 hCodeSize = 0; /* Current hCodeSize (size in bits of codes)*/
JC_INT16 hClearCode = 0; /* Clear code : resets decompressor*/
JC_INT16 hEndCode = 0; /* End code : marks end of information*/
JC_INT32 iwhichBit = 0; /* Index of next bit in pcBufIn*/
JC_INT32 iLongCode = 0; /* Temp. var. from which hCode is retrieved*/
JC_INT16 hCode = 0; /* hCode extracted*/
JC_INT16 hPrevCode = 0; /* Previous hCode*/
JC_INT16 hOutCode = 0; /* hCode to output*/
JC_INT16 hTmpOutCode = 0 ;
/* Translation Table:*/
JC_INT16 *phPrefix = (JC_INT16 *)JC_NULL ; /* phPrefix: index of another hCode*/
JC_UINT8 *pucSuffix = (JC_UINT8*) JC_NULL ; /* pucSuffix: terminating character*/
JC_UINT8 *pucOutStack = (JC_UINT8*) JC_NULL ; /* Output buffer*/
JC_INT32 iPrefix_size = MAX_GIF_CODE_SIZE ;
JC_INT32 iSuffix_size = MAX_GIF_CODE_SIZE ;
JC_INT32 iOutstack_size = MAX_GIF_CODE_SIZE ;
JC_INT8 cError_flag = 0 ;
JC_INT16 hFirstEntry = 0;
JC_INT16 hNextEntry = 0;
JC_INT32 iOutIndex = 0;
JC_INT32 iRowOffset = 0;
JC_INT32 iPreOutIndex = 0 ;
JC_INT32 iLast_alloc = 0;
JC_INT32 iFlag = E_FALSE;
JC_INT32 iLpCount;
JC_INT32 iPass = 0 ;
ST_LZW_MGR stFileMgr;
jc_memset(&stFileMgr, 0x00, sizeof(ST_LZW_MGR));
stFileMgr.vFilePointer = vFilePtr;
phPrefix = (JC_INT16 *) jdd_MemAlloc (iPrefix_size, sizeof (JC_INT16)) ;
if (phPrefix == JC_NULL)
{
cError_flag = 1 ;
goto error ;
}
pucSuffix = (JC_UINT8 *) jdd_MemAlloc (iSuffix_size, sizeof (JC_INT8)) ;
if (pucSuffix == JC_NULL)
{
cError_flag = 1 ;
goto error ;
}
pucOutStack = (JC_UINT8 *) jdd_MemAlloc (iOutstack_size, sizeof (JC_INT8)) ;
if (pucOutStack == JC_NULL)
{
cError_flag = 1 ;
goto error ;
}
/* Set up values that depend on hInitCodeSize Parameter.*/
hCodeSize = hInitCodeSize+1;
hClearCode = (1 << hInitCodeSize);
hEndCode = hClearCode + 1;
hNextEntry = hFirstEntry = hClearCode + 2;
iwhichBit=0;
iPixels = 0;
imaxPixels = iWidth*iHeight;
iRowOffset =0;
while (iPixels<imaxPixels) {
iOutIndex = 0; /* Reset Output Stack*/
/** * GET NEXT CODE FROM pcBufIn:
* LZW compression uses code items longer than a single byte.
* For GIF Files, code sizes are variable between 9 and 12 bits
* That's why we must read data (hCode) this way:
* lLongCode = * ((long*)(pcBufIn+lwhichBit/8)) ; // Get some bytes from pcBufIn
* Read 4 bytes of data, extract variable bits of data
* iLongCode = Gif_GetLong (pcBufIn + iwhichBit / 8) ;**/
GifGetLongEx (&stFileMgr, iwhichBit / 8, &iLongCode) ;
iLongCode>>=(iwhichBit&7);
hCode = (JC_INT16)((iLongCode & ((1<<hCodeSize)-1))) ;
iwhichBit += hCodeSize; /* Increase Bit Offset*/
/* SWITCH, DIFFERENT POSIBILITIES FOR CODE:*/
if (hCode == hEndCode) /* END CODE*/
break; /* Exit LZW Decompression loop*/
if (hCode == hClearCode) { /* CLEAR CODE:*/
hCodeSize = hInitCodeSize+1; /* Reset hCodeSize*/
hNextEntry = hFirstEntry; /* Reset Translation Table*/
hPrevCode=hCode; /* Prevent next to be added to table.*/
continue; /* restart, to get another code*/
}
if (hCode <hNextEntry) /* CODE IS IN TABLE*/
hOutCode = hCode; /* Set code to output.*/
else {
/* CODE IS NOT IN TABLE:*/
pucOutStack[0] = pucOutStack[iPreOutIndex - 1] ;
iOutIndex++; /* Keep "first" character of previous output.*/
hOutCode = hPrevCode; /* Set hPrevCode to be output*/
}
/* EXPAND hOutCode IN pucOutStack
- Elements up to hFirstEntry are Raw-Codes and are not expanded
- Table Prefices contain indexes to other codes
- Table Suffices contain the raw codes to be output */
iLast_alloc = 0;
iLpCount = 0;
while (hOutCode >= hFirstEntry)
{
if (iOutIndex >= iOutstack_size)
{
JC_UINT8 *pucTmp_outstack = pucOutStack ;
pucOutStack = (JC_UINT8*) calloc (iOutstack_size + MAX_GIF_CODE_SIZE, sizeof (JC_UINT8)) ;
if (pucOutStack == JC_NULL)
{
cError_flag = 1 ;
goto error ;
}
jc_memcpy (pucOutStack, pucTmp_outstack, iOutstack_size) ;
iOutstack_size += MAX_GIF_CODE_SIZE ;
free (pucTmp_outstack) ;
}
pucOutStack[iOutIndex++] = pucSuffix[hOutCode]; // Add suffix to Output Stack
hTmpOutCode = hOutCode ;
hOutCode = phPrefix[hOutCode]; // Loop with preffix
if(hTmpOutCode < hOutCode)
{
hOutCode = hFirstEntry ;
}
/*the compressed might be corrupted
* Avoid the possibility of overflow on 'pcBufOut'.*/
if (iPixels + iOutIndex > imaxPixels)
{
break ;
}
}
/* NOW hOutCode IS A RAW CODE, ADD IT TO OUTPUT STACK.*/
if (iOutIndex >= iOutstack_size)
{
JC_UINT8 *pucTmp_outstack = pucOutStack ;
pucOutStack = (JC_UINT8 *) calloc (iOutstack_size + MAX_GIF_CODE_SIZE, sizeof (JC_INT8)) ;
if (pucOutStack == JC_NULL)
{
free(pucTmp_outstack);
cError_flag = 1 ;
goto error ;
}
jc_memcpy (pucOutStack, pucTmp_outstack, iOutstack_size) ;
jdd_MemFree(pucTmp_outstack);
iOutstack_size += MAX_GIF_CODE_SIZE ;
}
pucOutStack[iOutIndex++] = (JC_UINT8) hOutCode;
/* ADD NEW ENTRY TO TABLE (hPrevCode + hOutCode)
(EXCEPT IF PREVIOUS CODE WAS A CLEARCODE)*/
if (hPrevCode!=hClearCode) {
phPrefix[hNextEntry] = hPrevCode;
pucSuffix[hNextEntry] = (JC_UINT8) hOutCode;
hNextEntry++;
/* Prevent Translation table overflow:*/
if (hNextEntry >= iSuffix_size)
{
JC_INT16 *phTmp_prefix = phPrefix ;
JC_UINT8 *pucTmp_suffix = pucSuffix ;
phPrefix = (JC_INT16 *) calloc (iPrefix_size + MAX_GIF_CODE_SIZE, sizeof (JC_INT16)) ;
if (phPrefix == JC_NULL)
{
cError_flag = 1 ;
if(pucTmp_suffix)
free(pucTmp_suffix);
if(phTmp_prefix)
free(phTmp_prefix);
goto error ;
}
jc_memcpy (phPrefix, phTmp_prefix, iPrefix_size * sizeof (JC_INT16)) ;
iPrefix_size += MAX_GIF_CODE_SIZE ;
pucSuffix = (JC_UINT8 *) calloc (iSuffix_size + MAX_GIF_CODE_SIZE, sizeof (JC_INT8)) ;
if (pucSuffix == JC_NULL)
{
cError_flag = 1 ;
if(pucTmp_suffix)
{
free(pucTmp_suffix);
}
if(phTmp_prefix)
{
free(phTmp_prefix);
}
goto error ;
}
jc_memcpy (pucSuffix, pucTmp_suffix, iSuffix_size) ;
iSuffix_size += MAX_GIF_CODE_SIZE ;
jdd_MemFree(phTmp_prefix) ;
jdd_MemFree(pucTmp_suffix) ;
}
if (hNextEntry >= (1<<hCodeSize)) {
if (hCodeSize < 12) hCodeSize++;
else {}
}
}
hPrevCode = hCode;
/* Avoid the possibility of overflow on 'pcBufOut'.*/
if (iPixels + iOutIndex > imaxPixels) iOutIndex = imaxPixels-iPixels;
iPreOutIndex = iOutIndex ;
/* OUTPUT pucOutStack (LAST-IN FIRST-OUT ORDER)*/
for (iNum=iOutIndex-1; iNum>=0; iNum--) {
if (iCol == iWidth)
{
if (iInterlace) {
switch (iPass)
{
case 0:
case 1:
iRow = iRow + 8 ;
break ;
case 2:
iRow = iRow + 4 ;
break ;
case 3:
iRow = iRow + 2 ;
break ;
}
while (iPass < 4 && iRow >= iHeight)
{
char a[3] = { 4, 2 , 1 } ;
iPass++ ;
iRow = a[iPass - 1];
}
if(iPass == 4)
break ;
}
else
iRow++;
iRowOffset=iRow * iAlignedWidth;
iCol=0;
}
JC_INT32 iiiii;
unsigned lenn = iRowOffset + iCol;
unsigned limit = iAlignedWidth * iHeight;
if (lenn >= limit)
{
iiiii = 0;
}
pcBufOut[lenn] = pucOutStack[iNum];
iCol++; iPixels++;
}
} /* while (main decompressor loop)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -