#include #include #include #include typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned long ULONG; #define PK __attribute__ ((packed)) struct FFEBitmap { UCHAR flags PK; UCHAR height PK; USHORT width PK; short xoff PK; short yoff PK; UCHAR pData[0]; }; static int ExportBitmap (FFEBitmap *pBitmap, char *pFilename); static int ReadData (char *&pSrc, UCHAR *pData); static UCHAR pFFEPal[128*3] = { 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0x10, 0x10, 0x10, 0x14, 0x14, 0x14, 0x18, 0x18, 0x18, 0x1c, 0x1c, 0x1c, 0x20, 0x20, 0x20, 0x24, 0x24, 0x24, 0x28, 0x28, 0x28, 0x2c, 0x2c, 0x2c, 0x30, 0x30, 0x30, 0x34, 0x34, 0x34, 0x38, 0x38, 0x38, 0x3c, 0x3c, 0x3c, 0x3c, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x3c, 0x3c, 0x0, 0x4, 0x8, 0x4, 0xa, 0x2, 0x6, 0x12, 0x4, 0x6, 0xa, 0xa, 0x8, 0x1a, 0x2, 0x2, 0xa, 0xa, 0x10, 0x12, 0xa, 0xa, 0x22, 0x2, 0x2, 0x4, 0x8, 0x1c, 0xc, 0x12, 0x10, 0x2a, 0x2, 0x2, 0x1a, 0xa, 0xc, 0x22, 0xa, 0xa, 0x32, 0x2, 0x2, 0xe, 0x1a, 0x10, 0xc, 0x20, 0xc, 0x6, 0xa, 0x2a, 0x14, 0x12, 0x14, 0x2a, 0xa, 0x8, 0x8, 0x2c, 0x8, 0xc, 0x26, 0xc, 0x1a, 0x12, 0x14, 0x8, 0x30, 0x8, 0x3a, 0x4, 0x4, 0x14, 0x1a, 0x14, 0x22, 0x12, 0xe, 0xe, 0x2c, 0xa, 0x32, 0xa, 0x8, 0x12, 0x20, 0x14, 0x12, 0x26, 0xe, 0x18, 0x20, 0x10, 0x2a, 0x12, 0xe, 0x18, 0x26, 0xc, 0x1a, 0x1a, 0x16, 0x22, 0x14, 0x16, 0x22, 0x1a, 0x10, 0x3a, 0xa, 0x8, 0x1e, 0x20, 0xe, 0x34, 0x12, 0x6, 0x18, 0x20, 0x16, 0x2a, 0x1a, 0xc, 0x32, 0x1a, 0x4, 0x1e, 0x26, 0xe, 0x12, 0x16, 0x2a, 0x14, 0x26, 0x18, 0x2a, 0x14, 0x14, 0x10, 0x32, 0x10, 0x24, 0x22, 0xe, 0xc, 0x12, 0x36, 0x3c, 0x12, 0x8, 0x32, 0x12, 0x12, 0x22, 0x1a, 0x1a, 0x18, 0x26, 0x18, 0x1e, 0x20, 0x18, 0x16, 0x2e, 0x14, 0x2a, 0x22, 0xe, 0x1a, 0x1a, 0x26, 0x34, 0x20, 0x8, 0x16, 0x22, 0x24, 0x3c, 0x1a, 0x6, 0x10, 0x14, 0x38, 0x2a, 0x1a, 0x18, 0x1e, 0x26, 0x1a, 0x24, 0x22, 0x18, 0x3a, 0x12, 0x12, 0x14, 0x34, 0x16, 0x30, 0x20, 0x10, 0x32, 0x1a, 0x16, 0x32, 0x2a, 0x6, 0x3c, 0x22, 0x4, 0x1e, 0x2e, 0x18, 0x2a, 0x22, 0x18, 0x1e, 0x20, 0x26, 0x12, 0x1a, 0x3a, 0x34, 0x32, 0x2, 0x1a, 0x36, 0x18, 0x3c, 0x2a, 0x4, 0x2a, 0x2a, 0x16, 0x1e, 0x26, 0x26, 0x1a, 0x1a, 0x38, 0x3a, 0x1a, 0x18, 0x24, 0x2c, 0x1c, 0x24, 0x22, 0x26, 0x1e, 0x30, 0x20, 0x32, 0x26, 0x16, 0x32, 0x32, 0xc, 0x2a, 0x22, 0x24, 0x24, 0x2a, 0x26, 0x3c, 0x34, 0x4, 0x30, 0x22, 0x22, 0x1e, 0x24, 0x36, 0x24, 0x32, 0x22, 0x2a, 0x2a, 0x26, 0x3c, 0x3a, 0x4, 0x24, 0x24, 0x32, 0x24, 0x28, 0x30, 0x3a, 0x22, 0x22, 0x2a, 0x30, 0x28, 0x24, 0x24, 0x3c, 0x24, 0x28, 0x3a, 0x32, 0x2a, 0x2c, 0x2a, 0x2a, 0x36, 0x3a, 0x2a, 0x28, 0x2c, 0x30, 0x30, 0x32, 0x32, 0x2e, 0x2c, 0x30, 0x3c, 0x32, 0x32, 0x38, 0x3a, 0x32, 0x32, 0x38, 0x3a, 0x38 }; static char *NextLine (const char *pData); static int CopyLine (char *pDest, const char *pSrc); static int LineToStr (char *pDest, const char *pSrc); static char *FindSymbol (char *pSym, char *pData, int datasize); static int ExportBitmap (FFEBitmap *pBitmap, char *pFilename); static int ReadData (char *&pSrc, UCHAR *pData); int main (int argc, char **argv) { FILE *pFile; int filesize, i; char *pImage, *pCur, *pBitmap; static UCHAR pData[100000]; static char pLStr[10000]; char pFilename[20]; if (argc!=3) { fprintf (stderr, "Wrong number of arguments\n"); fprintf (stderr, "Syntax: exppics [listsym] [datafile]\n"); return 1; } pFile = fopen (argv[2], "rt"); if (pFile == NULL) { fprintf (stderr, "Couldn't open file %s\n", argv[2]); return 1; } fseek (pFile, 0, SEEK_END); filesize = ftell (pFile); fseek (pFile, 0, SEEK_SET); pImage = (char *) malloc (filesize+1); filesize = fread (pImage, 1, filesize, pFile); fclose (pFile); pImage[filesize] = 0; i=0; pCur = FindSymbol (argv[1], pImage, filesize); if (!pCur) { fprintf (stderr, "Symbol %s not found\n", argv[1]); return 1; } for (i=0; pCur-pImage < filesize; pCur = NextLine (pCur), i++) { char *pTok; LineToStr (pLStr, pCur); printf ("pLStr = %s\n", pLStr); pTok = strtok (pLStr, " \t\r"); if (pTok == NULL || strcmp (pTok, "dd")) { printf ("Breaking at pTok = %s\n", pTok); break; } pTok = strtok (NULL, " \t\r"); pTok = FindSymbol (pTok, pImage, filesize); if (!pTok) continue; sprintf (pFilename, "ffe%03i.bmp", i); ReadData (pTok, pData); int rval = ExportBitmap ((FFEBitmap *)pData, pFilename); if (!rval) fprintf (stderr, "Failed to write file %s", pFilename); } free (pImage); return 0; } // ASCII line processing functions static char *NextLine (const char *pData) { char *pNext = strchr (pData, 0xa); return ++pNext; } static int CopyLine (char *pDest, const char *pSrc) { char *pEnd = strchr (pSrc, 0xa); int strsize = int(pEnd - pSrc); strncpy (pDest, pSrc, strsize+1); return strsize; } static int LineToStr (char *pDest, const char *pSrc) { char *pEnd = strchr (pSrc, 0xa); int strsize = int(pEnd - pSrc); strncpy (pDest, pSrc, strsize); pDest[strsize] = NULL; return strsize; } static char *FindSymbol (char *pSym, char *pData, int datasize) { static char pLStr[100000]; char *pCur = pData; int pos, len; int symlen = strlen (pSym); for (; pCur-pData < datasize; pCur = NextLine (pCur)) { len = LineToStr (pLStr, pData); printf pos = strspn (pLStr, " \t\r"); if (pos >= len) continue; if (!strncmp (pLStr, pSym, symlen)) continue; return NextLine (pCur); } return NULL; } // Generalised NASM format data reader static int ReadData (char *&pSrc, UCHAR *pData) { int n = 0, i = 0; static char pLStr[100000]; LineToStr (pLStr, pSrc); while (1) // Per-line loop { i = strspn (pLStr, "\t "); if (strncmp (pLStr+i, "db ", 3)) break; i += strcspn (pLStr+i, "0'"); while (pLStr[i] != 0) { if (pLStr[i] == '0') { pData[n++] = strtol (pLStr+i, NULL, 0); i += strcspn (pLStr+i, ","); } else { int nextq = strcspn (pLStr+i+1, "'"); strncpy ((char *)pData+n, pLStr+i+1, nextq); i += nextq + 2; n += nextq; } i += strcspn (pLStr+i, "0'"); } pSrc = NextLine (pSrc); LineToStr (pLStr, pSrc); } return n; } // FFEBitmap export function static int ExportBitmap (FFEBitmap *pBitmap, char *pFilename) { int i, j, w, h, sw; ULONG zero, col; USHORT pHead[27]; // Complete header size FILE *pFile; for (i=0; i<27; i++) pHead[i] = 0; // Zero whole header w = pBitmap->height; h = pBitmap->width; sw = w + 3 & -4; zero = 0; pFile = fopen (pFilename, "wb"); if (pFile == NULL) return 0; pHead[0] = 0x4D42; // RgbMap type 'BM' *(ULONG *)(pHead+1) = 54 + 256*4 + sw*h; // Total filesize pHead[5] = 54 + 256*4; // Offset to data pHead[7] = 40; // Size of info structure pHead[9] = USHORT(w); // Width pHead[11] = USHORT(h); // Height pHead[13] = 1; // Planes pHead[14] = 8; // Bpp fwrite (pHead, 2, 27, pFile); // Write header for (i=0; i<128; i++) { ULONG col = (ULONG(pFFEPal[i*3]) << 2) + (ULONG(pFFEPal[i*3+1]) << 10) + (ULONG(pFFEPal[i*3+2]) << 18); fwrite (&col, 4, 1, pFile); // Write Palette } for (i=0; i<128; i++) fwrite (&zero, 4, 1, pFile); for (i=(h-1)*w; i>=0; i-=w) { fwrite (pBitmap->pData+i+j, 1, w, pFile); // Write data fwrite (&zero, 1, sw-w, pFile); // Write padding } fclose (pFile); return 1; }