📄 wbmp_decoder.c
字号:
#ifndef WBMP_DECODER_C
#define WBMP_DECODER_C
#include "wbmp.h"
/*P(***************************************************************************
* Procedure name : wmp0_0Decode
* Object : Decode algorithm: convert WBMP (24/8/1bit) to native format
*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
*----------------------------------------------------------------------------*
*
* Scope :
* -------------------
* External
*
* Input parameters :
* -------------------
* pp_WBMPData : WBMP-Image data
* vp_LengthOfWBMPData : Length of data in wbmp format
*
* Output parameters :
* -------------------
* pp_LengthOfConvData : Length of BMP format file
* pp_WinBMPData : Buffer for BMP data
* pp_Width : Width of BMP image
* pp_Height : Height of BMP image
*
* Returned parameter:
* -------------------
* u8 ... : WBMP_CONVERSION_OK / WBMP_CONVERSION_ERROR
* (Status Of Conversion)
*
* Used variables :
* -------------------
* None
*
* Used procedures :
* -------------------
*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
* This function will convert the imagedata from the WBMP format into the
* BMP format. If the supplied buffer for the converted data is NULL the
* function will return an error. With a valid buffer the data is converted
* from the WBMP format to the BMP format and saved in the supplied buffer.
*
* The function will return:
* WBMP_CONVERSION_OK - Conversion completed
* WBMP_CONVERSION_ERROR - Error occured. Conversion not done.
*
***************************************************************************)P*/
/* #*/
#undef PROCEDURE_NUMBER
#define PROCEDURE_NUMBER 0
u8 wbmp0_0Decode( u8 *pp_WBMPData, u32 *pp_LengthOfConvData, u8 *pp_WinBMPData,
u32 *pp_Width, u32 *pp_Height)
{
u32 vl_LengthOfConvData;
u32 vl_DataLength;
u32 vl_WidthInBytes;
u32 vl_BMPWidthInBytes;
u8 *pl_CurrentReadByte;
u8 *pl_WindowsBitmap;
u32 vl_Width, vl_Height;
s32 i;
vl_LengthOfConvData = *pp_LengthOfConvData;
*pp_LengthOfConvData = 0;
pl_CurrentReadByte = pp_WBMPData + WBMP_FIXHEADER_FIELD_BYTE_NB + 1;
/* Decode the width of the wbmp and increment the pointer of reading on the wbmp data*/
pl_CurrentReadByte += wbmp0_2DecMultiByte(pl_CurrentReadByte, &vl_Width);
/*Test if the width is not null */
if (vl_Width == 0)
{
/* Width is null */
return (WBMP_CONVERSION_ERROR);
}
/* Decode the height of the wbmp and increment the pointer of reading on the wbmp data*/
pl_CurrentReadByte += wbmp0_2DecMultiByte(pl_CurrentReadByte, &vl_Height);
/*Test if the height is null OR higher than maximum allowed*/
if (vl_Height == 0)
{
/* Height is null OR higher than max allowed*/
return (WBMP_CONVERSION_ERROR);
}
if (pp_Width != NULL)
{
*pp_Width = vl_Width;
}
if (pp_Height != NULL)
{
*pp_Height = vl_Height;
}
/* Image Width in bytes*/
vl_WidthInBytes = ((vl_Width + 7 ) >> 3 );
/* For BMP, align the data to the next 4 byte boundary */
vl_BMPWidthInBytes = vl_WidthInBytes + ((0 - vl_WidthInBytes ) & 0x3 );
/* length in bytes needed to store the bitmap */
vl_DataLength = vl_BMPWidthInBytes * vl_Height;
/* Get the total length of the bitmap file */
*pp_LengthOfConvData = 14 + 48 + (vl_DataLength);
/*If the pointer pp_WinBMPData is NULL, we can't save the decoded data!*/
if (pp_WinBMPData == NULL)
{
return (WBMP_CONVERSION_ERROR);
}
/*Check if the length of the buffer destinated for converted data is long enough*/
if (*pp_LengthOfConvData > vl_LengthOfConvData)
{
/* The pointer reserved for converted data is not long enough*/
return WBMP_CONVERSION_ERROR;
}
/*Initialise all data to 0*/
memset(pp_WinBMPData, 0, *pp_LengthOfConvData);
/* BMP Type identifier = 0x4d42 */
pp_WinBMPData[0] = 0x42;
pp_WinBMPData[1] = 0x4d;
/* Total filesize */
pp_WinBMPData[2] = (*pp_LengthOfConvData) & 0x0FF;
pp_WinBMPData[3] = (*pp_LengthOfConvData >> 8) & 0x0FF;
pp_WinBMPData[4] = (*pp_LengthOfConvData >> 16) & 0x0FF;
pp_WinBMPData[5] = (*pp_LengthOfConvData >> 24) & 0x0FF;
/* Reserved dword */
pp_WinBMPData[6] = 0;
pp_WinBMPData[7] = 0;
pp_WinBMPData[8] = 0;
pp_WinBMPData[9] = 0;
/* Bitmap data offset */
pp_WinBMPData[10] = 62;
pp_WinBMPData[11] = 0;
pp_WinBMPData[12] = 0;
pp_WinBMPData[13] = 0;
/* Bitmap Header size */
pp_WinBMPData[14] = 40;
pp_WinBMPData[15] = 0;
pp_WinBMPData[16] = 0;
pp_WinBMPData[17] = 0;
/* Width of bitmap in pixels */
pp_WinBMPData[18] = (vl_Width) & 0x0FF;
pp_WinBMPData[19] = (vl_Width >> 8) & 0x0FF;
pp_WinBMPData[20] = (vl_Width >> 16) & 0x0FF;
pp_WinBMPData[21] = (vl_Width >> 24) & 0x0FF;
/* Height of bitmap in pixels */
pp_WinBMPData[22] = (vl_Height) & 0x0FF;
pp_WinBMPData[23] = (vl_Height >> 8) & 0x0FF;
pp_WinBMPData[24] = (vl_Height >> 16) & 0x0FF;
pp_WinBMPData[25] = (vl_Height >> 24) & 0x0FF;
/* Nuber of planes in bitmap */
pp_WinBMPData[26] = 1;
pp_WinBMPData[27] = 0;
/* Number of bits per pixel */
pp_WinBMPData[28] = 1;
pp_WinBMPData[29] = 0;
/* Compression used */
pp_WinBMPData[30] = 0;
pp_WinBMPData[31] = 0;
pp_WinBMPData[32] = 0;
pp_WinBMPData[33] = 0;
/* Bitmap data size */
pp_WinBMPData[34] = (vl_DataLength) & 0x0FF;
pp_WinBMPData[35] = (vl_DataLength >> 8) & 0x0FF;
pp_WinBMPData[36] = (vl_DataLength >> 16) & 0x0FF;
pp_WinBMPData[37] = (vl_DataLength >> 24) & 0x0FF;
/* Horisontal resolution in pixels/meter */
pp_WinBMPData[38] = 0;
pp_WinBMPData[39] = 0;
pp_WinBMPData[40] = 0;
pp_WinBMPData[41] = 0;
/* Vertical resolution in pixels/meter */
pp_WinBMPData[42] = 0;
pp_WinBMPData[43] = 0;
pp_WinBMPData[44] = 0;
pp_WinBMPData[45] = 0;
/* Number of colours used (For monochrome I use 0 instead of 2 -> easier wrt data alignment)*/
pp_WinBMPData[46] = 0;
pp_WinBMPData[47] = 0;
pp_WinBMPData[48] = 0;
pp_WinBMPData[49] = 0;
/* Number of important colours */
pp_WinBMPData[50] = 0;
pp_WinBMPData[51] = 0;
pp_WinBMPData[52] = 0;
pp_WinBMPData[53] = 0;
/* Colour1 data (White) */
pp_WinBMPData[54] = 0x00;
pp_WinBMPData[55] = 0x00;
pp_WinBMPData[56] = 0x00;
pp_WinBMPData[57] = 0x00;
/* Colour2 data (Black) */
pp_WinBMPData[58] = 0x0FF;
pp_WinBMPData[59] = 0x0FF;
pp_WinBMPData[60] = 0x0FF;
pp_WinBMPData[61] = 0x00;
pl_WindowsBitmap = (u8 *)pp_WinBMPData + 14 + 48;
/* Copy the bitmap data from the input-buffer to the output-buffer */
for(i = vl_Height - 1; i >= 0; i--)
{
memcpy( (pl_WindowsBitmap + (vl_BMPWidthInBytes * i)), (pl_CurrentReadByte + (vl_WidthInBytes * (vl_Height - 1 - i))), vl_WidthInBytes);
}
return WBMP_CONVERSION_OK;
}
/*P(***************************************************************************
* Procedure name : wbmp0_1PictSize
* Object : Decode algorithm: convert WBMP (24/8/1bit) to native format
*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
*----------------------------------------------------------------------------*
*
* Scope :
* -------------------
* External
*
* Input parameters :
* -------------------
* pp_WBMPData : WBMP-Image data
* vp_LengthOfWBMPData : Length of data in wbmp format
*
* Output parameters :
* -------------------
* pp_LengthOfConvData : Length of data in BMP format
* pp_Width : Width of image
* pp_Height : Height of image
*
* Returned parameter:
* -------------------
* u8 ... : WBMP_CONVERSION_OK / WBMP_CONVERSION_ERROR
* (Status Of Conversion)
*
* Used variables :
* -------------------
* None
*
* Used procedures :
* -------------------
*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
* This function will return the width and height of the image in pixels.
*
* The function will return:
* WBMP_CONVERSION_OK - Completed OK.
* WBMP_CONVERSION_ERROR - Error occured.
*
***************************************************************************)P*/
/* #*/
#undef PROCEDURE_NUMBER
#define PROCEDURE_NUMBER 1
u8 wbmp0_1PictSize( u8 *pp_WBMPData, u32 *pp_LengthOfConvData,
u32 *pp_Width, u32 *pp_Height)
{
u32 vl_DataLength;
u32 vl_WidthInBytes;
u8 *pl_CurrentReadByte;
u32 vl_Width, vl_Height;
/*Check if the input data is a WBMP image with the type 0*/
if (pp_WBMPData[WBMP_TYPE_FIELD_BYTE_NB] != WBMP_TYPE_0)
{
/* Wbmp image is not a type 0 one. */
return WBMP_CONVERSION_ERROR;
}
/*Check if the input data is a "without extension field" wbmp*/
if (pp_WBMPData[WBMP_FIXHEADER_FIELD_BYTE_NB] != WBMP_WITHOUT_EXT_FIELD)
{
/* Wbmp header is with an ext field */
return WBMP_CONVERSION_ERROR;
}
*pp_LengthOfConvData = 0;
pl_CurrentReadByte = pp_WBMPData + WBMP_FIXHEADER_FIELD_BYTE_NB + 1;
/* Decode the width of the wbmp and increment the pointer of reading on the wbmp data*/
pl_CurrentReadByte += wbmp0_2DecMultiByte(pl_CurrentReadByte, &vl_Width);
/*Test if the width is not null */
if (vl_Width == 0)
{
/* Width is null */
return (WBMP_CONVERSION_ERROR);
}
/* Decode the height of the wbmp and increment the pointer of reading on the wbmp data*/
pl_CurrentReadByte += wbmp0_2DecMultiByte(pl_CurrentReadByte, &vl_Height);
/*Test if the height is null OR higher than maximum allowed*/
if (vl_Height == 0)
{
/* Height is null */
return (WBMP_CONVERSION_ERROR);
}
if (pp_Width != NULL)
{
*pp_Width = vl_Width;
}
if (pp_Height != NULL)
{
*pp_Height = vl_Height;
}
/* Image Width in bytes*/
vl_WidthInBytes = ((vl_Width + 7 ) >> 3 );
/* Align the data to the next 4 byte boundary */
vl_WidthInBytes = vl_WidthInBytes + ((0 - vl_WidthInBytes ) & 0x3 );
/* length in bytes needed to store the bitmap */
vl_DataLength = vl_WidthInBytes * vl_Height;
/* Get the total length of the bitmap file */
*pp_LengthOfConvData = 14 + 48 + (vl_DataLength);
return (WBMP_CONVERSION_OK);
}
/*P(***************************************************************************
* Procedure name : wbmp0_2DecMultiByte
* Object : Convert multibyte into integer value.
*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
*----------------------------------------------------------------------------*
*
* Scope :
* -------------------
* Internal
*
* Input parameters :
* -------------------
* pp_Data : Data to be decoded from multibyte
*
* Output parameters :
* -------------------
* pp_IntegerValue : Integer value decoded from multibyte
*
* Returned parameter:
* -------------------
* vl_NbBytes : Number of bytes for multibyte value
*
* Used variables :
* -------------------
* None
*
* Used procedures :
* -------------------
* None
*
*----------------------------------------------------------------------------*
* DESCRIPTION
*
* The passed data is converted from a multibyte format into a standard integer
* value. The decoded value is saved into the parameter passed and the length
* (in number of bytes) of the encoded data is returned.
*
*************************************************************************/
/* INTERFACE DECLARATION: */
#undef PROCEDURE_NUMBER
#define PROCEDURE_NUMBER 2
u8 wbmp0_2DecMultiByte(u8 *pp_Data, u32 *pp_IntegerValue)
{
u32 vl_NbBytes;
u32 vl_Index;
u32 vl_IntegerValue;
vl_NbBytes = 0;
while ((pp_Data[vl_NbBytes] & CONTINUATION_BIT_FLAG) != 0)
{
vl_NbBytes++;
} /*End While loop*/
vl_NbBytes++;
if (pp_IntegerValue == NULL)
{
return vl_NbBytes;
}
vl_IntegerValue = 0;
for (vl_Index = 0; vl_Index < vl_NbBytes; vl_Index++)
{
vl_IntegerValue = (vl_IntegerValue << 7) | (pp_Data[vl_Index] & ~CONTINUATION_BIT_FLAG);
}
*pp_IntegerValue = vl_IntegerValue;
return vl_NbBytes;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -