home *** CD-ROM | disk | FTP | other *** search
- /*
-
- FIO.C New bitmap file IO
-
- This version reads and writes OS/2 1.1 format bitmap files only.
- Intended for use on OS/2 1.x and DOS systems.
- Bitmaps must be less than 64000 bytes big.
- eg: On input, 710x710 @ 1bpp, 350x350 @ 4bpp 250x250 @ 8bpp, 140x140 @ 24bpp
- On output, since all output is 24bpp, 140x140 maximum size.
-
- */
-
- /*...sincludes:0:*/
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <stdarg.h>
- #include <string.h>
- #include <memory.h>
- #include <malloc.h>
- #ifdef AIX
- #include <unistd.h>
- #else
- #include <io.h>
- #endif
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "standard.h"
-
- #ifndef O_BINARY
- #define O_BINARY 0
- #endif
- /*...e*/
-
- /*...sOS\47\2 bitmaps:0:*/
- #pragma pack ( 2 )
-
- /*
- Types extracted from OS/2 header files for bitmaps
- */
-
- /* --- From os2def.h --- */
-
- #define FAR far
-
- typedef short SHORT; /* s */
- typedef unsigned short USHORT; /* us */
- typedef long LONG; /* l */
- typedef unsigned long ULONG; /* ul */
- typedef unsigned char BYTE; /* b */
-
- /* --- From pmgpi.h --- */
-
- /* bitmap parameterization used by GpiCreateBitmap and others */
- typedef struct _BITMAPINFOHEADER { /* bmp */
- ULONG cbFix;
- USHORT cx;
- USHORT cy;
- USHORT cPlanes;
- USHORT cBitCount;
- } BITMAPINFOHEADER;
- typedef BITMAPINFOHEADER FAR *PBITMAPINFOHEADER;
-
- /* RGB data for _BITMAPINFO struct */
- typedef struct _RGB { /* rgb */
- BYTE bBlue;
- BYTE bGreen;
- BYTE bRed;
- } RGB;
-
- /* bitmap data used by GpiSetBitmapBits and others */
- typedef struct _BITMAPINFO { /* bmi */
- ULONG cbFix;
- USHORT cx;
- USHORT cy;
- USHORT cPlanes;
- USHORT cBitCount;
- RGB argbColor[1];
- } BITMAPINFO;
- typedef BITMAPINFO FAR *PBITMAPINFO;
-
- /* --- From pmbitmap.h --- */
-
- /*
- * This is the file format structure for Bit Maps, Pointers and Icons
- * as stored in the resource file of a PM application.
- *
- * Notes on file format:
- * Each BITMAPFILEHEADER entry is immediately followed by the color table
- * for the bit map bits it references.
- * Icons and Pointers contain two BITMAPFILEHEADERs for each ARRAYHEADER
- * item. The first one is for the ANDXOR mask, the second is for the
- * COLOR mask. All offsets are absolute based on the start of the FILE.
- */
- typedef struct _BITMAPFILEHEADER { /* bfh */
- USHORT usType;
- ULONG cbSize;
- SHORT xHotspot;
- SHORT yHotspot;
- ULONG offBits;
- BITMAPINFOHEADER bmp;
- } BITMAPFILEHEADER;
- typedef BITMAPFILEHEADER FAR *PBITMAPFILEHEADER;
-
- /*
- * This is the 1.2 device independent format header
- */
- typedef struct _BITMAPARRAYFILEHEADER { /* bafh */
- USHORT usType;
- ULONG cbSize;
- ULONG offNext;
- USHORT cxDisplay;
- USHORT cyDisplay;
- BITMAPFILEHEADER bfh;
- } BITMAPARRAYFILEHEADER;
- typedef BITMAPARRAYFILEHEADER FAR *PBITMAPARRAYFILEHEADER;
-
- /*
- * These are the identifying values that go in the usType field of the
- * BITMAPFILEHEADER and BITMAPARRAYFILEHEADER. (BFT_ => Bit map File Type)
- */
- #define BFT_ICON 0x4349 /* 'IC' */
- #define BFT_BMAP 0x4d42 /* 'BM' */
- #define BFT_POINTER 0x5450 /* 'PT' */
- #define BFT_COLORICON 0x4943 /* 'CI' */
- #define BFT_COLORPOINTER 0x5043 /* 'CP' */
- #define BFT_BITMAPARRAY 0x4142 /* 'BA' */
-
- #pragma pack ( )
- /*...e*/
-
- typedef struct
- {
- int w, h, bpp, stride;
- RGB rgbs [0x100];
- byte *data;
- int ref_count;
- } BITMAP;
-
- /*...sfio_init:0:*/
- void fio_init(void)
- {
- }
- /*...e*/
- /*...sfio_deinit:0:*/
- void fio_deinit(void)
- {
- }
- /*...e*/
- /*...sfio_create_bitmap:0:*/
- BITMAP *fio_create_bitmap(int w, int h)
- {
- BITMAP *bitmap;
-
- if ( (bitmap = malloc(sizeof(BITMAP))) == NULL )
- return ( NULL );
-
- bitmap -> w = w;
- bitmap -> h = h;
- bitmap -> bpp = 24;
- bitmap -> stride = ((w * 24 + 31)/32)*4;
-
- if ( (long) bitmap -> stride * (long) h > 64000L )
- { free(bitmap); return ( NULL ); }
-
- if ( (bitmap -> data = malloc(bitmap -> stride * h)) == NULL )
- { free(bitmap); return ( NULL ); }
-
- /* Initialse surface to medium grey */
- memset(bitmap -> data, 0x80, bitmap -> stride * h);
-
- bitmap -> ref_count = 1;
-
- return ( bitmap );
- }
- /*...e*/
- /*...sfio_copy_bitmap:0:*/
- BITMAP *fio_copy_bitmap(BITMAP *bitmap)
- {
- (bitmap -> ref_count)++;
- return ( bitmap );
- }
- /*...e*/
- /*...sfio_destroy_bitmap:0:*/
- void fio_destroy_bitmap(BITMAP *bitmap)
- {
- if ( --(bitmap -> ref_count) == 0 )
- {
- free(bitmap -> data);
- free(bitmap);
- }
- }
- /*...e*/
- /*...sfio_read_bitmap:0:*/
- BITMAP *fio_read_bitmap(char *fn)
- {
- BITMAP *bitmap;
- int fd;
- BITMAPFILEHEADER bfh;
- int cRGB;
-
- if ( (fd = open(fn, O_RDONLY | O_BINARY)) == -1 )
- return ( NULL );
-
- if ( (bitmap = malloc(sizeof(BITMAP))) == NULL )
- { close(fd); return ( NULL ); }
-
- if ( read(fd, (char *) &bfh, sizeof(bfh)) != sizeof(bfh) ||
- bfh.bmp.cPlanes != 1 )
- { free(bitmap); close(fd); return ( NULL ); }
-
- bitmap -> w = bfh.bmp.cx;
- bitmap -> h = bfh.bmp.cy;
- bitmap -> bpp = bfh.bmp.cBitCount;
-
- cRGB = ( ( 1 << bfh.bmp.cBitCount ) & 0x1ff );
- /* 1 -> 2, 4 -> 16, 8 -> 256, 24 -> 0 */
-
- if ( read(fd, (char *) (bitmap -> rgbs), cRGB * sizeof(RGB)) != cRGB * sizeof(RGB) )
- { free(bitmap); close(fd); return ( NULL ); }
-
- bitmap -> stride = (((bfh.bmp.cBitCount * bfh.bmp.cx + 31) / 32) * bfh.bmp.cPlanes) * 4;
-
- if ( (long) bitmap -> h * (long) bitmap -> stride > 64000L )
- { free(bitmap); close(fd); return ( NULL ); }
-
- if ( (bitmap -> data = malloc(bitmap -> h * bitmap -> stride)) == NULL )
- { free(bitmap); close(fd); return ( NULL ); }
-
- if ( read(fd, (char *) (bitmap -> data), bitmap -> h * bitmap -> stride) != bitmap -> h * bitmap -> stride )
- { free(bitmap); close(fd); return ( NULL ); }
-
- close(fd);
-
- bitmap -> ref_count = 1;
-
- return ( bitmap );
- }
- /*...e*/
- /*...sfio_write_bitmap:0:*/
- BOOLEAN fio_write_bitmap(BITMAP *bitmap, char *fn)
- {
- BITMAPFILEHEADER bfh;
- int fd;
-
- if ( (fd = open(fn, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1 )
- return ( FALSE );
-
- /* Write out file header */
-
- bfh.bmp.cbFix = sizeof(BITMAPINFOHEADER);
- bfh.bmp.cx = bitmap -> w;
- bfh.bmp.cy = bitmap -> h;
- bfh.bmp.cPlanes = 1;
- bfh.bmp.cBitCount = bitmap -> bpp;
-
- bfh.usType = BFT_BMAP;
- bfh.offBits = (long) sizeof(BITMAPFILEHEADER);
- bfh.cbSize = bfh.offBits + (long) bitmap -> stride * (long) bfh.bmp.cy;
- bfh.xHotspot = 0;
- bfh.yHotspot = 0;
-
- if ( write(fd, (char *) &bfh, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER) )
- { close(fd); unlink(fn); return ( FALSE ); }
-
- if ( write(fd, (char *) bitmap -> data, bitmap -> h * bitmap -> stride) !=
- bitmap -> h * bitmap -> stride )
- { close(fd); unlink(fn); return ( FALSE ); }
-
- close(fd);
-
- return ( TRUE );
- }
- /*...e*/
- /*...sfio_get_pixel:0:*/
- void fio_get_pixel(
- BITMAP *bitmap,
- int x, int y,
- byte *r, byte *g, byte *b
- )
- {
- byte inx, *data = bitmap -> data + y * bitmap -> stride;
-
- switch ( bitmap -> bpp )
- {
- /*...s1:16:*/
- case 1:
- inx = data [x >> 3];
- inx >>= ( 7 - (x & 7) );
- inx &= 1;
- inx ^= 1; /* B/W reverse palette fix */
- *b = bitmap -> rgbs [inx].bBlue ;
- *g = bitmap -> rgbs [inx].bGreen;
- *r = bitmap -> rgbs [inx].bRed ;
- break;
- /*...e*/
- /*...s4:16:*/
- case 4:
- inx = data [x >> 1];
- if ( x & 1 )
- inx &= 0x0f;
- else
- inx >>= 4;
- *b = bitmap -> rgbs [inx].bBlue ;
- *g = bitmap -> rgbs [inx].bGreen;
- *r = bitmap -> rgbs [inx].bRed ;
- break;
- /*...e*/
- /*...s8:16:*/
- case 8:
- inx = data [x];
- *b = bitmap -> rgbs [inx].bBlue ;
- *g = bitmap -> rgbs [inx].bGreen;
- *r = bitmap -> rgbs [inx].bRed ;
- break;
- /*...e*/
- /*...s24:16:*/
- case 24:
- data += (x * 3);
- *b = *data++;
- *g = *data++;
- *r = *data;
- break;
- /*...e*/
- }
- }
- /*...e*/
- /*...sfio_set_pixel:0:*/
- void fio_set_pixel(
- BITMAP *bitmap,
- int x, int y,
- byte r, byte g, byte b
- )
- {
- int stride = bitmap -> stride;
- byte *data = bitmap -> data + y * stride + x * 3;
-
- *data++ = b;
- *data++ = g;
- *data = r;
- }
- /*...e*/
- /*...sfio_width:0:*/
- int fio_width(BITMAP *bitmap)
- {
- return ( bitmap -> w );
- }
- /*...e*/
- /*...sfio_height:0:*/
- int fio_height(BITMAP *bitmap)
- {
- return ( bitmap -> h );
- }
- /*...e*/
-