home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / graphic / showbmp / bitmap.c next >
Text File  |  1990-06-19  |  13KB  |  263 lines

  1. #define PROGRAM       "BITMAP"         // Program Name
  2. #define LEVEL         "Level 00"       // Program Level
  3. #define COPYRIGHT     "Copyright (c) 1990 George S. Brickner"
  4.  
  5. #pragma title (PROGRAM " " LEVEL " - Process Bitmap")
  6. #pragma linesize(120)
  7. #pragma pagesize(55)
  8.  
  9. /*****************************************************************************
  10. **                                                                          **
  11. **          BITMAP - Load an OS/2 bitmap into a Device Memory Context       **
  12. **                      Level 00, June 19th, 1990                           **
  13. **                                                                          **
  14. *****************************************************************************/
  15. #define  INCL_DOS                      // Include OS/2 Doscalls
  16. #define  INCL_GPI                      // Include OS/2 PM GPI Calls
  17. #define  INCL_WIN                      // Include OS/2 PM Win Calls
  18. #define  INCL_BITMAPFILEFORMAT         // Include OS/2 PM Bitmap File Hdr
  19. #define  INCL_ERRORS                   // Include All OS/2 Errors
  20. #include <os2.h>                       // Standard OS/2 Definitions
  21.  
  22. #include <mt\process.h>                // C/2 Standard Process Defs
  23. #include <mt\string.h>                 // C/2 Standard String Defs
  24. #include <mt\stdlib.h>                 // C/2 Standard Library Defs
  25. #include <mt\stdio.h>                  // C/2 Standard I/O Defs
  26.  
  27. #include <SHOWBMP.h>                   // SHOWBMP header file
  28. #include <BITMAP.h>                    // BITMAP header file
  29.  
  30. static CHAR const eyepopper[] = PROGRAM "-" LEVEL "-" __TIMESTAMP__ "-" COPYRIGHT;
  31.  
  32. #pragma subtitle ("Read Bitmap File")
  33. #pragma page()
  34. /**********************************************************************
  35. **                         Read Bitmap File                          **
  36. **********************************************************************/
  37. static USHORT ReadBitmapFile (HFILE Han, PVOID Buffer, USHORT Length, ULONG Rba)
  38.   {
  39.   USHORT  rc = NO_ERROR;               // Return code
  40.   USHORT  ActSize = 0;                 // Actual bytes read
  41.   ULONG   NewRba = 0;                  // New RBA
  42.  
  43.     rc = DosChgFilePtr (Han, Rba, FILE_BEGIN, &NewRba); // Seek to RBA
  44.  
  45.     if (rc == NO_ERROR)                // Successful - read data
  46.       {
  47.         rc = DosRead (Han, Buffer, Length, &ActSize);
  48.  
  49.         if (rc == NO_ERROR && ActSize != Length)  // Must be EOF
  50.           {
  51.             rc = ERRBMP_RC_END_OF_FILE;
  52.           }
  53.       }
  54.  
  55.     return rc;                         // Return to caller
  56.   }
  57.  
  58. #pragma subtitle ("Load Bit Map")
  59. #pragma page()
  60. /**********************************************************************
  61. **              Create Bit Map In Memory Device Context              **
  62. **********************************************************************/
  63. USHORT CreateBitmap (PBMPCTL pCtl)
  64.   {
  65.   USHORT  rc = NO_ERROR;               // Return code
  66.   USHORT  OpenAction;                  // Open actions
  67.   USHORT  cbHeader;                    // Header & color table size in bytes
  68.   USHORT  cbAdj;                       // Adjustment
  69.   USHORT  i;                           // Scanline & color table index
  70.   ULONG   Rba = 0L;                    // Bitmap file RBA
  71.   HFILE   hFile;                       // Bitmap file handle
  72.   SIZEL   sizl;                        // Size
  73.  
  74.     rc = DosOpen (                     // Open bitmap file for input
  75.         pCtl->pFileName,               // Bitmap file name
  76.         &hFile,                        // Bitmap file handle
  77.         &OpenAction,                   // Open action taken
  78.         0L,                            // File size - not used
  79.         FILE_NORMAL,
  80.         OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
  81.         OPEN_ACCESS_READONLY       | OPEN_SHARE_DENYNONE,
  82.         NULL                           // Reserved
  83.       );
  84.  
  85.     if (rc == NO_ERROR)                // Process bitmap file
  86.       {
  87.         cbHeader = sizeof (BITMAPFILEHEADER);  // Bitmap file header size
  88.         rc = ReadBitmapFile (hFile, &pCtl->Hdr, cbHeader, Rba); // Read bit map file hdr
  89.  
  90.         if (rc == NO_ERROR)            // Success - process header
  91.           {
  92.             if (pCtl->Hdr.usType == BFT_BMAP ||  // Bitmap is valid file type
  93.                 pCtl->Hdr.usType == BFT_ICON ||  // Icon is valid file type
  94.                 pCtl->Hdr.usType == BFT_POINTER) // Pointer is valid file type
  95.               {
  96.                 pCtl->cbLine = (pCtl->Hdr.bmp.cx * pCtl->Hdr.bmp.cBitCount) / 8; // Scan line size
  97.                 if ((pCtl->Hdr.bmp.cx * pCtl->Hdr.bmp.cBitCount) % 8) // Add another byte
  98.                   {
  99.                     pCtl->cbLine++;
  100.                   }
  101.                 cbAdj = pCtl->cbLine % sizeof (ULONG); // Compute required adjustment
  102.                 if (cbAdj)                       // Round to multiple of ULONG
  103.                   {
  104.                     pCtl->cbLine += (sizeof (ULONG) - cbAdj);
  105.                   }
  106.                 pCtl->cLines = pCtl->Hdr.bmp.cy;   // Number of scan lines
  107.  
  108.                 pCtl->cColors = 1 << pCtl->Hdr.bmp.cBitCount;  // Get color count
  109.                 cbHeader = sizeof (BITMAPINFOHEADER) + (sizeof (RGB) * pCtl->cColors);
  110.  
  111.                 pCtl->pBmi = calloc (1, cbHeader); // Allocate bitmap info & color table
  112.  
  113.                 if (pCtl->pBmi)            // Bitmap info block allocated
  114.                   {
  115.                     Rba = (ULONG)(sizeof (BITMAPFILEHEADER) - sizeof (BITMAPINFOHEADER));
  116.                     rc = ReadBitmapFile (hFile, pCtl->pBmi, cbHeader, Rba);  // Read bit map info & color table
  117.  
  118.                     if (rc == NO_ERROR)        // Success - continue
  119.                       {
  120.                         for (i=0; i < pCtl->cColors; i++) // Copy color table
  121.                           {
  122.                             pCtl->lLogColorTbl[i] = ((ULONG) pCtl->pBmi->argbColor[i].bRed * 65536L) +
  123.                                                     ((ULONG) pCtl->pBmi->argbColor[i].bGreen * 256L) +
  124.                                                     (ULONG)  pCtl->pBmi->argbColor[i].bBlue;
  125.                           }
  126.                         pCtl->pScan = calloc (1, pCtl->cbLine); // Allocate scan line buffer
  127.  
  128.                         if (pCtl->pScan)           // Success - continue
  129.                           {
  130.                             pCtl->hdcBitmap = DevOpenDC (pCtl->habThread, OD_MEMORY, "*", 0L, NULL, NULL);
  131.  
  132.                             if (pCtl->hdcBitmap != DEV_ERROR) // Success - continue
  133.                               {
  134.                                 sizl.cx = sizl.cy = 0;
  135.                                 pCtl->hpsBitmap = GpiCreatePS (pCtl->habThread, pCtl->hdcBitmap, &sizl,
  136.                                     PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
  137.  
  138.                                 if (pCtl->hpsBitmap != GPI_ERROR) // Success - Continue
  139.                                   {
  140.                                     pCtl->hbmBitmap = GpiCreateBitmap (pCtl->hpsBitmap, &pCtl->Hdr.bmp,
  141.                                         0L, NULL, NULL);
  142.  
  143.                                     if (pCtl->hbmBitmap != GPI_ERROR) // Success - Continue
  144.                                       {
  145.                                         if (GpiSetBitmap (pCtl->hpsBitmap, pCtl->hbmBitmap)
  146.                                             != HBM_ERROR) // Success - continue
  147.                                           {
  148.                                             Rba = pCtl->Hdr.offBits;   // Get bitmap RBA
  149.                                             for (i=0; i < pCtl->cLines; i++) // Read & process scan lines
  150.                                               {
  151.                                                 rc = ReadBitmapFile (  // Read bit map scan line
  152.                                                     hFile, pCtl->pScan, pCtl->cbLine, Rba);
  153.  
  154.                                                 if (rc == NO_ERROR)    // Successful
  155.                                                   {
  156.                                                     if (GpiSetBitmapBits (pCtl->hpsBitmap, (LONG) i, (LONG) 1,
  157.                                                         pCtl->pScan, pCtl->pBmi)
  158.                                                         == GPI_ALTERROR)   // Error - GpiSetBitmapBits failed
  159.                                                       {
  160.                                                         rc = ERRBMP_RC_SETBMBITS;
  161.                                                         pCtl->Err = WinGetLastError (pCtl->habThread);
  162.                                                         break;             // Exit loop
  163.                                                       }
  164.                                                     Rba += pCtl->cbLine;   // Bump to next line
  165.                                                   }
  166.                                                 else               // Scan line read failed
  167.                                                   {
  168.                                                     pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_SCANLINE_FAILED);
  169.                                                     break;         // Exit loop
  170.                                                   }
  171.                                               }
  172.                                           }
  173.                                         else  // Error - GpiSetBitmap failed
  174.                                           {
  175.                                             rc = ERRBMP_RC_SETBM;
  176.                                             pCtl->Err = WinGetLastError (pCtl->habThread);
  177.                                           }
  178.                                       }
  179.                                     else  // Error - GpiCreateBitmap failed
  180.                                       {
  181.                                         rc = ERRBMP_RC_CREATEBM;
  182.                                         pCtl->Err = WinGetLastError (pCtl->habThread);
  183.                                       }
  184.                                   }
  185.                                 else  // Error - GpiCreatePS failed
  186.                                   {
  187.                                     rc = ERRBMP_RC_CREATEPS;
  188.                                     pCtl->Err = WinGetLastError (pCtl->habThread);
  189.                                   }
  190.                               }
  191.                             else  // Error - DevOpenDC failed
  192.                               {
  193.                                 rc = ERRBMP_RC_DEVOPENDC;
  194.                                 pCtl->Err = WinGetLastError (pCtl->habThread);
  195.                               }
  196.                           }
  197.                         else                   // Bitmap scanline buffer allocation failed
  198.                           {
  199.                             rc = ERROR_NOT_ENOUGH_MEMORY;
  200.                             pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_SCANBUF_FAILED);
  201.                           }
  202.                       }
  203.                     else                       // DosRead of bitmap info/color table failed
  204.                       {
  205.                         pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_BMPINFO_FAILED);
  206.                       }
  207.                   }
  208.                 else                           // Calloc failed
  209.                   {
  210.                     rc = ERROR_NOT_ENOUGH_MEMORY;
  211.                     pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_BMPINFO_FAILED);
  212.                   }
  213.               }
  214.             else                       // Invalid file type
  215.               {
  216.                 rc = ERROR_INVALID_DATA;
  217.                 pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_INVALID_FILETYPE);
  218.               }
  219.           }
  220.         else                           // Header read failed
  221.           {
  222.             pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_HDRREAD_FAILED);
  223.           }
  224.  
  225.         DosClose (hFile);              // Close bitmap file
  226.       }
  227.     else                               // DosOpen failed
  228.       {
  229.         pCtl->Err = MAKEERRORID (SEVERITY_ERROR, ERRBMP_DOSOPEN_FAILED);
  230.       }
  231.  
  232.     if (rc)                            // Error occured - cleanup
  233.       {
  234.         DestroyBitMap (pCtl);          // Free bitmap storage
  235.       }
  236.  
  237.     return rc;                         // Return to caller
  238.   }
  239.  
  240. #pragma subtitle ("Destroy Bit Map")
  241. #pragma page()
  242. /**********************************************************************
  243. **                     Destroy Bit Map In Memory                     **
  244. **********************************************************************/
  245. VOID DestroyBitMap (PBMPCTL pCtl)
  246.   {
  247.     if (pCtl)                          // Pointer passed - ok
  248.       {
  249.         if (pCtl->pScan)               // Free scan line buffer
  250.           {
  251.             free (pCtl->pScan);
  252.           }
  253.  
  254.         if (pCtl->pBmi)                // Free Bitmap Info
  255.           {
  256.             free (pCtl->pBmi);
  257.           }
  258.         GpiDestroyPS (pCtl->hpsBitmap);    // Destroy Presentation Space
  259.         DevCloseDC (pCtl->hdcBitmap);      // Close Dev Context
  260.         GpiDeleteBitmap (pCtl->hbmBitmap); // Destroy bitmap
  261.       }
  262.   }
  263.