📄 bmpi_rle4_decoder.c
字号:
/*
*******************************************************************************
*
* FILE NAME:
* bmp_rle4_decoder.c
*
* DESCRIPTION:
* source code for BMP decoder with 4-bit and RLE compression (RLE4)
*
* MODULE:
* BMP (BitMaP) decoder.
*
*
*******************************************************************************
*/
/*
*******************************************************************************
* Include files
*******************************************************************************
*/
/* -- Include for BMP ressources -- */
#include "bmp_decoder_api.h"
#include "bmpi_decoder.h"
/*
*******************************************************************************
*
* FUNCTION NAME:
* BMPI_DecodeRLE4()
*
* FUNCTION DESCRIPTION:
* This function decodes a BMP image with 4-bit color and RLE compression.
*
* INPUTS:
* pu8Bitmap : pointer to bitmap data
* psPalette : pointer to palette (structure)
* sImageInfo : image information structure
* func : pointer to callback function
*
* OUTPUTS:
* psOutputBuffer : pointer to output buffer (structure)
*
* RETURN:
* '0' if successful or '1' if failed.
*
* GLOBALS ACCESSED/MODIFIED:
* < List all global variables this function accesses and/or modifies >
*
* SPECIAL NOTES:
*
*******************************************************************************
*/
OP_UINT8 BMPI_DecodeRLE4
(
OP_UINT8 *pu8Bitmap,
PALETTE_TYPE *psPalette,
BMP_IMAGE_INFO sImageInfo,
OP_BOOLEAN func(OP_UINT16 x, OP_UINT16 y),
IMAGE_DECODER_OUTPUT_TYPE *psOutputBuffer
)
{
/*-----------------------------------------------------------------------*/
/* DECLARE LOCAL VARIABLES */
/*-----------------------------------------------------------------------*/
OP_UINT8 u8Xdelta; /* delta for a jump on X-axis in output buffer */
OP_UINT8 u8Ydelta; /* delta for a jump on Y-axis in output buffer */
OP_UINT8 u8PaletteIndex; /* palette index to retrieve RGB color */
OP_UINT8 u8PaletteFirstIndex; /* 1st palette index in encoded mode */
OP_UINT8 u8PaletteSecondIndex; /* 2nd palette index in encoded mode */
OP_UINT8 u8Byte; /* a subsequent byte in the absolute mode */
OP_UINT8 u8FirstByte; /* 1st byte for encoded and absolute modes */
OP_UINT8 u8SecondByte; /* 2nd byte for encoded and absolute modes */
OP_UINT8 u8ParityCheck; /* indicates odd-even parity of an 8-bit data */
OP_UINT8 u8Counter; /* loop counter */
OP_UINT32 u32Xindex; /* index for X-axis of decoded image */
OP_UINT32 u32Yindex; /* index for Y-axis of decoded image */
OP_UINT32 u32CurrentPixelIndex; /* current index for output buffer */
OP_UINT32 u32NumberOfPixels; /* number of pixels in image */
IMAGE_DECODER_OUTPUT_TYPE *psOutputTemp; /* temporary pointer on output buffer */
/*-----------------------------------------------------------------------*/
/* INITIALIZE LOCAL VARIABLES */
/*-----------------------------------------------------------------------*/
u32Xindex = 0;
u32Yindex = 0;
u32CurrentPixelIndex = 0;
u32NumberOfPixels = sImageInfo.u32ImageHeight*sImageInfo.u32ImageWidth;
/*-----------------------------------------------------------------------*/
/* DECODE 4-BIT COLORS & RLE COMPRESSION */
/*-----------------------------------------------------------------------*/
while(u32CurrentPixelIndex < u32NumberOfPixels)
{
u8FirstByte = *pu8Bitmap++;
u8SecondByte = *pu8Bitmap++;
if(u8FirstByte == 0)
{
/* -- Absolute mode -- */
if(u8SecondByte > 2)
{
if((u32CurrentPixelIndex+u8SecondByte) >= u32NumberOfPixels)
{
u8SecondByte =
(OP_UINT8)(u32NumberOfPixels-u32CurrentPixelIndex);
}
u8Counter = u8SecondByte >> 1;
while(u8Counter--)
{
/* read a byte in input buffer */
u8Byte = *pu8Bitmap++;
/* write first pixel in output buffer */
u8PaletteIndex = (u8Byte >> 4) & 0x0f;
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue
= (psPalette+u8PaletteIndex)->u8Blue;
psOutputTemp->u8Green
= (psPalette+u8PaletteIndex)->u8Green;
psOutputTemp->u8Red
= (psPalette+u8PaletteIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff;/* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
/* write second pixel in output buffer */
u8PaletteIndex = u8Byte & 0x0f;
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue
= (psPalette+u8PaletteIndex)->u8Blue;
psOutputTemp->u8Green
= (psPalette+u8PaletteIndex)->u8Green;
psOutputTemp->u8Red
= (psPalette+u8PaletteIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff;/* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
}
if(u8ParityCheck != 0)
{
u8Byte = *pu8Bitmap++;
u8PaletteIndex = (u8Byte >> 4) & 0x0f;
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue =
(psPalette+u8PaletteIndex)->u8Blue;
psOutputTemp->u8Green =
(psPalette+u8PaletteIndex)->u8Green;
psOutputTemp->u8Red =
(psPalette+u8PaletteIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff;/* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
}
/* 16-bit boundary in absolute mode */
u8ParityCheck = u8SecondByte & 0x03;
if( (u8ParityCheck == 1) || (u8ParityCheck == 2) )
{
pu8Bitmap++;
}
}
/* -- 'Escape mode' -- */
else
{
/* end of line */
switch (u8SecondByte)
{
case 0:
u32Xindex = 0;
u32Yindex++;
u32CurrentPixelIndex =
u32Yindex*sImageInfo.u32ImageWidth+u32Xindex;
break;
/* end of bitmap */
case 1:
u32CurrentPixelIndex = u32NumberOfPixels;
break;
/* delta : jump in output buffer */
case 2:
u8Xdelta = *pu8Bitmap++;
u8Ydelta = *pu8Bitmap++;
u32Xindex += u8Xdelta;
u32Yindex += u8Ydelta;
u32CurrentPixelIndex =
u32Yindex*sImageInfo.u32ImageWidth+u32Xindex;
break;
default:
return(1);
}
}
}
/* -- Encoded mode -- */
else
{
if((u32CurrentPixelIndex+u8FirstByte) >= u32NumberOfPixels)
{
u8FirstByte = (OP_UINT8)(u32NumberOfPixels-u32CurrentPixelIndex);
}
u8Counter = u8FirstByte >> 1;
u8ParityCheck = u8FirstByte & 0x01;
u8PaletteFirstIndex = u8PaletteIndex = (u8SecondByte >> 4) & 0x0f;
u8PaletteSecondIndex = u8SecondByte & 0x0f;
while(u8Counter--)
{
/* write the two pixels */
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue =
(psPalette+u8PaletteFirstIndex)->u8Blue;
psOutputTemp->u8Green =
(psPalette+u8PaletteFirstIndex)->u8Green;
psOutputTemp->u8Red =
(psPalette+u8PaletteFirstIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff; /* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue =
(psPalette+u8PaletteSecondIndex)->u8Blue;
psOutputTemp->u8Green =
(psPalette+u8PaletteSecondIndex)->u8Green;
psOutputTemp->u8Red =
(psPalette+u8PaletteSecondIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff; /* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
}
if(u8ParityCheck != 0)
{
psOutputTemp = psOutputBuffer+u32CurrentPixelIndex;
psOutputTemp->u8Blue =
(psPalette+u8PaletteFirstIndex)->u8Blue;
psOutputTemp->u8Green =
(psPalette+u8PaletteFirstIndex)->u8Green;
psOutputTemp->u8Red =
(psPalette+u8PaletteFirstIndex)->u8Red;
psOutputTemp->u8Alpha = 0xff; /* set to opaque as default */
u32Xindex++;
u32CurrentPixelIndex++;
}
}
}
/*-----------------------------------------------------------------------*/
/* DECODED SUCCESSFULLY */
/*-----------------------------------------------------------------------*/
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -