📄 bmp.cpp.svn-base
字号:
/***************************************************************************
*
* File Name bmp.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"
#include "bmp.h"
/***************************************************************************
* Macros
**************************************************************************/
#define MAX(a, b) ((a) >= b?(a):(b))
#define MIN(a, b) ((a) <= b?(a):(b))
#define BMP_DEFAULT_PALETTECOUNT 256
#define BMP_FILEINFOHEADER 40
#define BMP_FILEHEADER 14
/***************************************************************************
* Local Function Prototypes
**************************************************************************/
typedef struct stRgba
{
JC_UINT8 ucR;
JC_UINT8 ucG;
JC_UINT8 ucB;
JC_UINT8 ucA;
}ST_RGBA;
static JC_RETCODE BmpFillBitmapFileHeader(ST_BMPFILEHEADER* pBitmapFileHeader, JC_INT32 iBitsPerPixel, ST_GIF_ATTRIBUTE* pstGifAttribute, JC_INT32 iFrame);
static JC_RETCODE BmpFillBitmapInfoHeader(ST_BMPINFOHEADER* pBitmapInfoHeader, JC_INT32 iBitsPerPixel, ST_GIF_ATTRIBUTE* pstGifAttribute, JC_INT32 iFrame);
static void BmpWriteBitmapFileHeader(ST_BMPFILEHEADER* pBitmapFileHeader, JDD_FILE pszOutBmpFile);
static JC_RETCODE BmpGetColorFromPreviousFrame(JC_INT32 x, JC_INT32 y, JC_INT32 iPreviousFrame, ST_GIF_ATTRIBUTE* pstGifAttribute, ST_RGBA* prgba);
static void BmpAppendRaster8BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute, JDD_FILE file, JC_INT32 iFrame);
static void BmpAppendRaster24BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute, JDD_FILE file, JC_INT32 iFrame);
static JC_BOOLEAN BmpIntersectRect(JC_RECT *pOut, JC_RECT *pRect);
static void BmpBufAppendRaster8BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute, JC_UINT8* pmBuf, JC_INT32 iFrame);
static void BmpBufAppendRaster24BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute, JC_UINT8* pmBuf, JC_INT32 iFrame);
/***************************************************************************
* All Local Function Definitions
**************************************************************************/
JC_RETCODE BmpFillBitmapFileHeader(ST_BMPFILEHEADER* pBitmapFileHeader, JC_INT32 iBitsPerPixel, ST_GIF_ATTRIBUTE* pstGifAttribute, JC_INT32 iFrame)
{
JC_RETCODE rCode = JC_OK ;
if( JC_NULL != pBitmapFileHeader && JC_NULL != pstGifAttribute && iFrame >= 0)
{
JC_INT32 alignwidth = ((pstGifAttribute->iScreenWidth * iBitsPerPixel + 31) / 32) * 4;
jc_memset(pBitmapFileHeader, 0x00,BMP_FILEHEADER);
pBitmapFileHeader->hFileType =0x4D42;
if(iBitsPerPixel >= 16)
{
pBitmapFileHeader->uiFileSize = BMP_FILEHEADER + BMP_FILEINFOHEADER + alignwidth * pstGifAttribute->iScreenHeight;
pBitmapFileHeader->uiFlieOffBits = 54;
}
else
{
pBitmapFileHeader->uiFileSize = BMP_FILEHEADER + BMP_FILEINFOHEADER + pstGifAttribute->ppstFrameAttribute[iFrame]->iNumPalette * 4 + alignwidth * pstGifAttribute->ppstFrameAttribute[0]->iFrameHeight;
pBitmapFileHeader->uiFlieOffBits = 54 + (4 * pstGifAttribute->ppstFrameAttribute[iFrame]->iNumPalette);
}
pBitmapFileHeader->hFlieReserved1 = 0;
pBitmapFileHeader->hFlieReserved2 = 0;
}
else
{
rCode = JC_ERR_INVALID_PARAMETER ;
}
return rCode;
}
JC_RETCODE BmpFillBitmapInfoHeader(ST_BMPINFOHEADER* pBitmapInfoHeader, JC_INT32 iBitsPerPixel, ST_GIF_ATTRIBUTE* pstGifAttribute, JC_INT32 iFrame)
{
JC_RETCODE rCode = JC_OK ;
if( JC_NULL != pBitmapInfoHeader && JC_NULL != pstGifAttribute && iFrame >= 0)
{
jc_memset(pBitmapInfoHeader, 0x00, BMP_FILEINFOHEADER);
pBitmapInfoHeader->uiSize = BMP_FILEINFOHEADER;
pBitmapInfoHeader->uiWidth = pstGifAttribute->iScreenWidth;
pBitmapInfoHeader->uiHeight = pstGifAttribute->iScreenHeight;
pBitmapInfoHeader->hPlanes = 1 ;
pBitmapInfoHeader->hBitCount= iBitsPerPixel;
pBitmapInfoHeader->uiCompression =0;
pBitmapInfoHeader->uiSizeImage =0;
pBitmapInfoHeader->uiXPelsPerMeter = 0;
pBitmapInfoHeader->uiYPelsPerMeter =0;
pBitmapInfoHeader->uiClrUsed = pstGifAttribute->ppstFrameAttribute[iFrame]->iNumPalette;
pBitmapInfoHeader->uiClrImportant = 0;
}
else
{
rCode = JC_ERR_INVALID_PARAMETER ;
}
return rCode;
}
void BmpWriteBitmapFileHeader(ST_BMPFILEHEADER* pBitmapFileHeader, JDD_FILE pszOutBmpFile)
{
jdd_FSWrite(&pBitmapFileHeader->hFileType, sizeof(JC_INT16), 1, pszOutBmpFile);
jdd_FSWrite(&pBitmapFileHeader->uiFileSize, sizeof(JC_INT32), 1, pszOutBmpFile);
jdd_FSWrite(&pBitmapFileHeader->hFlieReserved1, sizeof(JC_INT16), 1, pszOutBmpFile);
jdd_FSWrite(&pBitmapFileHeader->hFlieReserved2, sizeof(JC_INT16), 1, pszOutBmpFile);
jdd_FSWrite(&pBitmapFileHeader->uiFlieOffBits, sizeof(JC_INT32), 1, pszOutBmpFile);
}
void BmpAppendRaster8BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute,JDD_FILE vFile, JC_INT32 iFrame)
{
JC_UINT32 uiRowStart;
JC_UINT32 uiAllignedWidth;
JC_INT32 iJ;
JC_INT32 iPaddingByte;
const JC_UINT8 aucPadding[4] = {0x00, 0x00, 0x00, 0x00};
uiAllignedWidth = ((pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameWidth + 3) / 4) * 4;
iPaddingByte = uiAllignedWidth - pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameWidth;
jdd_FSWrite(pstGifAttribute->ppstFrameAttribute[iFrame]->pucFramePalette, 1, pstGifAttribute->ppstFrameAttribute[iFrame]->iNumPalette * 4, vFile);
for(iJ = 0; iJ < pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameHeight; iJ++)
{
uiRowStart = (pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameHeight - iJ) * pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameWidth;
jdd_FSWrite(pstGifAttribute->ppstFrameAttribute[iFrame]->pucFrameRaster + uiRowStart, 1, pstGifAttribute->ppstFrameAttribute[iFrame]->iFrameWidth, vFile);
jdd_FSWrite(aucPadding, 1, iPaddingByte, vFile);
}
}
void BmpAppendRaster24BitVersion(ST_GIF_ATTRIBUTE* pstGifAttribute, JDD_FILE vFile, JC_INT32 iFrame)
{
JC_INT32 iI;
JC_INT32 iJ;
JC_INT32 iCorrectedX;
JC_INT32 iCorrectedY;
JC_UINT32 uiAlignedRowStride;
JC_INT32 iPaddingByte;
ST_RGBA stRgba;
ST_FRAME_ATTRIBUTE* lpCurFrame;
JC_INT32 iCurColorIndex;
const JC_UINT8 aucPadding[4] = {0x00, 0x00, 0x00, 0x00};
lpCurFrame = pstGifAttribute->ppstFrameAttribute[iFrame];
uiAlignedRowStride = ((pstGifAttribute->iScreenWidth * 24 + 31) / 32) * 4;
iPaddingByte = uiAlignedRowStride - pstGifAttribute->iScreenWidth * 3;
for(iJ = (pstGifAttribute->iScreenHeight - 1); iJ >= 0; iJ--)
{
for(iI = 0; iI < pstGifAttribute->iScreenWidth; iI++)
{
iCorrectedX = iI - lpCurFrame->stPosition.iX;
iCorrectedY = iJ - lpCurFrame->stPosition.iY;
if(iCorrectedX < 0 || iCorrectedY < 0)
{
BmpGetColorFromPreviousFrame( iI, iJ, iFrame-1, pstGifAttribute, &stRgba);
}
else if(iCorrectedX >= lpCurFrame->iFrameWidth || iCorrectedY >= lpCurFrame->iFrameHeight)
{
BmpGetColorFromPreviousFrame( iI, iJ, iFrame-1, pstGifAttribute, &stRgba);
}
else
{
iCurColorIndex = lpCurFrame->pucFrameRaster[iCorrectedY * lpCurFrame->iFrameWidth + iCorrectedX];
if(lpCurFrame->iFrameTransparency && iCurColorIndex == lpCurFrame->iFrameTransparent)
{
BmpGetColorFromPreviousFrame( iI, iJ, iFrame-1, pstGifAttribute, &stRgba);
}
else
{
stRgba.ucR = lpCurFrame->pucFramePalette[iCurColorIndex * 4];
stRgba.ucG = lpCurFrame->pucFramePalette[iCurColorIndex * 4 + 1];
stRgba.ucB = lpCurFrame->pucFramePalette[iCurColorIndex * 4 + 2];
stRgba.ucA = 0;
}
}
jdd_FSWrite(&stRgba, 1, 3, vFile);
}
jdd_FSWrite(&aucPadding, 1, iPaddingByte, vFile);
}
}
JC_RETCODE BmpGetColorFromPreviousFrame(JC_INT32 x, JC_INT32 y, JC_INT32 iPreviousFrame, ST_GIF_ATTRIBUTE* pstGifAttribute, ST_RGBA* pstRgba)
{
JC_INT32 iCorrectedX;
JC_INT32 iCorrectedY;
JC_INT32 iColorIndex;
ST_FRAME_ATTRIBUTE* lpFrame;
JC_RETCODE rCode = JC_OK ;
while(iPreviousFrame >= 0)
{
lpFrame = pstGifAttribute->ppstFrameAttribute[iPreviousFrame];
iCorrectedX = x - lpFrame->stPosition.iX;
iCorrectedY = y - lpFrame->stPosition.iY;
if(iCorrectedX < 0 || iCorrectedY < 0)
{
iPreviousFrame--;
continue;
}
else if(iCorrectedX >= lpFrame->iFrameWidth || iCorrectedY >= lpFrame->iFrameHeight)
{
iPreviousFrame--;
continue;
}
else if(lpFrame->iFrameDisposal == 3)
{
iPreviousFrame--;
continue;
}
iColorIndex = lpFrame->pucFrameRaster[iCorrectedY * lpFrame->iFrameWidth + iCorrectedX];
if(lpFrame->iFrameTransparency && iColorIndex == lpFrame->iFrameTransparent)
{
iPreviousFrame--;
continue;
}
else
{
break;
}
}
if(iPreviousFrame < 0)
{
jc_memset(pstRgba, TRANSPARENT_COLOR, 3);
pstRgba->ucA = 0;
rCode = JC_OK;
}
else
{
pstRgba->ucR = lpFrame->pucFramePalette[iColorIndex * 4];
pstRgba->ucG = lpFrame->pucFramePalette[iColorIndex * 4 + 1];
pstRgba->ucB = lpFrame->pucFramePalette[iColorIndex * 4 + 2];
pstRgba->ucA = 0;
}
return rCode;
}
JC_BOOLEAN BmpIntersectRect(JC_RECT *pOut, JC_RECT *pRect)
{
JC_INT32 iIntersectLeft;
JC_INT32 iIntersectTop;
JC_INT32 iIntersectRight;
JC_INT32 iIntersectBottom;
JC_BOOLEAN bReturn = E_TRUE;
iIntersectLeft = MAX(pOut->iLeft, pRect->iLeft);
iIntersectTop = MAX(pOut->iTop, pRect->iTop);
iIntersectRight = MIN(pOut->iLeft + pOut->uiWidth, pRect->iLeft + pRect->uiWidth);
iIntersectBottom = MIN(pOut->iTop + pOut->uiHeight, pRect->iTop + pRect->uiHeight);
if(iIntersectLeft < pOut->iLeft || iIntersectLeft >= (pOut->iLeft + (JC_INT32)pOut->uiWidth))
{
bReturn = E_FALSE;
}
else if(iIntersectRight < pOut->iLeft || iIntersectRight >= (pOut->iLeft + (JC_INT32)pOut->uiWidth))
{
bReturn = E_FALSE;
}
else if(iIntersectTop < pOut->iTop || iIntersectTop >= (pOut->iTop + (JC_INT32)pOut->uiHeight))
{
bReturn = E_FALSE;
}
else if(iIntersectBottom < pOut->iTop || iIntersectBottom >= (pOut->iTop + (JC_INT32)pOut->uiHeight))
{
bReturn = E_FALSE;
}
else
{
pOut->iLeft = iIntersectLeft;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -