home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / bitmap3.zip / BITMAP.INF (.txt) < prev    next >
OS/2 Help File  |  1994-12-03  |  18KB  |  524 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Bitmap Class Overview ΓòÉΓòÉΓòÉ
  3.  
  4.  
  5. What it does:
  6. The Bitmap class provides the means to create and manipulate bitmaps. With it, 
  7. you can load and save bitmaps which are not part of a Presentation Manager 
  8. resource. A Gpi bitmap can be used to create a Bitmap object or the object can 
  9. create a Gpi bitmap.
  10.  
  11. The class handles 1-, 4-, 8-, and 24-bpp bitmaps. It can read Windows bitmaps 
  12. as well as read and save OS/2 version 1x and 2x bitmaps.
  13.  
  14. The class was designed to provide direct access to image data in support of a 
  15. graphical rendering (raytracing) application. As such, it provides a "buffer" 
  16. for building and transferring bitmap data between an application and a Gpi 
  17. bitmap. 
  18. Member functions access the image data allowing the application to set or query 
  19. image pels independent from a device context. Other functions transfer the 
  20. image to or from a presentation space.
  21. The consequence of this is that a large amount of memory is allocated to the 
  22. image data. However, it is possible to build a Gpi bitmap from the object and 
  23. then discard the object.
  24.  
  25. What it doesn't:
  26. It does not load bitmap arrays. However, a bitmap from an array can be loaded 
  27. if the file is positioned at a bitmap file header. Neither does it save a 
  28. bitmap array. A single bitmap can be written to an array file if the file is 
  29. properly positioned. It will not update the bitmap array file header.
  30.  
  31. Several member functions will raise exceptions if the bitmap is compressed. 
  32. However, it can be decompressed. 
  33.  
  34. Tools:
  35. The class was developed using IBM C/Set++ Tools. It is provided as a DLL; it 
  36. requires the runtime libraries provided with the IBM product. They are not 
  37. distributed with the class.
  38.  
  39. Files:
  40. The DLL, LIB, HPP, and INF files are provided as "freeware". They may be freely 
  41. distributed and incorporated into any software you develop.
  42.  
  43. Support:
  44. The author will provide support via CompuServe account 70252,3144.
  45.  
  46. Source Code:
  47. Source code is available from the author for $20.00 US. The source includes 
  48. HPP, CPP, DEF and WF (HyperWise) files. Please remit to:
  49.  
  50.  William A. Leonard 
  51.  29 Bow Street 
  52.  Jamestown, RI 02835 
  53.  
  54.  
  55. Disclaimer:
  56. The author will not be liable for any bug, error, omission, defect, deficiency, 
  57. or nonconformity in this software. The author also disclaims all implied 
  58. warranties, including without limitation warranties of merchantability, 
  59. performance, and fitness for a particular purpose. This software is provided 
  60. "as is" and the user assumes the entire risk as to its quality and performance. 
  61.  
  62.  
  63. ΓòÉΓòÉΓòÉ 2. Data Members ΓòÉΓòÉΓòÉ
  64.  
  65. The following data members of the Bitmap class are private to the class:
  66.  
  67. PBITMAPINFO2 _pbmi2 
  68.   Pointer to a BITMAPINFO2 structure. The structure is created during 
  69. construction of the Bitmap object or when a bitmap is loaded. It is not 
  70. settable but can be accessed by Bitmap::bmi(). The structure is also accessible 
  71. as a BITMAPINFOHEADER2 structure. The structure is destroyed when the Bitmap 
  72. object is destroyed.
  73.  
  74. PBYTE    _pbmb
  75.   Pointer to bitmap image data. The data is in the format described by the 
  76. BITMAPINFOHEADER. The memory for this data is allocated during construction of 
  77. the Bitmap object or when a bitmap is loaded. It is not settable but can be 
  78. accessed by Bitmap::bmb().
  79.  
  80. ULONG    _ulScanlineSize
  81.   The size of a row of bitmap image data. The size is 
  82.    _pbmi2->cBitCount * _pbmi2->cx + 31) / 32)
  83.    * 4 * _pbmi2->cPlanes
  84. The value is calculated when the object is constructed or when a bitmap file is 
  85. loaded. It is not settable but can be accessed by Bitmap::scanLineSize().
  86.  
  87. IHandle    _hdc
  88.   Handle to device context. This is set when a Gpi bitmap is created from 
  89. Bitmap::createGpiBitmap(). Otherwise, it is not settable. It can be accessed by 
  90. Bitmap::hdc(). The DC is closed when the Bitmap object is destroyed.
  91.  
  92. IPresSpaceHandle  _hps 
  93.   Handle to a presentation space. This is set when a Gpi bitmap is created from 
  94. Bitmap::createGpiBitmap(). Otherwise it is not settable. It can be accessed by 
  95. Bitmap::hps(). The PS is destroyed when the Bitmap object is destroyed.
  96.  
  97. IHandle    _hpal
  98.   Handle to a palette if palette manager functions are supported. This is set 
  99. when a Gpi bitmap is created from Bitmap::createGpiBitmap(). Otherwise it is 
  100. not settable. It can be accessed by Bitmap::hpal(). The palette is destroyed 
  101. when the bitmap object is destroyed.
  102.  
  103. IBitmapHandle _hbm 
  104.   Handle to a Gpi bitmap. This is set when the Gpi bitmap is created from 
  105. Bitmap::createGpiBitmap(). Otherwise it is not settable. It can be accessed by 
  106. Bitmap::hbm(). The Gpi bitmap is deleted when the Bitmap object is destroyed.
  107.  
  108.  
  109. ΓòÉΓòÉΓòÉ 3. Member Functions ΓòÉΓòÉΓòÉ
  110.  
  111.  
  112. ΓòÉΓòÉΓòÉ 3.1. Constructors & Destructor ΓòÉΓòÉΓòÉ
  113.  
  114. Bitmap(IString const& fname)
  115. fname - the name of an unopened bitmap file.
  116.  
  117.   This constructor will build a Bitmap object and read the header and image 
  118. data from the file. The file must not contain a bitmap array header. This 
  119. constructor does not create a Gpi bitmap - call Bitmap::createGpiBitmap(). The 
  120. file is closed after it is read.
  121.   If the image is compressed, the memory allocated for the image data is not 
  122. large enough to contain the uncompressed image.
  123.  
  124. Bitmap(const IBitmapHandle& hbmp)
  125. hbmp - handle to an existing Gpi bitmap.
  126.  
  127.   This constructor builds a Bitmap object from the first 16 bytes of 
  128. BITMAPINFOHEADER2 of the Gpi bitmap. That is, only cx, cy, cPlanes, and 
  129. cBitCount are preserved from the Gpi bitmap. Space is allocated for the color 
  130. table and bitmap image data but neither is initialized.
  131.  
  132. This constructor does not create a Gpi bitmap.
  133.  
  134.  
  135. Bitmap(PBITMAPINFOHEADER2 const pbmp)
  136. pbmp - pointer to a BITMAPINFOHEADER2.
  137.  
  138.   This constructor builds a Bitmap object from a BITMAPINFOHEADER2. The header 
  139. is copied. Space is allocated for the color table and image data but is 
  140. uninitialized. 
  141.   Use this constructor for creating a bitmap from scratch. Simply create a 
  142. BITMAPINFOHEADER2 and set: 
  143. (ULONG)cbFix = 16,
  144. (ULONG)cx,
  145. (ULONG)cy,
  146. (USHORT)cPlanes,
  147. (USHORT)cBitCount.
  148.  
  149.   If other options are desired, set those members of the structure and modify 
  150. cbFix. 
  151.  
  152.   Memory allocated for the image data is determined from cx, cy, cPlanes, and 
  153. cBitCount unless cbImage is given and is not zero. Compression is not used to 
  154. calculate the size: the default memory allocation is large enough for the 
  155. uncompressed image.
  156.  
  157.   This constructor does not create a Gpi bitmap - call Bitmap::createGpiBitmap().
  158.  
  159.  
  160. ~Bitmap()
  161.  
  162.   The destructor frees memory allocated for the BITMAPINFOHEADER2, color table, 
  163. and image data. 
  164.   If a Gpi bitmap is associated with the object, it, too, is destroyed along 
  165. with its DC, PS, and palette.
  166.   To avoid destroying the Gpi bitmap, DC, PS, and palette: call 
  167. Bitmap::disassociate() first.
  168.  
  169.  
  170. ΓòÉΓòÉΓòÉ 3.2. Accessors ΓòÉΓòÉΓòÉ
  171.  
  172. The following member functions access data of the Bitmap object - not a Gpi 
  173. bitmap. In fact, a Gpi bitmap need not exist. See Gpi Bitmap Functions for 
  174. accessing Gpi bitmaps.
  175.  
  176. PBITMAPINFOHEADER2 bmp()
  177.  
  178.   This function returns a pointer to a BITMAPINFOHEADER2 structure describing 
  179. the bitmap. Individual fields in the structure may be accessed or modified 
  180. using this pointer. Certain Gpi functions that require a pointer to a 
  181. BITMAPINFOHEADER2 may use the returned pointer.
  182.   The returned pointer may be cast to a BITMAPINFO2 structure because the color 
  183. table immediately follows the fixed portion of the structure.
  184.  
  185.  
  186. PBITMAPINFO2 bmi()
  187.  
  188.   This function returns a pointer to a BITMAPINFO2 structure describing the 
  189. bitmap. Individual fields in the structure may be accessed or modified using 
  190. this pointer. Certain Gpi functions that require a pointer to a BITMAPINFO2 may 
  191. use the returned pointer.
  192.  
  193.  
  194. PRGB2 rgb(USHORT index=0)
  195. index - the index of the desired color.
  196.  
  197.   This function returns a pointer to an RGB2 structure in the color table. The 
  198. default index can be used to return the entire array. Returns NULL if this is a 
  199. 24-bpp bitmap or if the index is out of range.
  200.  
  201. PRGB2 rgb(USHORT row, USHORT col)
  202. row - the row coordinate in the image.
  203. col - the column coordinate in the image.
  204.  
  205.   Returns a pointer to the color of a pel at a specific location in the image. 
  206. For a 24-bpp bitmap, the returned pointer points to a RGB structure in the 
  207. image data. For bitmaps with a color table, the returned pointer points to a 
  208. RGB2 structure in the color table. If you use this accessor to change the rgb 
  209. value: in a 24-bpp you will change the color of a single pel; otherwise you 
  210. will change the color of all pels that share that color table entry. An 
  211. exception is raised if the image is compressed.
  212.  
  213.  
  214. PBYTE bmb(USHORT row=0, USHORT col=0)
  215. row - the row coordinate in the image.
  216. col - the column coordinate in the image.
  217.  
  218.   Returns a pointer to a byte containing bitmap bits at a specific point in the 
  219. image. The default arguments return the image data array. The default col 
  220. returns the row array. An exception is raised if the image is compressed unless 
  221. both row and col are zero.
  222.  
  223.  
  224. USHORT index(USHORT row, USHORT col)
  225. row - the row coordinate in the image.
  226. col - the column coordinate in the image.
  227.  
  228.   Returns the color index of a pel at a specific point in the image. For a 
  229. 24-bpp bitmap, returns 0xffff. An exception is raised if the image is compressed.
  230.  
  231. ULONG scanLineSize()
  232.  
  233.   Returns the size of a scan line (a row) of image data. This is always a 
  234. multiple of 4 bytes. The scanline size is calculated for an uncompressed image.
  235.  
  236.  
  237. ΓòÉΓòÉΓòÉ 3.3. Modifiers ΓòÉΓòÉΓòÉ
  238.  
  239.   The Bitmap class allocates memory for the headers, color table, and image 
  240. data. Accessors return pointers to these making them available to the 
  241. application for direct manipulation. Therefore, there is no need for member 
  242. functions to modify them... with one exception:
  243.  
  244. void setIndex(USHORT indx, USHORT row, USHORT col) 
  245. indx - the index to set.
  246. row - the row coordinate of the pel.
  247. col - the column coordinate of the pel.
  248.  
  249.   This function sets the color of a pel at the given coordinate. In a 24-bpp 
  250. bitmap, this function has no effect. Otherwise, this function masks and shifts 
  251. the color index and imbeds it in the image at the proper location.
  252.  
  253.  
  254. ΓòÉΓòÉΓòÉ 3.4. Gpi Bitmap Functions ΓòÉΓòÉΓòÉ
  255.  
  256. The Bitmap object is device independent. It is also Gpi independent. These 
  257. functions are provided to bridge the gap.
  258.  
  259. IBitmapHandle createGpiBitmap(Boolean bPal=0)
  260.  
  261.   Opens a memory DC and creates a PS. If bPal is not false, it also creates a 
  262. Gpi palette from the color table (if there is one and palette manager functions 
  263. are supported) and selects it into the PS. An initialized Gpi bitmap is created 
  264. from the BITMAPINFO2 data member and the image data. The Gpi bitmap is 
  265. associated with the Bitmap object. An exception is raised if there is already a 
  266. Gpi bitmap associated with the object.
  267.  
  268.  
  269. void blitTo(IPresSpaceHandle hps, IPoint& destPt, IRectangle& sourceRect)
  270. hps - the target presentation space handle.
  271. destPt - the lower left corner of the rectangle in the target hps.
  272. sourceRect - the rectangle defining the area in the image to be transferred.
  273.  
  274.   Performs GpiDrawBits() from the Bitmap object's image data to the target hps.
  275.   If the target hps is 0, this function performs GpiDrawBits() to the 
  276. associated Gpi bitmap's PS. Otherwise, the target hps may need to have a Gpi 
  277. bitmap selected - see the documentation for GpiDrawBits().
  278.   sourceRect defines the rectangle of image data. It is intersected with the 
  279. bitmap. The result is used for the transfer. destPt defines the lower left 
  280. corner of the rectangle in hps. It is adjusted as necessary for the 
  281. intersection rectangle. The source and (implied) target rectangles are the same 
  282. size. The blit operation is limited to ROP_SRCCOPY, BBO_IGNORE. For other 
  283. options, call the Gpi function directly.
  284.  
  285. void blitTo(IPresSpaceHandle hps = 0)
  286. hps - the target presentation space 
  287.  
  288.   Performs GpiDrawBits() from the Bitmap object's image data to the target hps.
  289.   If the target hps is 0, this function performs GpiDrawBits() to the 
  290. associated Gpi bitmap's PS. Otherwise, the target hps may need to have a Gpi 
  291. bitmap selected - see the documentation for GpiDrawBits().
  292.   The entire bitmap is transferred.
  293.  
  294. void blitFrom(IPresSpaceHandle hps, IPoint& sourcePt, IRectangle& destRect)
  295. hps - the source presentation space handle.
  296. sourcePt - the lower left corner of the source rectangle in the hps.
  297. destRect - the destination rectangle in the object's image data.
  298.  
  299.   Performs a GpiQueryBitmapBits() from the source hps to the image data of the 
  300. Bitmap object. If hps is zero, then the hps data member is used as the source.
  301.   destRect defines the target rectangle. It is intersected with the bitmap and 
  302. the result is used in the transfer. sourcePt defines the lower left corner of 
  303. the source rectangle. It is adjusted as necessary to the intersection 
  304. rectangle. The (implied) source and target rectangles are the same size.
  305.   Note that GpiQueryBitmapBits() transfers entire rows. The x coordinates of 
  306. both destRect and sourcePt are ignored. The arguments were chosen to conform to 
  307. the style of blitTo(). Also be aware that GpiQueryBitmapBits() may modify the 
  308. BITMAPINFO2 data member structure: the format of the bitmap and the color table 
  309. entries may be altered to match the presentation space/device context used as 
  310. the source.
  311.   A Gpi bitmap must be selected into the source PS.
  312.  
  313. void blitFrom(IPresSpaceHandle hps = 0)
  314. hps - the source presentation space handle.
  315.  
  316.   Performs a GpiQueryBitmapBits() from the source hps to the image data of the 
  317. Bitmap object. If hps is zero, then the hps data member is used as the source.
  318.   The entire bitmap is transferred.
  319.   GpiQueryBitmapBits() may modify the BITMAPINFO2 member structure: the format 
  320. of the bitmap and the color table entries may be altered to match the 
  321. presentation space/device context used as the source.
  322.   A Gpi bitmap must be selected into the source PS.
  323.  
  324. void disassociate()
  325.  
  326.   If a Gpi bitmap is associated with a Bitmap object, it lives and dies with 
  327. the Bitmap object. If the Gpi bitmap is to be independent it must be 
  328. disassociated from the object. This function breaks the association.
  329.   Note that the DC, PS, and Gpi palette, too, are no longer associated with the 
  330. Bitmap object. They must be closed and destroyed by the application. (Be sure 
  331. to save their handles - the Bitmap object won't retain them.)
  332.   Once disassociated, a new Gpi bitmap may be created and a new association formed.
  333.   The association can be made only through the Bitmap::createGpiBitmap().
  334.  
  335. void deleteGpiBitmap()
  336.  
  337.   As a Bitmap object can create a Gpi bitmap, so, too, can it destroy a Gpi 
  338. bitmap. This function will close the DC, destroy the PS, delete the Gpi 
  339. palette, and delete the Gpi bitmap - but only if the Gpi bitmap is associated 
  340. with the Bitmap object. The association is also disolved.
  341.  
  342.  
  343. IBitmapHandle hbm()
  344.  
  345.   This function is an accessor to the handle of the associated Gpi bitmap.
  346.  
  347.  
  348. IHandle hdc()
  349.  
  350.   This function is the accessor to the device context handle used by the 
  351. associated Gpi bitmap.
  352.  
  353.  
  354. IPresSpaceHandle hps() 
  355.  
  356.   This function is the accessor to the presentation space handle used by the 
  357. associated Gpi bitmap.
  358.  
  359. IHandle hpal()
  360.  
  361.   This function accesses the palette handle if a palette is associated with the 
  362. Bitmap object.
  363.  
  364.  
  365. ΓòÉΓòÉΓòÉ 3.5. Bitmap File I/O ΓòÉΓòÉΓòÉ
  366.  
  367.   The Bitmap class can load Windows, OS/2 version 1x, and OS/2 version 2x 
  368. bitmap files. The files can be bitmap arrays (icons) if the application can 
  369. manage the BITMAPARRAYFILEHEADER2 structure.
  370.   These functions transfer data between the Bitmap object and a file. The Gpi 
  371. bitmap is not involved (except when loading a file - any previously associated 
  372. Gpi bitmap is discarded) . 
  373.  
  374.  
  375. void load(ifstream& BMPfile) 
  376. BMPfile - an object of ifstream (an open input file)
  377.  
  378.   Reads the BITMAPFILEHEADER(2), BITMAPINFOHEADER(2), color table, and image 
  379. data from an open file. The file must be positioned properly to the BITMAPFILEHEADER(2).
  380.   This function is not intended to be called by the application unless the file 
  381. is a bitmap array. Instead, use the constructor which takes a file name as the argument.
  382.   If an association exists with a Gpi bitmap, that association is disolved and 
  383. those Gpi resources discarded. 
  384.  
  385. void save1x(ofstream& BMPfile)
  386. BMPfile - an object of ofstream (an open output file)
  387.  
  388.   Saves a version 1x bitmap to an open file. Writing to the file begins at the 
  389. current file position and includes the BITMAPFILEHEADER, BITMAPINFOHEADER, the 
  390. RGB color table and bitmap bits. For a single-bitmap file, simply open the 
  391. file, call this function, and close the file. For a bitmap array, be sure to 
  392. update the BITMAPARRAYFILEHEADER.
  393.  
  394.  
  395. void save2x(ofstream& BMPfile)
  396. BMPfile - an object of ofstream (an open output file)
  397.  
  398.   Saves a version 2x bitmap to an open file. Writing to the file begins at the 
  399. current file position and includes the BITMAPFILEHEADER2, BITMAPINFOHEADER2, 
  400. the RGB2 color table and bitmap bits. For a single-bitmap file, simply open the 
  401. file, call this function, and close the file. For a bitmap array, be sure to 
  402. update the BITMAPARRAYFILEHEADER2.
  403.  
  404.  
  405. ΓòÉΓòÉΓòÉ 4. Examples ΓòÉΓòÉΓòÉ
  406.  
  407.  
  408. ΓòÉΓòÉΓòÉ 4.1. Display a Bitmap from a file ΓòÉΓòÉΓòÉ
  409.  
  410.   A Canvas class is derived from ICanvas. It has a data member (_pBitmap) 
  411. pointing to a Bitmap object to be painted. When the Canvas is painted, the 
  412. bitmap is drawn.
  413.   Note that in blitTo() the invalid rectangle is intersected with the bitmap so 
  414. that any invalid region outside the bitmap image does not cause unpredictable results.
  415.  
  416. Canvas::Canvas(unsigned long id,
  417.                  IWindow* parent,
  418.                  IWindow* owner)
  419.    : ICanvas(id, parent, owner) {
  420.  
  421.    _pBitmap = new Bitmap("\\os2\\bitmap\\shells.bmp") ;
  422.  
  423.    IPaintHandler::handleEventsFor(this) ;
  424.    }
  425.  
  426. Canvas::~Canvas() {
  427.  delete _pBitmap ;
  428.  }
  429.  
  430. ...
  431.  
  432. Boolean Canvas::paintWindow(IPaintEvent& paintEvent) {
  433.    IPresSpaceHandle hps(paintEvent.presSpaceHandle()) ;
  434.  
  435.    paintEvent.clearBackground(paintEvent.rect()) ;
  436.    _pBitmap->blitTo(hps,
  437.                     paintEvent.rect().bottomLeft(),
  438.                     paintEvent.rect()) ;
  439.  
  440.    paintEvent.setResult(true) ;
  441.    return true;
  442.    }
  443.  
  444.  
  445. ΓòÉΓòÉΓòÉ 4.2. Capture the Screen & Save Compressed ΓòÉΓòÉΓòÉ
  446.  
  447. In this example the screen is captured, converted to 4-bpp, compressed, and 
  448. saved to a BMP file in version 2x format. The application should hide its 
  449. window first or the result will be a self-portrait.
  450.  
  451. Bitmap* pBitmap ;
  452. BITMAPINFOHEADER2 bmp ;
  453. RECTL rectl ;
  454. HPS   hpsScreen ;
  455.  
  456. // Set up BITMAPINFOHEADER2 from screen parameters
  457. WinQueryWindowRect(HWND_DESKTOP, &rectl) ;
  458. bmp.cbFix = 20 ;
  459. bmp.cx = rectl.xRight ;
  460. bmp.cy = rectl.yTop ;
  461. bmp.cPlanes = 1 ;
  462. bmp.cBitCount = 4 ;
  463. bmp.ulCompression = BCA_RLE4 ;
  464.  
  465. // create Bitmap object & Gpi bitmap
  466. pBitmap = new Bitmap(&bmp) ;
  467. pBitmap->createGpiBitmap() ;
  468.  
  469. // blit from screen to Gpi bitmap (compressed)
  470. POINTL aptl[3] ;
  471. aptl[0].x = aptl[0].y = 0 ;
  472. aptl[1].x = bmp.cx ;
  473. aptl[1].y = bmp.cy ;
  474. aptl[2] = aptl[0] ;
  475. hpsScreen = WinGetScreenPS(HWND_DESKTOP) ;
  476. GpiBitBlt(pBitmap->hps(),hpsScreen,3,aptl,ROP_SRCCOPY,BBO_IGNORE) ;
  477. WinReleasePS(hpsScreen) ;
  478.  
  479. // transfer bitmap to application store
  480. pBitmap->blitFrom() ;
  481.  
  482. // save bitmap to file
  483. ofstream bmpFile("screen.bmp") ;
  484. pBitmap->save2x(bmpFile) ;
  485. bmpFile.close() ;
  486.  
  487. delete pBitmap ;
  488.  
  489.  
  490. ΓòÉΓòÉΓòÉ 4.3. Decompress Image ΓòÉΓòÉΓòÉ
  491.  
  492.   If a bitmap is only to be displayed, it's not necessary to decompress it. If, 
  493. however, it will be written to a file uncompressed or its pels manipulated, it 
  494. must be decompressed. This is done by transferring it from application store to 
  495. a hps and then transferring it back to a new application store. (This procedure 
  496. ignores a custom color table.)
  497.  
  498. Bitmap* decompress(IString const& filename) {
  499.    Bitmap* compressedBitmap ;
  500.    Bitmap* uncompressedBitmap ;
  501.    compressedBitmap = new Bitmap(filename) ;      // load bitmap
  502.    if (compressedBitmap->bmp()->ulCompression) {  // is compressed ?
  503.  
  504.       // create Gpi bitmap, hps, etc.; associate with compressed bitmap
  505.       compressedBitmap->createGpiBitmap() ;
  506.  
  507.       // construct Bitmap object using Gpi bitmap dimensions
  508.       // this constructor omits compression
  509.       uncompressedBitmap = new Bitmap(compressedBitmap->hbm()) ;
  510.  
  511.       // convert format
  512.       uncompressedBitmap->blitFrom(compressedBitmap->hps()) ;
  513.  
  514.       // discard compressed bitmap object & its Gpi bitmap
  515.       delete compressedBitmap ;
  516.  
  517.       return uncompressedBitmap ;
  518.       }
  519.    else  // is not compressed
  520.       return compressedBitmap ;
  521.    }
  522.  
  523.  
  524.