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