home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / PROG / REXX / CMD / EDMI7.ZIP / BMPINFO.ZIP / BMPINFO.CPP next >
Encoding:
C/C++ Source or Header  |  1993-12-06  |  11.8 KB  |  385 lines

  1. /* BMPINFO - Bitmap Information display
  2.  
  3. Copyright (C) 1993 Timur Tabi
  4.  
  5. This program displays information about bit map files (bitmaps, icons, and
  6. pointers).  It supports 16-bit (version 1.2) and 32-bit (version 2.0) bit
  7. maps.
  8.  
  9. This program is most useful for programmers developing software that reads
  10. and writes OS/2 bitmaps.  It can be used to verify that your program is
  11. working correctly.
  12. */
  13.  
  14. #define INCL_GPIBITMAPS
  15. #define INCL_GPILOGCOLORTABLE
  16. #include <os2.h>
  17.  
  18. #include <stdlib.h>
  19. #include <iostream.h>
  20. #include "file.hpp"
  21.  
  22. static char *bitmap;
  23. static int fShowColors=FALSE,fShowPels=FALSE;
  24.  
  25. void pel_info(char *peldata, int cx, int cy) {
  26.   if (!fShowPels) return;
  27.  
  28.   cx=4*((cx+3)/4);                              // round up to nearest ULONG
  29.   cout << "      Bit map pel data:\n";
  30.  
  31.   long lOrigFlags=cout.flags();
  32.   cout.flags(ios::left | ios::hex | ios::uppercase);
  33.   cout.fill('0');
  34.  
  35.   for (int y=0; y<cy; y++) {
  36.     cout << "        ";
  37.     for (int x=0; x<cx; x++) {
  38.       cout.width(2);
  39.       cout << (int) peldata[x+y*cx];
  40.     }
  41.     cout << endl;
  42.   }
  43.   cout.flags(lOrigFlags);
  44. }
  45.  
  46. int ipow(int b, int e) {
  47.   int p=b;
  48.   for (int i=1; i<e; i++) p*=b;
  49.   return p;
  50. }
  51.  
  52. int bitmapinfoheader(PBITMAPINFOHEADER pbih) {
  53.   cout << "      Bitmap width: " << pbih->cx;
  54.   cout << "\n      Bitmap height: " << pbih->cy;
  55.   cout << "\n      Number of bit planes: " << pbih->cPlanes;
  56.   cout << "\n      Number of bits per pel: " << pbih->cBitCount;
  57.   cout << "\n      Offset at end: " << (PBYTE) &pbih->cBitCount + sizeof(pbih->cBitCount) - bitmap << endl;
  58.  
  59.   int numbits=pbih->cPlanes * pbih->cBitCount;
  60.   int size = numbits == 24 ? 0 : ipow(2,numbits);
  61.   cout << "      Num entries in color table: " << size;
  62.  
  63.   if (size) {
  64.     cout << "\n      Size of color table: " << size*sizeof(RGB) << " bytes\n";
  65.     if (fShowColors) {
  66.       RGB *prgb=((PBITMAPINFO) pbih)->argbColor;
  67.       long lOrigFlags=cout.flags();
  68.       cout.flags(ios::left | ios::hex | ios::uppercase);
  69.       cout.fill('0');
  70.       for (int i=0; i<size; i++) {
  71.         cout << "        ";
  72.         cout.width(2);
  73.         cout << i;
  74.         cout.width(2);
  75.         cout << " Red:" << (int) prgb[i].bRed;
  76.         cout.width(2);
  77.         cout << " Green:" << (int) prgb[i].bGreen;
  78.         cout.width(2);
  79.         cout << " Blue:" << (int) prgb[i].bBlue << endl;
  80.       }
  81.       cout.flags(lOrigFlags);
  82.     }
  83.   }
  84.   return size*sizeof(RGB);
  85. }
  86.  
  87. int bitmapinfoheader2(PBITMAPINFOHEADER2 pbih) {
  88.   cout << "      Bitmap width: " << pbih->cx;
  89.   cout << "\n      Bitmap height: " << pbih->cy;
  90.   cout << "\n      Number of bit planes: " << pbih->cPlanes;
  91.   cout << "\n      Number of bits per pel: " << pbih->cBitCount;
  92.   cout << "\n      Compression scheme: " << pbih->ulCompression;
  93.   switch (pbih->ulCompression) {
  94.     case BCA_UNCOMP: cout << " (Uncompressed)";           break;
  95.     case BCA_HUFFMAN1D: cout << " (Huffman)";             break;
  96.     case BCA_RLE4: cout << " (4-bit RLE)";                break;
  97.     case BCA_RLE8: cout << " (8-bit RLE)";                break;
  98.     case BCA_RLE24: cout << " (24-bit RLE)";              break;
  99.     default: cout << " (unknown)";
  100.   }
  101.   cout << "\n      Bitmap storage data length: " << pbih->cbImage;
  102.   cout << "\n      Horiz resolution: " << pbih->cxResolution;
  103.   cout << "\n      Vert resolution: " << pbih->cyResolution;
  104.   cout << "\n      Number of color indices used: " << pbih->cclrUsed;
  105.   cout << "\n      Number of important colors: " << pbih->cclrImportant;
  106.   cout << "\n      Units of measure: " << pbih->usUnits;
  107.     cout << (pbih->usUnits==BRU_METRIC ? " (pels per meter)" : " (unknown)");
  108.   cout << "\n      Reserved field: " << pbih->usReserved;
  109.   cout << "\n      Recording algorithm: " << pbih->usRecording;
  110.     cout << (pbih->usRecording==BRA_BOTTOMUP ? " (bottom-to-top)" : " (unknown)");
  111.   cout << "\n      Halftoning algorithm: " << pbih->usRendering;
  112.   switch (pbih->usRendering) {
  113.     case BRH_NOTHALFTONED: cout << " (not halftoned)";               break;
  114.     case BRH_ERRORDIFFUSION: cout << " ([Damped] Error Diffusion)";  break;
  115.     case BRH_PANDA: cout << " (PANDA)";                              break;
  116.     case BRH_SUPERCIRCLE: cout << " (Super Circle)";                 break;
  117.     default: cout << " (unknown)";
  118.   }
  119.   cout << "\n      Size value 1: " << pbih->cSize1;
  120.   cout << "\n      Size value 2: " << pbih->cSize1;
  121.   cout << "\n      Color encoding: " << pbih->ulColorEncoding;
  122.   switch (pbih->ulColorEncoding) {
  123.     case BCE_RGB: cout << " (RGB2 structures)";             break;
  124.     case BCE_PALETTE: cout << " (BCE_PALETTE)";             break;
  125.     default: cout << " (unknown)";
  126.   }
  127.   cout << "\n      Application-reserved identifier: " << pbih->ulIdentifier;
  128.   cout << "\n      Offset at end: " << (PBYTE) &pbih->ulIdentifier + sizeof(pbih->ulIdentifier) - bitmap << endl;
  129.  
  130.   int size,numbits=pbih->cPlanes * pbih->cBitCount;
  131.   if (numbits != 24)
  132.     size = pbih->cclrUsed ? pbih->cclrUsed : ipow(2,numbits);
  133.   else
  134.     size=pbih->cclrUsed;
  135.   cout << "      Num entries in color table: " << size;
  136.  
  137.   PRGB2 prgb=((PBITMAPINFO2) pbih)->argbColor;
  138.   if (size) {
  139.     cout << "\n      Size of color table: " << size*sizeof(RGB2) << " bytes\n";
  140.     if (fShowColors) {
  141.       long lOrigFlags=cout.flags();
  142.       cout.flags(ios::left | ios::hex | ios::uppercase);
  143.       cout.fill('0');
  144.       for (int i=0; i<size; i++) {
  145.         cout << "        ";
  146.         cout.width(2);
  147.         cout << i;
  148.         cout.width(2);
  149.         cout << " Red:" << (int) prgb[i].bRed;
  150.         cout.width(2);
  151.         cout << " Green:" << (int) prgb[i].bGreen;
  152.         cout.width(2);
  153.         cout << " Blue:" << (int) prgb[i].bBlue;
  154.         cout.width(2);
  155.         cout << " Options: " << (int) prgb[i].fcOptions;
  156.         if (prgb[i].fcOptions) {
  157.           cout << " (";
  158.           if (prgb[i].fcOptions & PC_RESERVED)
  159.             cout << " RESERVED ";
  160.           if (prgb[i].fcOptions & PC_EXPLICIT)
  161.             cout << " EXPLICIT ";
  162.           cout << ")";
  163.         }
  164.         cout << endl;
  165.       }
  166.       cout.flags(lOrigFlags);
  167.     }
  168.   }
  169.   return size*sizeof(RGB2);
  170. }
  171.  
  172. int single(PBITMAPFILEHEADER pbfh) {
  173.   cout << "   Offset: " << (PBYTE) pbfh - bitmap;
  174.   cout << "\n   Type: ";
  175.   switch(pbfh->usType) {
  176.     case BFT_BMAP:
  177.       cout << "bitmap\n";
  178.       break;
  179.     case BFT_ICON:
  180.       cout << "icon\n";
  181.       break;
  182.     case BFT_POINTER:
  183.       cout << "pointer\n";
  184.       break;
  185.     case BFT_COLORICON:
  186.       cout << "color icon\n";
  187.       break;
  188.     case BFT_COLORPOINTER:
  189.       cout << "color pointer\n";
  190.       break;
  191.   }
  192.  
  193.   if (pbfh->usType != BFT_BMAP)
  194.     cout << "   Hot Spot: (" << pbfh->xHotspot << ',' << pbfh->yHotspot << ")\n";
  195.  
  196.   cout << "   Offset to pel data: " << pbfh->offBits << "\n";
  197.  
  198.   int size=bitmapinfoheader(&pbfh->bmp);
  199.   pel_info(bitmap+pbfh->offBits,pbfh->bmp.cx,pbfh->bmp.cy);
  200.   return size;
  201. }
  202.  
  203. int single2(PBITMAPFILEHEADER2 pbfh) {
  204.   cout << "   Offset: " << (PBYTE) pbfh - (PBYTE) bitmap;
  205.   cout << "\n   Type: ";
  206.   switch(pbfh->usType) {
  207.     case BFT_BMAP:
  208.       cout << "bitmap\n";
  209.       break;
  210.     case BFT_ICON:
  211.       cout << "icon\n";
  212.       break;
  213.     case BFT_POINTER:
  214.       cout << "pointer\n";
  215.       break;
  216.     case BFT_COLORICON:
  217.       cout << "color icon\n";
  218.       break;
  219.     case BFT_COLORPOINTER:
  220.       cout << "color pointer\n";
  221.       break;
  222.   }
  223.  
  224.   if (pbfh->usType != BFT_BMAP)
  225.     cout << "   Hot Spot: (" << pbfh->xHotspot << ',' << pbfh->yHotspot << ")\n";
  226.  
  227.   cout << "   Offset to pel data: " << pbfh->offBits << "\n";
  228.  
  229.   int size=bitmapinfoheader2(&pbfh->bmp2);
  230.   pel_info(bitmap+pbfh->offBits,pbfh->bmp2.cx,pbfh->bmp2.cy);
  231.   return size;
  232. }
  233.  
  234. void multiple(PBITMAPARRAYFILEHEADER pbafhFirst) {
  235.   PBITMAPARRAYFILEHEADER pbafh=pbafhFirst;
  236.   PBITMAPFILEHEADER pbfh;
  237.   int fValid=0;
  238.  
  239.   do {
  240.     cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
  241.  
  242.     cout << "\nOffset to next: " << pbafh->offNext;
  243.     cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
  244.  
  245.     pbfh=&pbafh->bfh;
  246.     do {
  247.       pbfh=(PBITMAPFILEHEADER) ((PBYTE) pbfh + single(pbfh));
  248.       pbfh++;
  249.       fValid=FALSE;
  250.       switch (pbfh->usType) {
  251.         case BFT_BMAP:
  252.         case BFT_ICON:
  253.         case BFT_POINTER:
  254.         case BFT_COLORICON:
  255.         case BFT_COLORPOINTER:
  256.           fValid=TRUE;
  257.       }
  258.     } while (fValid);
  259.     pbafh=(PBITMAPARRAYFILEHEADER) ((PBYTE) pbafhFirst+pbafh->offNext);
  260.   } while (pbafh != pbafhFirst);
  261. /*
  262.   PBITMAPARRAYFILEHEADER pbafh=pbafhFirst;
  263.  
  264.   do {
  265.     cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
  266.  
  267.     cout << "\nOffset to next: " << pbafh->offNext;
  268.     cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
  269.     single(&pbafh->bfh);
  270.     pbafh=(PBITMAPARRAYFILEHEADER) ((PBYTE) pbafhFirst+pbafh->offNext);
  271.   } while (pbafh != pbafhFirst);
  272. */
  273. }
  274.  
  275. void multiple2(PBITMAPARRAYFILEHEADER2 pbafhFirst) {
  276.   PBITMAPARRAYFILEHEADER2 pbafh=pbafhFirst;
  277.   PBITMAPFILEHEADER2 pbfh;
  278.   int fValid=0;
  279.  
  280.   do {
  281.     cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
  282.  
  283.     cout << "\nOffset to next: " << pbafh->offNext;
  284.     cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
  285.  
  286.     pbfh=&pbafh->bfh2;
  287.     do {
  288.       pbfh=(PBITMAPFILEHEADER2) ((PBYTE) pbfh + single2(pbfh));
  289.       pbfh++;
  290.       fValid=FALSE;
  291.       switch (pbfh->usType) {
  292.         case BFT_BMAP:
  293.         case BFT_ICON:
  294.         case BFT_POINTER:
  295.         case BFT_COLORICON:
  296.         case BFT_COLORPOINTER:
  297.           fValid=TRUE;
  298.       }
  299.     } while (fValid);
  300.     pbafh=(PBITMAPARRAYFILEHEADER2) ((PBYTE) pbafhFirst+pbafh->offNext);
  301.   } while (pbafh != pbafhFirst);
  302. /*
  303.   PBITMAPARRAYFILEHEADER2 pbafh=pbafhFirst;
  304.  
  305.   do {
  306.     cout << "\nOffset: " << (PBYTE) pbafh - (PBYTE) bitmap;
  307.  
  308.     cout << "\nOffset to next: " << pbafh->offNext;
  309.     cout << "\nDevice dimensions: " << pbafh->cxDisplay << " x " << pbafh->cyDisplay << "\n";
  310.  
  311.     single2(&pbafh->bfh2);
  312.     pbafh=(PBITMAPARRAYFILEHEADER2) ((PBYTE) pbafhFirst+pbafh->offNext);
  313.   } while (pbafh != pbafhFirst);
  314. */
  315. }
  316.  
  317. void error_exit(int errorcode) {
  318.   cout << "Usage: BMPINFO [/c] [/p] filename\n";
  319.   cout << " /c  show color table\n";
  320.   cout << " /p  show pel data in hex format";
  321.   exit(errorcode);
  322. }
  323.  
  324. #pragma pack(1)
  325.  
  326. int main(int argc, char **argv) {
  327.   char *szFile=NULL;
  328.  
  329.   if (argc < 2) error_exit(1);
  330.  
  331.   for (int i=1; i<argc; i++) {
  332.     if (!strnicmp(argv[i],"/p",2)) 
  333.       fShowPels=TRUE;
  334.     else if (!strnicmp(argv[i],"/c",2)) 
  335.       fShowColors=TRUE;
  336.     else
  337.       szFile=argv[i];
  338.   }
  339.  
  340.   if (!szFile) error_exit(1);
  341.  
  342.   int length=load(szFile,bitmap);
  343.   if (!length) error_exit(2);
  344.  
  345.   cout << "filesize = " << length << ".\n";
  346.  
  347.   typedef struct {
  348.     USHORT usType;
  349.     ULONG cbSize;
  350.   } HEADER;            // the header of a bafh or bfh
  351.  
  352.   HEADER *phdr=(HEADER *) bitmap;
  353.  
  354.   if (phdr->usType == BFT_BITMAPARRAY) {
  355.     cout << "Multiple bitmap file, ";
  356.     switch (phdr->cbSize) {
  357.       case sizeof(BITMAPARRAYFILEHEADER):
  358.         cout << "version 1.2\n";
  359.         multiple((PBITMAPARRAYFILEHEADER) bitmap);
  360.         break;
  361.       case sizeof(BITMAPARRAYFILEHEADER2):
  362.         cout << "version 2.0\n";
  363.         multiple2((PBITMAPARRAYFILEHEADER2) bitmap);
  364.         break;
  365.       default:
  366.         cout << "unknown version\n";
  367.     }
  368.   } else {
  369.     cout << "Single bitmap file, ";
  370.     switch (phdr->cbSize) {
  371.       case sizeof(BITMAPFILEHEADER):
  372.         cout << "version 1.2\n";
  373.         single((PBITMAPFILEHEADER) bitmap);
  374.         break;
  375.       case sizeof(BITMAPFILEHEADER2):
  376.         cout << "version 2.0\n";
  377.         single2((PBITMAPFILEHEADER2) bitmap);
  378.         break;
  379.       default:
  380.         cout << "unknown version, size: " << phdr->cbSize << '\n';
  381.     }
  382.   }
  383.   return 0;
  384. }
  385.