⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wbmp_decoder.c

📁 WBMP格式图片解码器
💻 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 + -