查找当前目录下的png和bmp图片,将其像素点读取出来压缩进theme.bin中,并将图片的其他信息如宽高压缩前后大小和在theme.bin中的偏移位置保存在bmpaddr.h中,方便在其他代码中读取图片像素信息。
main.c
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <zlib.h>
#include <png.h>
#include <setjmp.h>
#include "Userdefine.h"
#include "bmp.h"
#define MAX_IMAGE_FILE_NUM (512)
#define MAX_NAME_LEN (128)
typedef struct
{
char acName[MAX_NAME_LEN];
char acBaseName[MAX_NAME_LEN];
}IMAGE_NAME;
typedef struct
{
IMAGE_NAME stImageName[MAX_IMAGE_FILE_NUM];
unsigned int uiTotalPNGFile;
unsigned int uiTotalBMPFile;
}IMAGE_FILE;
#define FORMAT "#define %-60s"
#define HEADER_MARO ("_BMPADDR_H_")
#define HEADER_FILE ("bmpaddr.h")
#define BIN_FILE ("theme.bin")
#define DIR_PATH ("./")
IMAGE_FILE stImageFile;
FILE *pfHeaderFile = NULL;
FILE *pfBinFile = NULL;
static int iAddr = 0x0;
const unsigned char ucPNGHeadData[] = {0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa};
#define BMP_INDEX(x) (MAX_IMAGE_FILE_NUM - x - 1)
void HandleFileName(char *pucFileName, unsigned int uiFileLen)
{
unsigned int uiIndex = 0;
char cTemp = 0;
if(pucFileName == NULL || uiFileLen <= 0)
{
return;
}
for(uiIndex = 0; uiIndex < uiFileLen; uiIndex++)
{
cTemp = pucFileName[uiIndex];
if(cTemp >= 'a' && cTemp <= 'z')
{
cTemp -= 32;
}
else if(!((cTemp >= 'A' && cTemp <= 'Z') || (cTemp >= '0' && cTemp <= '9')))
{
cTemp = '_';
}
pucFileName[uiIndex] = cTemp;
}
}
void FindAllImageFile()
{
struct dirent *pstDirent = NULL;
DIR *pstDir;
IMAGE_NAME *pstTemp = NULL;
BOOL bFound = FALSE;
memset(&stImageFile, 0, sizeof(stImageFile));
pstDir = opendir(DIR_PATH);
while(NULL != (pstDirent = readdir(pstDir)))
{
bFound = FALSE;
if(8 == pstDirent->d_type)
{
if((stImageFile.uiTotalPNGFile + stImageFile.uiTotalBMPFile) < MAX_IMAGE_FILE_NUM)
{
if(strstr(pstDirent->d_name, ".png") || strstr(pstDirent->d_name, ".PNG"))
{
pstTemp = &(stImageFile.stImageName[stImageFile.uiTotalPNGFile]);
stImageFile.uiTotalPNGFile++;
bFound = TRUE;
}
else if(strstr(pstDirent->d_name, ".bmp") || strstr(pstDirent->d_name, ".BMP"))
{
pstTemp = &(stImageFile.stImageName[MAX_IMAGE_FILE_NUM - stImageFile.uiTotalBMPFile - 1]);
stImageFile.uiTotalBMPFile++;
bFound = TRUE;
}
if(bFound)
{
snprintf(pstTemp->acName, sizeof(pstTemp->acName), "%s", pstDirent->d_name);
snprintf(pstTemp->acBaseName, sizeof(pstTemp->acBaseName), "%s", pstDirent->d_name);
HandleFileName(pstTemp->acBaseName, strlen(pstTemp->acBaseName));
}
}
}
}
closedir(pstDir);
}
void SortImageFile()
{
int iIndex = 0;
int iTemp = 0;
IMAGE_NAME stTemp;
int iIndexTemp = 0;
int iTempIndex = 0;
for(iIndex = 0; iIndex < stImageFile.uiTotalPNGFile; iIndex++)
{
stTemp = stImageFile.stImageName[iIndex];
for(iTemp = iIndex + 1; iTemp < stImageFile.uiTotalPNGFile; iTemp++)
{
if(strcmp(stTemp.acBaseName, stImageFile.stImageName[iTemp].acBaseName) > 0)
{
stImageFile.stImageName[iIndex] = stImageFile.stImageName[iTemp];
stImageFile.stImageName[iTemp] = stTemp;
stTemp = stImageFile.stImageName[iIndex];
}
}
}
for(iIndex = 0; iIndex < stImageFile.uiTotalBMPFile; iIndex++)
{
iIndexTemp = BMP_INDEX(iIndex);
stTemp = stImageFile.stImageName[iIndexTemp];
for(iTemp = iIndex + 1; iTemp < stImageFile.uiTotalBMPFile; iTemp++)
{
iTempIndex = BMP_INDEX(iTemp);
if(strcmp(stTemp.acBaseName, stImageFile.stImageName[iTempIndex].acBaseName) > 0)
{
stImageFile.stImageName[iIndexTemp] = stImageFile.stImageName[iTempIndex];
stImageFile.stImageName[iTempIndex] = stTemp;
stTemp = stImageFile.stImageName[iIndexTemp];
}
}
}
}
void FlipImage(unsigned char * ucImgBuff, int iWidth, int iHeight)
{
unsigned char *pucLineBuf = NULL;
int iIndexY = 0;
unsigned char *pucHead = NULL;
unsigned char *pucTail = NULL;
pucLineBuf = (unsigned char *)malloc(iWidth * 4);
if(pucLineBuf == NULL)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
return;
}
for(iIndexY = 0; iIndexY < iHeight / 2; ++iIndexY)
{
pucHead = ucImgBuff + iIndexY * iWidth * 4;
pucTail = ucImgBuff + (iHeight - iIndexY - 1) * iWidth * 4;
memcpy(pucLineBuf, pucHead, iWidth * 4);
memcpy(pucHead, pucTail, iWidth * 4);
memcpy(pucTail, pucLineBuf, iWidth * 4);
}
free(pucLineBuf);
pucLineBuf = NULL;
}
void WriteToFile(int iStartAddr, int iWidth, int iHeight, unsigned char *pucPicBuffer, char *acBaseName)
{
uLongf iDataLenBeforeCompress = iWidth * iHeight * 4;
uLongf iDataLenAfterCompress = compressBound(iDataLenBeforeCompress);
int iRet = 0;
char acTempBuffer[1024];
unsigned char acName[128];
unsigned char *pucCompressData = NULL;
do
{
pucCompressData = (unsigned char *)malloc(iDataLenAfterCompress);
if(pucCompressData == NULL)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
break;
}
iRet = compress(pucCompressData, &iDataLenAfterCompress, pucPicBuffer, iDataLenBeforeCompress);
if(Z_OK != iRet)
{
printf("===>[%s, %d]%d\n", __FUNCTION__, __LINE__, iRet);
break;
}
if(pfHeaderFile)
{
int iTempOffset = (4 - (iDataLenAfterCompress % 4));
snprintf(acName, sizeof(acName), "%s", acBaseName);
snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" 0x%x\n", acName, iAddr);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
snprintf(acName, sizeof(acName), "%s_SIZE", acBaseName);
snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iDataLenBeforeCompress);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
snprintf(acName, sizeof(acName), "%s_COMPRESS_SIZE", acBaseName);
snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iDataLenAfterCompress);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
snprintf(acName, sizeof(acName), "%s_WIDTH", acBaseName);
snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iWidth);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
snprintf(acName, sizeof(acName), "%s_HEIGHT", acBaseName);
snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n\n", acName, iHeight);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
if(pfBinFile)
{
char acTemp[8];
memset(acTemp, 0, sizeof(acTemp));
// printf("===>[%s, %d]%x\n", __FUNCTION__, __LINE__, ftell(pfBinFile));
fwrite(pucCompressData, iDataLenAfterCompress, 1, pfBinFile);
fwrite(acTemp, iTempOffset, 1, pfBinFile);
}
iAddr = iAddr + iDataLenAfterCompress + iTempOffset;
}
}while(0);
if(pucCompressData)
{
free(pucCompressData);
pucCompressData = NULL;
}
}
#define PNG_BYTES_TO_CHECK 4
void UseLibPNGToLoadPNGFile(IMAGE_NAME stFileName)
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_bytep* row_pointers;
char buf[PNG_BYTES_TO_CHECK];
int iWidth, iHeight, iIndexX, iIndexY, iTemp, iColorType;
BOOL bGetImageData = FALSE;
unsigned char *pucImageBuffer = NULL;
if(strlen(stFileName.acName) <= 0 || strlen(stFileName.acBaseName) <= 0)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
return;
}
do
{
fp = fopen(stFileName.acName, "rb");
if(fp == NULL)
{
break;
}
png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0);
info_ptr = png_create_info_struct(png_ptr);
setjmp(png_jmpbuf(png_ptr));
iTemp = fread(buf, 1, PNG_BYTES_TO_CHECK, fp);
if(iTemp < PNG_BYTES_TO_CHECK)
{
break;
}
iTemp = png_sig_cmp((png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK);
if(iTemp != 0)
{
break;
}
rewind(fp);
png_init_io(png_ptr, fp);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);
iColorType = png_get_color_type(png_ptr, info_ptr);
iWidth = png_get_image_width(png_ptr, info_ptr);
iHeight = png_get_image_height(png_ptr, info_ptr);
row_pointers = png_get_rows(png_ptr, info_ptr);
// printf("===>[%s, %d]%d %d %d\n", __FUNCTION__, __LINE__, iWidth, iHeight, iColorType);
pucImageBuffer = (unsigned char *)malloc(iWidth * iHeight * 4);
if(pucImageBuffer == NULL)
{
break;
}
bGetImageData = FALSE;
switch(iColorType)
{
case PNG_COLOR_TYPE_RGB_ALPHA:
for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)
{
for(iIndexX = 0; iIndexX < iWidth * 4; iIndexX += 4)
{
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 2) = row_pointers[iIndexY][iIndexX + 0];//r
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 1) = row_pointers[iIndexY][iIndexX + 1];//g
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 0) = row_pointers[iIndexY][iIndexX + 2];//b
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 3) = row_pointers[iIndexY][iIndexX + 3];//a
}
}
bGetImageData = TRUE;
break;
case PNG_COLOR_TYPE_RGB:
{
int iTempIndex = 0;
for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)
{
for(iIndexX = 0; iIndexX < iWidth * 3;iIndexX +=3)
{
iTempIndex = (iIndexX / 3) * 4;
*(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 2) = row_pointers[iIndexY][iIndexX + 0];
*(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 1) = row_pointers[iIndexY][iIndexX + 1];
*(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 0) = row_pointers[iIndexY][iIndexX + 2];
*(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 3) = 0xff;
}
}
bGetImageData = TRUE;
}
break;
default:
break;
}
if(bGetImageData)
{
// FlipImage(pucImageBuffer, iWidth, iHeight);
WriteToFile(iAddr, iWidth, iHeight, pucImageBuffer, stFileName.acBaseName);
}
}while(0);
if(pucImageBuffer)
{
free(pucImageBuffer);
pucImageBuffer = NULL;
}
if(fp)
{
fclose(fp);
fp = NULL;
}
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
}
void LoadBMPFile(IMAGE_NAME stFileName)
{
FILE *fp = NULL;
BITMAPFILEHEADER stPicHead;
BITMAPINFOHEADER stPicInfoHead;
int iWidth = 0;
int iHeight = 0;
int iBitCount = 0;
int iLineByte = 0;
unsigned char *pucPicBuffer = NULL;
unsigned char *pucImageBuffer = NULL;
if(strlen(stFileName.acName) <= 0 || strlen(stFileName.acBaseName) <= 0)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
return;
}
do
{
fp = fopen(stFileName.acName, "rb");
if(fp == NULL)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
break;
}
fread(&stPicHead.bfType, sizeof(stPicHead.bfType), 1, fp);
fread(&stPicHead.bfSize, sizeof(stPicHead.bfSize), 1, fp);
fread(&stPicHead.bfReserved1, sizeof(stPicHead.bfReserved1), 1, fp);
fread(&stPicHead.bfReserved2, sizeof(stPicHead.bfReserved2), 1, fp);
fread(&stPicHead.bfOffBits, sizeof(stPicHead.bfOffBits), 1, fp);
if(stPicHead.bfType != 0x4D42)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
break;
}
fread(&stPicInfoHead, 1, sizeof(stPicInfoHead), fp);
iWidth = stPicInfoHead.biWidth;
iHeight = stPicInfoHead.biHeight;
iBitCount = stPicInfoHead.biBitCount;
// printf("===>[%s, %d]%d %d %d\n", __FUNCTION__, __LINE__, iWidth, iHeight, iBitCount);
// printf("===>[%s, %d]%d %x\n", __FUNCTION__, __LINE__, stPicInfoHead.biSize, stPicInfoHead.biSizeImage);
if(iBitCount == 24 || iBitCount == 32)
{
int iIndexY = 0;
int iIndexX = 0;
iLineByte = (iWidth*iBitCount / 8 + 3) / 4 * 4;
pucPicBuffer = (unsigned char *)malloc(iHeight * iLineByte);
if(NULL == pucPicBuffer)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
break;
}
pucImageBuffer = (unsigned char *)malloc(iHeight * iWidth * 4);
if(NULL == pucImageBuffer)
{
printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);
break;
}
fread(pucPicBuffer, 1, iHeight * iLineByte, fp);
// printf("===>[%s, %d]%x\n", __FUNCTION__, __LINE__, iHeight * iLineByte);
FlipImage(pucPicBuffer, iLineByte / 4, iHeight);
if(iBitCount == 24)
{
for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)
{
for(iIndexX = 0; iIndexX < iWidth; ++iIndexX)
{
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 0) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 0);//b
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 1) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 1);//g
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 2) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 2);//r
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 3) = 0xff;
}
}
}
else if(iBitCount == 32)
{
for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)
{
for(iIndexX = 0; iIndexX < iWidth; ++iIndexX)
{
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 0) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 0);//b
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 1) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 1);//g
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 2) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 2);//r
*(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 3) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 3);//a
}
}
}
WriteToFile(iAddr, iWidth, iHeight, pucImageBuffer, stFileName.acBaseName);
}
}while(0);
if(fp)
{
fclose(fp);
fp = NULL;
}
if(pucPicBuffer)
{
free(pucPicBuffer);
pucPicBuffer = NULL;
}
if(pucImageBuffer)
{
free(pucImageBuffer);
pucImageBuffer = NULL;
}
}
void HandleImageFile()
{
int iIndex = 0;
IMAGE_NAME stTemp;
int iIndexTemp = 0;
char acTempBuffer[1024];
do
{
pfHeaderFile = fopen(HEADER_FILE, "w");
if(pfHeaderFile == NULL)
{
break;
}
pfBinFile = fopen(BIN_FILE, "w");
if(pfBinFile == NULL)
{
break;
}
snprintf(acTempBuffer, sizeof(acTempBuffer), "#ifndef %s\n", HEADER_MARO);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
snprintf(acTempBuffer, sizeof(acTempBuffer), "#define %s\n\n", HEADER_MARO);
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
DEBUG_DEB("Total %d PNG file.\n", stImageFile.uiTotalPNGFile);
for(iIndex = 0; iIndex < stImageFile.uiTotalPNGFile; iIndex++)
{
stTemp = stImageFile.stImageName[iIndex];
UseLibPNGToLoadPNGFile(stTemp);
}
DEBUG_DEB("Total %d BMP file.\n", stImageFile.uiTotalBMPFile);
for(iIndex = 0; iIndex < stImageFile.uiTotalBMPFile; iIndex++)
{
iIndexTemp = BMP_INDEX(iIndex);
stTemp = stImageFile.stImageName[iIndexTemp];
LoadBMPFile(stTemp);
}
snprintf(acTempBuffer, sizeof(acTempBuffer), "#endif\n");
fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);
}while(0);
if(pfHeaderFile)
{
fclose(pfHeaderFile);
pfHeaderFile = NULL;
}
if(pfBinFile)
{
fclose(pfBinFile);
pfBinFile = NULL;
}
}
int main(int argc, char *argv[])
{
FindAllImageFile();
if(stImageFile.uiTotalBMPFile + stImageFile.uiTotalPNGFile > 0)
{
SortImageFile();
HandleImageFile();
}
return 0;
}
bmp.h
#ifndef BMP_H_
#define BMP_H_
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef long LONG;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD { // rgbq
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
#endif /* BMP_H_ */
Userdefine.h
#ifndef USERDEFINE_H_
#define USERDEFINE_H_
#if 1
#define DEBUG_DEB(fmt, arg...) printf("[DEBUG][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)
#else
#define DEBUG_DEB(fmt, arg...)
#endif
#if 0
#define DEBUG_INFO(fmt, arg...) printf("[DEBUG][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)
#else
#define DEBUG_INFO(fmt, arg...)
#endif
#if 1
#define DEBUG_ERR(fmt, arg...) printf("[ERROR][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)
#else
#define DEBUG_ERR(fmt, arg...)
#endif
typedef enum
{
FALSE,
TRUE,
}BOOL;
typedef unsigned int U32;
#endif /* USERDEFINE_H_ */