home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / csg_rt / fio_b.c < prev    next >
C/C++ Source or Header  |  1993-01-12  |  9KB  |  357 lines

  1. /*
  2.  
  3. FIO.C  New bitmap file IO
  4.  
  5. This version reads and writes OS/2 1.1 format bitmap files only.
  6. Intended for use on OS/2 1.x and DOS systems.
  7. Bitmaps must be less than 64000 bytes big.
  8. eg: On input, 710x710 @ 1bpp, 350x350 @ 4bpp 250x250 @ 8bpp, 140x140 @ 24bpp
  9.     On output, since all output is 24bpp, 140x140 maximum size.
  10.  
  11. */
  12.  
  13. /*...sincludes:0:*/
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include <stdarg.h>
  19. #include <string.h>
  20. #include <memory.h>
  21. #include <malloc.h>
  22. #ifdef AIX
  23. #include <unistd.h>
  24. #else
  25. #include <io.h>
  26. #endif
  27. #include <fcntl.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include "standard.h"
  31.  
  32. #ifndef O_BINARY
  33. #define    O_BINARY 0
  34. #endif
  35. /*...e*/
  36.  
  37. /*...sOS\47\2 bitmaps:0:*/
  38. #pragma pack ( 2 )
  39.  
  40. /*
  41. Types extracted from OS/2 header files for bitmaps
  42. */
  43.  
  44. /* --- From os2def.h --- */
  45.  
  46. #define FAR     far
  47.  
  48. typedef short SHORT;            /* s   */
  49. typedef unsigned short USHORT;  /* us  */
  50. typedef long LONG;              /* l   */
  51. typedef unsigned long ULONG;    /* ul  */
  52. typedef unsigned char BYTE;     /* b   */
  53.  
  54. /* --- From pmgpi.h --- */
  55.  
  56. /* bitmap parameterization used by GpiCreateBitmap and others */
  57. typedef struct _BITMAPINFOHEADER {      /* bmp */
  58.     ULONG  cbFix;
  59.     USHORT cx;
  60.     USHORT cy;
  61.     USHORT cPlanes;
  62.     USHORT cBitCount;
  63. } BITMAPINFOHEADER;
  64. typedef BITMAPINFOHEADER FAR *PBITMAPINFOHEADER;
  65.  
  66. /* RGB data for _BITMAPINFO struct */
  67. typedef struct _RGB {           /* rgb */
  68.     BYTE bBlue;
  69.     BYTE bGreen;
  70.     BYTE bRed;
  71. } RGB;
  72.  
  73. /* bitmap data used by GpiSetBitmapBits and others */
  74. typedef struct _BITMAPINFO {    /* bmi */
  75.     ULONG  cbFix;
  76.     USHORT cx;
  77.     USHORT cy;
  78.     USHORT cPlanes;
  79.     USHORT cBitCount;
  80.     RGB    argbColor[1];
  81. } BITMAPINFO;
  82. typedef BITMAPINFO FAR *PBITMAPINFO;
  83.  
  84. /* --- From pmbitmap.h --- */
  85.  
  86. /*
  87.  * This is the file format structure for Bit Maps, Pointers and Icons
  88.  * as stored in the resource file of a PM application.
  89.  *
  90.  * Notes on file format:
  91.  *   Each BITMAPFILEHEADER entry is immediately followed by the color table
  92.  *   for the bit map bits it references.
  93.  *   Icons and Pointers contain two BITMAPFILEHEADERs for each ARRAYHEADER
  94.  *   item.  The first one is for the ANDXOR mask, the second is for the
  95.  *   COLOR mask.  All offsets are absolute based on the start of the FILE.
  96.  */
  97. typedef struct _BITMAPFILEHEADER { /* bfh */
  98.     USHORT    usType;
  99.     ULONG     cbSize;
  100.     SHORT     xHotspot;
  101.     SHORT     yHotspot;
  102.     ULONG     offBits;
  103.     BITMAPINFOHEADER bmp;
  104. } BITMAPFILEHEADER;
  105. typedef BITMAPFILEHEADER FAR *PBITMAPFILEHEADER;
  106.  
  107. /*
  108.  * This is the 1.2 device independent format header
  109.  */
  110. typedef struct _BITMAPARRAYFILEHEADER {    /* bafh */
  111.     USHORT    usType;
  112.     ULONG     cbSize;
  113.     ULONG     offNext;
  114.     USHORT    cxDisplay;
  115.     USHORT    cyDisplay;
  116.     BITMAPFILEHEADER bfh;
  117. } BITMAPARRAYFILEHEADER;
  118. typedef BITMAPARRAYFILEHEADER FAR *PBITMAPARRAYFILEHEADER;
  119.  
  120. /*
  121.  * These are the identifying values that go in the usType field of the
  122.  * BITMAPFILEHEADER and BITMAPARRAYFILEHEADER.  (BFT_ => Bit map File Type)
  123.  */
  124. #define BFT_ICON           0x4349   /* 'IC' */
  125. #define BFT_BMAP           0x4d42   /* 'BM' */
  126. #define BFT_POINTER        0x5450   /* 'PT' */
  127. #define BFT_COLORICON      0x4943   /* 'CI' */
  128. #define BFT_COLORPOINTER   0x5043   /* 'CP' */
  129. #define BFT_BITMAPARRAY    0x4142   /* 'BA' */
  130.  
  131. #pragma pack ( )
  132. /*...e*/
  133.  
  134. typedef struct
  135.     {
  136.     int w, h, bpp, stride;
  137.     RGB rgbs [0x100];
  138.     byte *data;
  139.     int ref_count;
  140.     } BITMAP;
  141.  
  142. /*...sfio_init:0:*/
  143. void fio_init(void)
  144.     {
  145.     }
  146. /*...e*/
  147. /*...sfio_deinit:0:*/
  148. void fio_deinit(void)
  149.     {
  150.     }
  151. /*...e*/
  152. /*...sfio_create_bitmap:0:*/
  153. BITMAP *fio_create_bitmap(int w, int h)
  154.     {
  155.     BITMAP *bitmap;
  156.  
  157.     if ( (bitmap = malloc(sizeof(BITMAP))) == NULL )
  158.         return ( NULL );
  159.  
  160.     bitmap -> w      = w;
  161.     bitmap -> h      = h;
  162.     bitmap -> bpp    = 24;
  163.     bitmap -> stride = ((w * 24 + 31)/32)*4;
  164.  
  165.     if ( (long) bitmap -> stride * (long) h > 64000L )
  166.         { free(bitmap); return ( NULL ); }
  167.  
  168.     if ( (bitmap -> data = malloc(bitmap -> stride * h)) == NULL )
  169.         { free(bitmap); return ( NULL ); }
  170.  
  171.     /* Initialse surface to medium grey */
  172.     memset(bitmap -> data, 0x80, bitmap -> stride * h);
  173.  
  174.     bitmap -> ref_count = 1;
  175.  
  176.     return ( bitmap );
  177.     }
  178. /*...e*/
  179. /*...sfio_copy_bitmap:0:*/
  180. BITMAP *fio_copy_bitmap(BITMAP *bitmap)
  181.     {
  182.     (bitmap -> ref_count)++;
  183.     return ( bitmap );
  184.     }
  185. /*...e*/
  186. /*...sfio_destroy_bitmap:0:*/
  187. void fio_destroy_bitmap(BITMAP *bitmap)
  188.     {
  189.     if ( --(bitmap -> ref_count) == 0 )
  190.         {
  191.         free(bitmap -> data);
  192.         free(bitmap);
  193.         }
  194.     }
  195. /*...e*/
  196. /*...sfio_read_bitmap:0:*/
  197. BITMAP *fio_read_bitmap(char *fn)
  198.     {
  199.     BITMAP *bitmap;
  200.     int fd;
  201.     BITMAPFILEHEADER bfh;
  202.     int cRGB;
  203.  
  204.     if ( (fd = open(fn, O_RDONLY | O_BINARY)) == -1 )
  205.         return ( NULL );
  206.  
  207.     if ( (bitmap = malloc(sizeof(BITMAP))) == NULL )
  208.         { close(fd); return ( NULL ); }
  209.  
  210.     if ( read(fd, (char *) &bfh, sizeof(bfh)) != sizeof(bfh) ||
  211.          bfh.bmp.cPlanes != 1 )
  212.         { free(bitmap); close(fd); return ( NULL ); }
  213.  
  214.     bitmap -> w   = bfh.bmp.cx;
  215.     bitmap -> h   = bfh.bmp.cy;
  216.     bitmap -> bpp = bfh.bmp.cBitCount;
  217.  
  218.     cRGB = ( ( 1 << bfh.bmp.cBitCount ) & 0x1ff );
  219.         /* 1 -> 2, 4 -> 16, 8 -> 256, 24 -> 0 */
  220.  
  221.     if ( read(fd, (char *) (bitmap -> rgbs), cRGB * sizeof(RGB)) != cRGB * sizeof(RGB) )
  222.         { free(bitmap); close(fd); return ( NULL ); }
  223.  
  224.     bitmap -> stride = (((bfh.bmp.cBitCount * bfh.bmp.cx + 31) / 32) * bfh.bmp.cPlanes) * 4;
  225.  
  226.     if ( (long) bitmap -> h * (long) bitmap -> stride > 64000L )
  227.         { free(bitmap); close(fd); return ( NULL ); }
  228.  
  229.     if ( (bitmap -> data = malloc(bitmap -> h * bitmap -> stride)) == NULL )
  230.         { free(bitmap); close(fd); return ( NULL ); }
  231.  
  232.     if ( read(fd, (char *) (bitmap -> data), bitmap -> h * bitmap -> stride) != bitmap -> h * bitmap -> stride )
  233.         { free(bitmap); close(fd); return ( NULL ); }
  234.  
  235.     close(fd);
  236.  
  237.     bitmap -> ref_count = 1;
  238.  
  239.     return ( bitmap );
  240.     }
  241. /*...e*/
  242. /*...sfio_write_bitmap:0:*/
  243. BOOLEAN fio_write_bitmap(BITMAP *bitmap, char *fn)
  244.     {
  245.     BITMAPFILEHEADER bfh;
  246.     int fd;
  247.  
  248.     if ( (fd = open(fn, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1 )
  249.         return ( FALSE );
  250.  
  251.     /* Write out file header */
  252.  
  253.     bfh.bmp.cbFix     = sizeof(BITMAPINFOHEADER);
  254.     bfh.bmp.cx        = bitmap -> w;
  255.     bfh.bmp.cy        = bitmap -> h;
  256.     bfh.bmp.cPlanes   = 1;
  257.     bfh.bmp.cBitCount = bitmap -> bpp;
  258.  
  259.     bfh.usType        = BFT_BMAP;
  260.     bfh.offBits       = (long) sizeof(BITMAPFILEHEADER);
  261.     bfh.cbSize        = bfh.offBits + (long) bitmap -> stride * (long) bfh.bmp.cy;
  262.     bfh.xHotspot      = 0;
  263.     bfh.yHotspot      = 0;
  264.  
  265.     if ( write(fd, (char *) &bfh, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER) )
  266.         { close(fd); unlink(fn); return ( FALSE ); }
  267.  
  268.     if ( write(fd, (char *) bitmap -> data, bitmap -> h * bitmap -> stride) !=
  269.          bitmap -> h * bitmap -> stride )
  270.         { close(fd); unlink(fn); return ( FALSE ); }
  271.  
  272.     close(fd);
  273.  
  274.     return ( TRUE );
  275.     }
  276. /*...e*/
  277. /*...sfio_get_pixel:0:*/
  278. void fio_get_pixel(
  279.     BITMAP *bitmap,
  280.     int x, int y,
  281.     byte *r, byte *g, byte *b
  282.     )
  283.     {
  284.     byte inx, *data = bitmap -> data + y * bitmap -> stride;
  285.  
  286.     switch ( bitmap -> bpp )
  287.         {
  288. /*...s1:16:*/
  289. case 1:
  290.     inx = data [x >> 3];
  291.     inx >>= ( 7 - (x & 7) );
  292.     inx &= 1;    
  293.     inx ^= 1;            /* B/W reverse palette fix */
  294.     *b = bitmap -> rgbs [inx].bBlue ;
  295.     *g = bitmap -> rgbs [inx].bGreen;
  296.     *r = bitmap -> rgbs [inx].bRed  ;
  297.     break;
  298. /*...e*/
  299. /*...s4:16:*/
  300. case 4:
  301.     inx = data [x >> 1];
  302.     if ( x & 1 )
  303.         inx &= 0x0f;
  304.     else
  305.         inx >>= 4;
  306.     *b = bitmap -> rgbs [inx].bBlue ;
  307.     *g = bitmap -> rgbs [inx].bGreen;
  308.     *r = bitmap -> rgbs [inx].bRed  ;
  309.     break;
  310. /*...e*/
  311. /*...s8:16:*/
  312. case 8:
  313.     inx = data [x];
  314.     *b = bitmap -> rgbs [inx].bBlue ;
  315.     *g = bitmap -> rgbs [inx].bGreen;
  316.     *r = bitmap -> rgbs [inx].bRed  ;
  317.     break;
  318. /*...e*/
  319. /*...s24:16:*/
  320. case 24:
  321.     data += (x * 3);
  322.     *b = *data++;
  323.     *g = *data++;
  324.     *r = *data;
  325.     break;
  326. /*...e*/
  327.         }
  328.     }
  329. /*...e*/
  330. /*...sfio_set_pixel:0:*/
  331. void fio_set_pixel(
  332.     BITMAP *bitmap,
  333.     int x, int y,
  334.     byte r, byte g, byte b
  335.     )
  336.     {
  337.     int stride = bitmap -> stride;
  338.     byte *data = bitmap -> data + y * stride + x * 3;
  339.  
  340.     *data++ = b;
  341.     *data++ = g;
  342.     *data   = r;
  343.     }
  344. /*...e*/
  345. /*...sfio_width:0:*/
  346. int fio_width(BITMAP *bitmap)
  347.     {
  348.     return ( bitmap -> w );
  349.     }
  350. /*...e*/
  351. /*...sfio_height:0:*/
  352. int fio_height(BITMAP *bitmap)
  353.     {
  354.     return ( bitmap -> h );
  355.     }
  356. /*...e*/
  357.