home *** CD-ROM | disk | FTP | other *** search
- /* BMPINFO - Bitmap Information display
-
- Copyright (C) 1993 Timur Tabi
-
- This program displays information about bit map files (bitmaps, icons, and
- pointers). It supports 16-bit (version 1.2) and 32-bit (version 2.0) bit
- maps.
-
- This program is most useful for programmers developing software that reads
- and writes OS/2 bitmaps. It can be used to verify that your program is
- working correctly.
- */
-
- #define INCL_GPIBITMAPS
- #define INCL_GPILOGCOLORTABLE
- #include <os2.h>
-
- #include <stdlib.h>
- #include <iostream.h>
- #include "file.hpp"
-
- static char *bitmap;
- static int fShowColors=FALSE,fShowPels=FALSE;
-
- void pel_info(char *peldata, int cx, int cy) {
- if (!fShowPels) return;
-
- cx=4*((cx+3)/4); // round up to nearest ULONG
- cout << " Bit map pel data:\n";
-
- long lOrigFlags=cout.flags();
- cout.flags(ios::left | ios::hex | ios::uppercase);
- cout.fill('0');
-
- for (int y=0; y<cy; y++) {
- cout << " ";
- for (int x=0; x<cx; x++) {
- cout.width(2);
- cout << (int) peldata[x+y*cx];
- }
- cout << endl;
- }
- cout.flags(lOrigFlags);
- }
-
- int ipow(int b, int e) {
- int p=b;
- for (int i=1; i<e; i++) p*=b;
- return p;
- }
-
- int bitmapinfoheader(PBITMAPINFOHEADER pbih) {
- cout << " Bitmap width: " << pbih->cx;
- cout << "\n Bitmap height: " << pbih->cy;
- cout << "\n Number of bit planes: " << pbih->cPlanes;
- cout << "\n Number of bits per pel: " << pbih->cBitCount;
- cout << "\n Offset at end: " << (PBYTE) &pbih->cBitCount + sizeof(pbih->cBitCount) - bitmap << endl;
-
- int numbits=pbih->cPlanes * pbih->cBitCount;
- int size = numbits == 24 ? 0 : ipow(2,numbits);
- cout << " Num entries in color table: " << size;
-
- if (size) {
- cout << "\n Size of color table: " << size*sizeof(RGB) << " bytes\n";
- if (fShowColors) {
- RGB *prgb=((PBITMAPINFO) pbih)->argbColor;
- long lOrigFlags=cout.flags();
- cout.flags(ios::left | ios::hex | ios::uppercase);
- cout.fill('0');
- for (int i=0; i<size; i++) {
- cout << " ";
- cout.width(2);
- cout << i;
- cout.width(2);
- cout << " Red:" << (int) prgb[i].bRed;
- cout.width(2);
- cout << " Green:" << (int) prgb[i].bGreen;
- cout.width(2);
- cout << " Blue:" << (int) prgb[i].bBlue << endl;
- }
- cout.flags(lOrigFlags);
- }
- }
- return size*sizeof(RGB);
- }
-
- int bitmapinfoheader2(PBITMAPINFOHEADER2 pbih) {
- cout << " Bitmap width: " << pbih->cx;
- cout << "\n Bitmap height: " << pbih->cy;
- cout << "\n Number of bit planes: " << pbih->cPlanes;
- cout << "\n Number of bits per pel: " << pbih->cBitCount;
- cout << "\n Compression scheme: " << pbih->ulCompression;
- switch (pbih->ulCompression) {
- case BCA_UNCOMP: cout << " (Uncompressed)"; break;
- case BCA_HUFFMAN1D: cout << " (Huffman)"; break;
- case BCA_RLE4: cout << " (4-bit RLE)"; break;
- case BCA_RLE8: cout << " (8-bit RLE)"; break;
- case BCA_RLE24: cout << " (24-bit RLE)"; break;
- default: cout << " (unknown)";
- }
- cout << "\n Bitmap storage data length: " << pbih->cbImage;
- cout << "\n Horiz resolution: " << pbih->cxResolution;
- cout << "\n Vert resolution: " << pbih->cyResolution;
- cout << "\n Number of color indices used: " << pbih->cclrUsed;
- cout << "\n Number of important colors: " << pbih->cclrImportant;
- cout << "\n Units of measure: " << pbih->usUnits;
- cout << (pbih->usUnits==BRU_METRIC ? " (pels per meter)" : " (unknown)");
- cout << "\n Reserved field: " << pbih->usReserved;
- cout << "\n Recording algorithm: " << pbih->usRecording;
- cout << (pbih->usRecording==BRA_BOTTOMUP ? " (bottom-to-top)" : " (unknown)");
- cout << "\n Halftoning algorithm: " << pbih->usRendering;
- switch (pbih->usRendering) {
- case BRH_NOTHALFTONED: cout << " (not halftoned)"; break;
- case BRH_ERRORDIFFUSION: cout << " ([Damped] Error Diffusion)"; break;
- case BRH_PANDA: cout << " (PANDA)"; break;
- case BRH_SUPERCIRCLE: cout << " (Super Circle)"; break;
- default: cout << " (unknown)";
- }
- cout << "\n Size value 1: " << pbih->cSize1;
- cout << "\n Size value 2: " << pbih->cSize1;
- cout << "\n Color encoding: " << pbih->ulColorEncoding;
- switch (pbih->ulColorEncoding) {
- case BCE_RGB: cout << " (RGB2 structures)"; break;
- case BCE_PALETTE: cout << " (BCE_PALETTE)"; break;
- default: cout << " (unknown)";
- }
- cout << "\n Application-reserved identifier: " << pbih->ulIdentifier;
- cout << "\n Offset at end: " << (PBYTE) &pbih->ulIdentifier + sizeof(pbih->ulIdentifier) - bitmap << endl;
-
- int size,numbits=pbih->cPlanes * pbih->cBitCount;
- if (numbits != 24)
- size = pbih->cclrUsed ? pbih->cclrUsed : ipow(2,numbits);
- else
- size=pbih->cclrUsed;
- cout << " Num entries in color table: " << size;
-
- PRGB2 prgb=((PBITMAPINFO2) pbih)->argbColor;
- if (size) {
- cout << "\n Size of color table: " << size*sizeof(RGB2) << " bytes\n";
- if (fShowColors) {
- long lOrigFlags=cout.flags();
- cout.flags(ios::left | ios::hex | ios::uppercase);
- cout.fill('0');
- for (int i=0; i<size; i++) {
- cout << " ";
- cout.width(2);
- cout << i;
- cout.width(2);
- cout << " Red:" << (int) prgb[i].bRed;
- cout.width(2);
- cout << " Green:" << (int) prgb[i].bGreen;
- cout.width(2);
- cout << " Blue:" << (int) prgb[i].bBlue;
- cout.width(2);
- cout << " Options: " << (int) prgb[i].fcOptions;
- if (prgb[i].fcOptions) {
- cout << " (";
- if (prgb[i].fcOptions & PC_RESERVED)
- cout << " RESERVED ";
- if (prgb[i].fcOptions & PC_EXPLICIT)
- cout << " EXPLICIT ";
- cout << ")";
- }
- cout << endl;
- }
- cout.flags(lOrigFlags);
- }
- }
- return size*sizeof(RGB2);
- }
-
- int single(PBITMAPFILEHEADER pbfh) {
- cout << " Offset: " << (PBYTE) pbfh - bitmap;
- cout << "\n Type: ";
- switch(pbfh->usType) {
- case BFT_BMAP:
- cout << "bitmap\n";
- break;
- case BFT_ICON:
- cout << "icon\n";
- break;
- case BFT_POINTER:
- cout << "pointer\n";
- break;
- case BFT_COLORICON:
- cout << "color icon\n";
- break;
- case BFT_COLORPOINTER:
- cout << "color pointer\n";
- break;
- }
-
- if (pbfh->usType != BFT_BMAP)
- cout << " Hot Spot: (" << pbfh->xHotspot << ',' << pbfh->yHotspot << ")\n";
-
- cout << " Offset to pel data: " << pbfh->offBits << "\n";
-
- int size=bitmapinfoheader(&pbfh->bmp);
- pel_info(bitmap+pbfh->offBits,pbfh->bmp.cx,pbfh->bmp.cy);
- return size;
- }
-
- int single2(PBITMAPFILEHEADER2 pbfh) {
- cout << " Offset: " << (PBYTE) pbfh - (PBYTE) bitmap;
- cout << "\n Type: ";
- switch(pbfh->usType) {
- case BFT_BMAP:
- cout << "bitmap\n";
- break;
- case BFT_ICON:
- cout << "icon\n";
- break;
- case BFT_POINTER:
- cout << "pointer\n";
- break;
- case BFT_COLORICON:
- cout << "color icon\n";
- break;
- case BFT_COLORPOINTER:
- cout << "color pointer\n";
- break;
- }
-
- if (pbfh->usType != BFT_BMAP)
- cout << " Hot Spot: (" << pbfh->xHotspot << ',' << pbfh->yHotspot << ")\n";
-
- cout << " Offset to pel data: " << pbfh->offBits << "\n";
-
- int size=bitmapinfoheader2(&pbfh->bmp2);
- pel_info(bitmap+pbfh->offBits,pbfh->bmp2.cx,pbfh->bmp2.cy);
- return size;
- }
-
- void multiple(PBITMAPARRAYFILEHEADER pbafhFirst) {
- PBITMAPARRAYFILEHEADER pbafh=pbafhFirst;
- PBITMAPFILEHEADER pbfh;
- int fValid=0;
-
- do {
- cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
-
- cout << "\nOffset to next: " << pbafh->offNext;
- cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
-
- pbfh=&pbafh->bfh;
- do {
- pbfh=(PBITMAPFILEHEADER) ((PBYTE) pbfh + single(pbfh));
- pbfh++;
- fValid=FALSE;
- switch (pbfh->usType) {
- case BFT_BMAP:
- case BFT_ICON:
- case BFT_POINTER:
- case BFT_COLORICON:
- case BFT_COLORPOINTER:
- fValid=TRUE;
- }
- } while (fValid);
- pbafh=(PBITMAPARRAYFILEHEADER) ((PBYTE) pbafhFirst+pbafh->offNext);
- } while (pbafh != pbafhFirst);
- /*
- PBITMAPARRAYFILEHEADER pbafh=pbafhFirst;
-
- do {
- cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
-
- cout << "\nOffset to next: " << pbafh->offNext;
- cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
- single(&pbafh->bfh);
- pbafh=(PBITMAPARRAYFILEHEADER) ((PBYTE) pbafhFirst+pbafh->offNext);
- } while (pbafh != pbafhFirst);
- */
- }
-
- void multiple2(PBITMAPARRAYFILEHEADER2 pbafhFirst) {
- PBITMAPARRAYFILEHEADER2 pbafh=pbafhFirst;
- PBITMAPFILEHEADER2 pbfh;
- int fValid=0;
-
- do {
- cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
-
- cout << "\nOffset to next: " << pbafh->offNext;
- cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
-
- pbfh=&pbafh->bfh2;
- do {
- pbfh=(PBITMAPFILEHEADER2) ((PBYTE) pbfh + single2(pbfh));
- pbfh++;
- fValid=FALSE;
- switch (pbfh->usType) {
- case BFT_BMAP:
- case BFT_ICON:
- case BFT_POINTER:
- case BFT_COLORICON:
- case BFT_COLORPOINTER:
- fValid=TRUE;
- }
- } while (fValid);
- pbafh=(PBITMAPARRAYFILEHEADER2) ((PBYTE) pbafhFirst+pbafh->offNext);
- } while (pbafh != pbafhFirst);
- /*
- PBITMAPARRAYFILEHEADER2 pbafh=pbafhFirst;
-
- do {
- cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
-
- cout << "\nOffset to next: " << pbafh->offNext;
- cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
-
- single2(&pbafh->bfh2);
- pbafh=(PBITMAPARRAYFILEHEADER2) ((PBYTE) pbafhFirst+pbafh->offNext);
- } while (pbafh != pbafhFirst);
- */
- }
-
- void error_exit(int errorcode) {
- cout << "Usage: BMPINFO [/c] [/p] filename\n";
- cout << " /c show color table\n";
- cout << " /p show pel data in hex format";
- exit(errorcode);
- }
-
- #pragma pack(1)
-
- int main(int argc, char **argv) {
- char *szFile=NULL;
-
- if (argc < 2) error_exit(1);
-
- for (int i=1; i<argc; i++) {
- if (!strnicmp(argv[i],"/p",2))
- fShowPels=TRUE;
- else if (!strnicmp(argv[i],"/c",2))
- fShowColors=TRUE;
- else
- szFile=argv[i];
- }
-
- if (!szFile) error_exit(1);
-
- int length=load(szFile,bitmap);
- if (!length) error_exit(2);
-
- cout << "filesize = " << length << ".\n";
-
- typedef struct {
- USHORT usType;
- ULONG cbSize;
- } HEADER; // the header of a bafh or bfh
-
- HEADER *phdr=(HEADER *) bitmap;
-
- if (phdr->usType == BFT_BITMAPARRAY) {
- cout << "Multiple bitmap file, ";
- switch (phdr->cbSize) {
- case sizeof(BITMAPARRAYFILEHEADER):
- cout << "version 1.2\n";
- multiple((PBITMAPARRAYFILEHEADER) bitmap);
- break;
- case sizeof(BITMAPARRAYFILEHEADER2):
- cout << "version 2.0\n";
- multiple2((PBITMAPARRAYFILEHEADER2) bitmap);
- break;
- default:
- cout << "unknown version\n";
- }
- } else {
- cout << "Single bitmap file, ";
- switch (phdr->cbSize) {
- case sizeof(BITMAPFILEHEADER):
- cout << "version 1.2\n";
- single((PBITMAPFILEHEADER) bitmap);
- break;
- case sizeof(BITMAPFILEHEADER2):
- cout << "version 2.0\n";
- single2((PBITMAPFILEHEADER2) bitmap);
- break;
- default:
- cout << "unknown version, size: " << phdr->cbSize << '\n';
- }
- }
- return 0;
- }