//#undef _IT_DEBUG_
#if (defined(_WIN32) || defined(_WINDOWS) || defined(__MSDOS__))
#define DOSMSWIN
#endif
#include
#include
#ifndef DOSMSWIN
#include
#include
#endif
#include
#include
#include
#include
#include
#ifdef DOSMSWIN
#include
#endif
/* common used types on *this* machine, s.a.
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
/* allow 2-byte-boundary packaging of structs */
#pragma pack(2)
/* Windows-BMP Declarations */
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
}
BITMAPFILEHEADER;
typedef struct
{
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
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
}
RGBQUAD;
/* WAP-Forum WBMP-Declarations */
typedef struct
{
BYTE wbhTypeField;
BYTE wbhFixHeaderField;
BYTE wbhWidth; //Attention MultiByteInteger for > 128
BYTE wbhHeight; //Attention MultiByteInteger for > 128
}
WAPBMPHEADER;
/* set struct-packing back to default */
#pragma pack()
#define BYTE_BIT_COUNT 8
#define DWORD_BIT_COUNT 32
wbmp2cfile (unsigned char *str,int rev);
int
main (int argc, char *argv[])
{
/* file specs */
int fd;
int fdo;
char infile[256];
char outfile[256];
int pos;
/* bmp specs */
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD rbgq;
BYTE *ppixs;
BYTE *pwappixs;
WAPBMPHEADER wbh;
int byteboundbytewidth;
int dwordboundbytewidth;
int wbmppixelbytes;
BYTE *ppos;
BYTE *pwappos;
/* read commandine */
if((argc != 3)&&(argv[2] == NULL))
{
return 0;
}
/* open Bitmap-File */
memset(infile,0,256);
memset(outfile,0,256);
sprintf (infile, "%s.bmp", argv[2]);
if ((fd = open (infile, O_RDONLY)) < 0)
{
printf ("couldn't open file: %s\n", argv[1]);
exit (1);
}
/* read BITMAPFILEHEADER no pragma pack - option found for struct :( */
if (read (fd, &bmfh, sizeof (BITMAPFILEHEADER)) != sizeof (BITMAPFILEHEADER))
{
printf ("Can't read complete BMP Fileheader.\n");
close (fd);
exit (1);
}
#if defined _IT_DEBUG_
printf ("\n'BM'=%x\n", (WORD) ((WORD) 'B' | ((WORD) 'M' << (WORD) 8)));
printf ("\nBitmapfileheader:\n");
printf ("bfType %x\nbfSize %u\nbfRes1 %u\nbfRes2 %u\nbfOffBits %u\n", bmfh.bfType, bmfh.bfSize, bmfh.bfReserved1, bmfh.bfReserved2, bmfh.bfOffBits);
#endif
if (bmfh.bfType != (WORD) ((WORD) 'B' | ((WORD) 'M' << (WORD) 8)))
{
printf ("Can't find *magic* BM for BMP.\n");
exit (1);
}
/* read BITMAPINFOHEADER */
if (read (fd, &bmih, sizeof (BITMAPINFOHEADER)) != sizeof (BITMAPINFOHEADER))
{
printf ("Can't read complete BMP Infoheader.\n");
close (fd);
exit (1);
}
#if defined _IT_DEBUG_
printf ("\nBitmapinfoheader:\n");
printf ("biSize %u\nbiWidth %u\nbiHeight %i\nbiPlanes %u\nbiBitCount %u \
\nbiCompression %u\nbiSizeImage %u\nbiXPelsPerMeter %u \
\nbiYPelsPerMeter %u\nbiClrUsed %u\nbiClrImportant %u\n", bmih.biSize, bmih.biWidth, bmih.biHeight, bmih.biPlanes, bmih.biBitCount, bmih.biCompression, bmih.biSizeImage, bmih.biXPelsPerMeter, bmih.biYPelsPerMeter, bmih.biClrUsed, bmih.biClrImportant);
#endif
if (bmih.biBitCount != 1)
{
printf ("Sorry, conversion possible only for 1-bit depth BMP's.\n");
close (fd);
exit (1);
}
/* calc position */
pos = (int) sizeof (BITMAPFILEHEADER) + (int) bmih.biSize;
/* discard redundant palette-information (entry 0 = black (R00 G00 B00) */
/* entry 1 = white (RFF GFF BFF) ), every entry has a special 4th Byte */
while (pos < (int) bmfh.bfOffBits)
{
pos += (int) read (fd, &rbgq, sizeof (RGBQUAD));
}
/* calc DWORD- & BYTE-boundaries */
if (bmih.biWidth % DWORD_BIT_COUNT == 0)
{
dwordboundbytewidth = (bmih.biWidth / DWORD_BIT_COUNT) * sizeof (DWORD);
}
else
{
dwordboundbytewidth = ((bmih.biWidth / DWORD_BIT_COUNT) + 1) * sizeof (DWORD);
}
if (bmih.biWidth % BYTE_BIT_COUNT == 0)
{
byteboundbytewidth = (bmih.biWidth / BYTE_BIT_COUNT) * sizeof (BYTE);
}
else
{
byteboundbytewidth = ((bmih.biWidth / BYTE_BIT_COUNT) + 1) * sizeof (BYTE);
}
#if defined _IT_DEBUG_
printf ("\nDWORDboundary %i\nBYTEboundary %i\n", dwordboundbytewidth, byteboundbytewidth);
#endif
/* in case bmih.biSizeImage is NOT provided, calculate */
if (bmih.biSizeImage == 0)
{
bmih.biSizeImage = dwordboundbytewidth * (int) bmih.biHeight;
printf ("BMP-File had Zero biSizeImage (warning).\n");
}
/* alloc memory for pixels */
ppixs = (unsigned char *) malloc (bmih.biSizeImage * sizeof (BYTE));
if (ppixs == NULL)
{
printf ("Failed to allocate memory.\n");
close (fd);
exit (1);
}
/* read pixs */
pos += (int) read (fd, ppixs, bmih.biSizeImage * sizeof (BYTE));
//forget this check...:)
// if ( pos != (int)bmfh.bfSize
// && pos != (int)bmfh.bfSize - 2) { //DWORD alignment on file scale
// printf("Error in pixel section alignment of file.\n");
// free(ppixs);
// close(fd);
// exit(1);
// }
// for larger images: code which reads in packets
// for (j=0,k=1;((DWORD)j
// k=min(16384,bmfh.bfSize-j);
// k=(long)read(fp,lpp,(int)k);
// lpp+=k;
// }
/* create outfile name */
sprintf (outfile, "%s.wbmp", argv[2]);
/* create out-file */
#ifdef DOSMSWIN
if ((fdo = open (outfile, (O_CREAT | O_TRUNC | O_WRONLY), (S_IREAD | S_IWRITE))) < 0)
{
#else
if ((fdo = open (outfile, (O_CREAT | O_TRUNC | O_WRONLY | O_SYNC), (S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP))) < 0)
{
#endif
printf ("Couldn't create file: %s\n", outfile);
free (ppixs);
close (fd);
exit (1);
}
/* provide WAPBMPHEADER */
wbh.wbhTypeField = 0;
wbh.wbhFixHeaderField = 0;
if ((bmih.biWidth > 127) || (bmih.biHeight > 127))
{
printf ("Sorry, *this* Version of WapConvert supports Bitmap-Sizes up to 127x127.\n");
free (ppixs);
close (fdo);
close (fd);
exit (1);
}
wbh.wbhWidth = (BYTE) bmih.biWidth;
wbh.wbhHeight = (BYTE) bmih.biHeight;
#if defined _IT_DEBUG_
printf ("outfile %s\n", outfile);
printf ("\nWapBitmapHeader:\n");
printf ("wbhTypeField %u\nwbhFixHeaderField %u\nwbhWidth %u\nwbhHeight %u\n", wbh.wbhTypeField, wbh.wbhFixHeaderField, wbh.wbhWidth, wbh.wbhHeight);
#endif
/* write WAPBMPHEADER */
if (write (fdo, &wbh, sizeof (WAPBMPHEADER)) != sizeof (WAPBMPHEADER))
{
printf ("Couldn't write WBMP-Header.\n");
free (ppixs);
close (fdo);
close (fd);
exit (1);
}
/* calc wbmppixwlbytes */
wbmppixelbytes = bmih.biSizeImage - (dwordboundbytewidth - byteboundbytewidth) * bmih.biHeight;
#if defined _IT_DEBUG_
printf ("\nwbmppixs %i\n", wbmppixelbytes);
#endif
/* alloc memory for wappixels */
pwappixs = (unsigned char *) malloc (wbmppixelbytes * sizeof (BYTE));
if (pwappixs == NULL)
{
printf ("Failed to allocate memory.\n");
free (ppixs);
close (fdo);
close (fd);
exit (1);
}
/* CORE: set BMP DWORD-boundary to WBMP BYTE-boundary in pixel information */
ppos = ppixs;
pwappos = pwappixs + wbmppixelbytes - byteboundbytewidth;
for (pos = 0; pos < (int) bmih.biHeight; pos++)
{
memcpy (pwappos, ppos, byteboundbytewidth * sizeof (BYTE));
ppos += dwordboundbytewidth;
pwappos -= byteboundbytewidth;
}
/* write pixels */
if (write (fdo, pwappixs, wbmppixelbytes * sizeof (BYTE)) != (int) (wbmppixelbytes * sizeof (BYTE)))
{
printf ("Couldn't write WBMP pixels.\n");
free (pwappixs);
free (ppixs);
close (fdo);
close (fd);
exit (1);
}
/* free pixel memories */
free (pwappixs);
free (ppixs);
close (fd);
close (fdo);
/* print report */
printf ("BMP-Size: %u (%u x %u)\n", bmfh.bfSize, bmih.biWidth, bmih.biHeight);
printf ("WBMP-Size: %u\n", wbmppixelbytes + sizeof (WAPBMPHEADER));
//yacht:20031212 add load
if(strcmp(argv[1],"1")==0)
wbmp2cfile (argv[2],0);
else
wbmp2cfile (argv[2],1);
//yacht:20031212 add load
return (0);
}
//yacht:20031212 add load
int
wbmp2cfile (unsigned char *str,int rev)
{
FILE *fp1;
FILE *fp2;
int len;
int i;
unsigned char ch;
unsigned char instr[256];
unsigned char outstr[256];
if (NULL == str)
return -1;
memset (instr, 0, 255);
sprintf (instr, "%s.wbmp", str);
if ((fp1 = fopen (instr, "rb")) == NULL)
{
printf ("Can not open wBmp File!");
return -1;
}
memset (outstr, 0, 255);
sprintf (outstr, "%s.c", str);
if ((fp2 = fopen (outstr, "w")) == NULL)
{
printf ("Can not creat C File!");
return -1;
}
printf ("\nWrite pixel data into %s\n", outstr);
fprintf (fp2, "static const unsigned char %s[] = {", str);
fseek (fp1, 0, SEEK_END);
len = ftell (fp1);
fseek (fp1, 4, 0);
for (i = 0; i < len; i++)
{
if (0 == (i % 20))
fprintf (fp2, "\n");
fread (&ch, 1, sizeof (unsigned char), fp1);
if(!rev)
fprintf (fp2, "0x%02X,",ch);
else
fprintf (fp2, "0x%02X,",(unsigned char)(~ch));
}
fprintf (fp2, "};\n");
fclose (fp1);
fclose (fp2);
(void) unlink(instr);
return 0;
}
/*
WBMP的格式
WBMP的格式如下(例如Width=16,Height=15的一个白色的画面):
0x00,0x00,0x10,0x0f,0xff,0xff......,0xff。
头两个字节为0,现在还不清楚它的用途。
第三个字节为Width,第四个字节为Height,后面的是数据。
数据有以下特点:用一个Bit对应一个Pixel。0表示黑色,1表示白色。
高位开始到底位结束对应着从左到右,数据从低地址到高地址对应着
从上到下。一个字节可以表示8个像素,不足的部分可以用0补齐。
下面是一张太阳的图片,仅供参考。
0x00,0x00,//Unknown or reserved,maybe the mark for the wbmp
0x14,//Width
0x14,//Height 1
//Pixel data
0xfa,0xf5,0xf0,0xfb,0x6d,0xf0,0xfb,0xad,0xf0,0xfb,
0xdd,0x80,0x1b,0xfc,0x70,0xe7,0x1f,0xe0,0x7c,0xe7,
0xd0,0xbb,0xfb,0xd0,0xdb,0xfb,0xb0,0xd7,0xfd,0x70,
0xb7,0xfd,0xb0,0x77,0xf5,0xd0,0xfb,0xeb,0xe0,0xfb,
0xdb,0xf0,0x1c,0xe7,0x80,0xc7,0x1c,0x70,0xf7,0xfd,
0xf0,0xf7,0xbf,0xf0,0xf6,0x5d,0xf0,0xf5,0xed,0xf00
因此在知道了WBMP的格式后,就可以在WAP移动设备上做出
各种图形,甚至是绘图。本来WAP终端设备一般是不支持图
形模式,但是可以在服务端将所有的图形按照WBMP的格式
准备好再送往WAP终端设备,那么看起来就好象在WAP终端
设备上直接绘图。大家可以去
http://www.infoislive.com/demo 看看。
*/