home *** CD-ROM | disk | FTP | other *** search
- // PRC2BMP
- //
- // Takes a Pilot resource database (PRC) file extracts the icon and
- // saves it as a .bmp file.
- //
- // Written by Scott Ludwig (scottlu@eskimo.com).
- // .PRC reading pulled from PRC2BIN by Darrin Massena (darrin@massena.com)
- // 8 Aug 96
-
- #include <Windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- // My favorite lower case types
-
- typedef unsigned char byte; // b
- typedef unsigned short ushort; // us
- typedef unsigned long ulong; // ul
- #pragma warning(disable : 4237) // disable bool keyword warning
- typedef BOOL bool; // f
-
- #define SWAPPER
- #include "swapper.h"
-
- typedef ulong FourCC;
-
- const ulong kcbHeader = 0x4e;
- byte gabHeader[kcbHeader];
-
- #pragma pack(2)
- struct ResourceMapEntry {
- ulong fcType;
- ushort id;
- ulong ulOffset;
- };
- #pragma pack()
-
- ResourceMapEntry garme[2000]; // should be enough
- byte gabResData[65536]; // should be plenty
-
- void tAIBToBmpSave(const char *pszOutName);
-
- /////////////////////////////////////////////////////////////////////////////
-
- void main(int cpszArgs, char *apszArgs[])
- {
- if (cpszArgs < 2 || strcmp(apszArgs[1], "-?") == 0) {
- printf("prc2bmp 1.0 -- Extracts icon from .prc and saves as .bmp\n"
- "by Scott Ludwig (scottlu@eskimo.com)\n\n"
- "Usage: prc2bmp <PRC file or wildcard such as *.prc>\n");
- exit(1);
- }
-
- char *pszFilename = apszArgs[1];
-
- WIN32_FIND_DATA fd;
- HANDLE h = FindFirstFile(pszFilename, &fd);
- if (h == INVALID_HANDLE_VALUE) {
- printf("Error: Can't open input file \"%s\"\n", pszFilename);
- exit(1);
- }
-
- // Split the path from the original
-
- char szDrive[_MAX_PATH];
- char szDir[_MAX_PATH];
- _splitpath(pszFilename, szDrive, szDir, NULL, NULL);
-
-
- char szFullPath[_MAX_PATH];
- do {
- // Create full path to file
-
- strcpy(szFullPath, szDrive);
- strcat(szFullPath, szDir);
- strcat(szFullPath, fd.cFileName);
-
- // Open the file
-
- FILE *pfil = fopen(szFullPath, "rb");
- if (pfil == NULL || pfil == (FILE *)-1) {
- printf("Error: Can't open input file \"%s\"\n", szFullPath);
- exit(1);
- }
-
- // Read the PRC header.
-
- if (fread(gabHeader, sizeof(gabHeader), 1, pfil) != 1) {
- printf("Error: Can't read %s's PRC header\n", szFullPath);
- exit(1);
- }
-
- //
- // Loop through all the resources, suck 'em in and spit 'em out.
- //
-
- ulong cres = ReverseLong(*(ulong *)(gabHeader + kcbHeader - 4));
-
- // Read the resource map.
-
- ResourceMapEntry *prme = garme;
- for (ulong i = 0; i < cres; i++, prme++) {
-
- if (fread(prme, sizeof(ResourceMapEntry), 1, pfil) != 1) {
- printf("Error: Can't read the resource map\n");
- exit(1);
- }
- prme->id = SwapBytes(prme->id);
- prme->ulOffset = ReverseLong(prme->ulOffset);
- }
-
-
- char szOutName[_MAX_PATH];
- _splitpath(szFullPath, NULL, NULL, szOutName, NULL);
- strcat(szOutName, ".bmp");
-
- // Read each resource and write it out as a new file.
-
- char szType[5];
- szType[4] = 0;
- prme = garme;
- for (i = 0; i < cres; i++, prme++) {
- *(ulong *)szType = prme->fcType;
-
- ulong cbres;
- if (i + 1 < cres)
- cbres = garme[i + 1].ulOffset - prme->ulOffset;
- else
- cbres = 65536;
-
- fseek(pfil, prme->ulOffset, SEEK_SET);
- cbres = fread(gabResData, 1, cbres, pfil);
- if (cbres == 0) {
- printf("Error: Can't read the resource %s\n", szOutName);
- exit(1);
- }
-
- // If not the icon, continue
-
- if (strcmp(szType, "tAIB") != 0)
- continue;
-
- // Convert pilot icon bits into windows bitmap
-
- tAIBToBmpSave(szOutName);
- printf("Bitmap %s written.\n", szOutName);
- break;
- }
-
- fclose(pfil);
-
- } while (FindNextFile(h, &fd));
-
- FindClose(h);
- printf("Done.\n");
- }
-
- // Pilot bitmap format (also format of icon)
-
- typedef struct _Bitmap { // bm
- ushort cx;
- ushort cy;
- ushort cbRow;
- ushort ff;
- ushort ausUnk[4];
- byte abBits[1]; // word aligned bits
- } Bitmap;
-
- // Test bit in a 1bpp bitmap
-
- BOOL TestBit(int cx, int cy, byte *pb, int x, int y, int cBitsAlign)
- {
- int cbRow = (cx + (cBitsAlign - 1)) & ~(cBitsAlign - 1);
- pb += (cbRow >> 3) * y + (x >> 3);
- return (*pb & (1 << (7 - (x & 7))));
- }
-
- // Set bit in a 1bpp bitmap
-
- void SetBit(int cx, int cy, byte *pb, int x, int y, int cBitsAlign)
- {
- int cbRow = (cx + (cBitsAlign - 1)) & ~(cBitsAlign - 1);
- pb += (cbRow >> 3) * y + (x >> 3);
- *pb |= (1 << (7 - (x & 7)));
- }
-
- void tAIBToBmpSave(const char *pszOutName)
- {
- // Only first 32 cx, 22 cy pixels shown in app dialog
- #define kcxIcon 32
- #define kcyIcon 22
- #define kcbBmpBits (kcxIcon / 8 * kcyIcon)
-
- BITMAPFILEHEADER bfh;
- memset(&bfh, 0, sizeof(bfh));
- bfh.bfType = 'B' | ((unsigned short)'M' << 8);
- bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
- 2 * sizeof(RGBQUAD) + kcbBmpBits;
- bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
- 2 * sizeof(RGBQUAD);
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
- bmi.bmiHeader.biWidth = kcxIcon;
- bmi.bmiHeader.biHeight = kcyIcon;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 1;
- bmi.bmiHeader.biSizeImage = kcbBmpBits;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biClrUsed = 2;
- bmi.bmiHeader.biClrImportant = 2;
-
- // Convert bits. Fill bits off first, then turn on where pilot bits
- // are off
-
- byte *pbNew = &gabResData[8192];
- memset(pbNew, 0, kcbBmpBits);
-
- Bitmap *pbm = (Bitmap *)gabResData;
- pbm->cx = SwapBytes(pbm->cx);
- pbm->cy = SwapBytes(pbm->cy);
-
- for (int y = 0; y < kcyIcon; y++) {
- for (int x = 0; x < kcxIcon; x++) {
- if (!TestBit(pbm->cx, pbm->cy, pbm->abBits, x, y, 16))
- SetBit(kcxIcon, kcyIcon, pbNew, x, kcyIcon - y - 1, 32);
- }
- }
-
- // Write it out!
-
- FILE *pfilOut = fopen(pszOutName, "wb");
- if (pfilOut == NULL || pfilOut == (FILE *)-1) {
- printf("Error: Can't open the output file %s\n", pszOutName);
- exit(1);
- }
-
- // Write header and bitmapinfo
-
- fwrite(&bfh, sizeof(bfh), 1, pfilOut);
- fwrite(&bmi, sizeof(bmi) - sizeof(RGBQUAD), 1, pfilOut);
-
- // Write color table
-
- ulong ul = 0;
- fwrite(&ul, sizeof(ul), 1, pfilOut);
- ul = 0x00FFFFFF;
- fwrite(&ul, sizeof(ul), 1, pfilOut);
-
- // Write bits
-
- fwrite(pbNew, kcbBmpBits, 1, pfilOut);
- fclose(pfilOut);
- }
-