home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
rexx
/
library2
/
gbmrexx
/
gbm
/
gbmkps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-04
|
8KB
|
360 lines
/*
GBMKPS.C IBM KIPS support
Reads array as 8 bit palettised colour.
Writes 8 bit palettised colour.
Input options: pal,kpl (default: pal)
Output options: pal,kpl (default: pal)
*/
/*...sincludes:0:*/
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <stdlib.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"
#include "gbm.h"
/*...vgbm\46\h:0:*/
/* Handle case for UNIX machines where O_BINARY has no meaning */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*...e*/
/*...suseful:0:*/
#define low_byte(w) ((byte) ((w)&0x00ff) )
#define high_byte(w) ((byte) (((w)&0xff00)>>8))
#define make_word(a,b) (((word)a) + (((word)b) << 8))
/*...e*/
/*...sextension:0:*/
static char *extension(char *fn)
{
char *dot, *slash;
if ( (dot = strrchr(fn, '.')) == NULL )
return ( NULL );
if ( (slash = strpbrk(fn, "/\\")) == NULL )
return ( dot + 1 );
return ( ( slash < dot ) ? dot + 1 : NULL );
}
/*...e*/
/*...ssame:0:*/
static BOOLEAN same(char *s1, char *s2, int n)
{
for ( ; n--; s1++, s2++ )
if ( tolower(*s1) != tolower(*s2) )
return ( FALSE );
return ( TRUE );
}
/*...e*/
/*...sfind_word:0:*/
static char *find_word(char *str, char *substr)
{
char buf [100+1], *s;
int len = strlen(substr);
for ( s = strtok(strcpy(buf, str), " \t,");
s != NULL;
s = strtok(NULL, " \t,") )
if ( same(s, substr, len) && s [len] == '\0' )
return ( str + (s - buf) );
return ( NULL );
}
/*...e*/
static GBMFT kps_gbmft =
{
"KIPS",
"IBM KIPS",
"KPS",
GBM_FT_R8|
GBM_FT_W8,
};
#define GBM_ERR_KPS_OPEN ((GBM_ERR) 500)
#define GBM_ERR_KPS_CREATE ((GBM_ERR) 501)
/*...skps file header definition:0:*/
/*
This defines the 32 byte header found on .KPS and .KPL files.
*/
#define KPS_SIGNITURE "DFIMAG00"
typedef struct
{
byte signiture [8]; /* Usually "DFIMAG00" */
byte height_low;
byte height_high; /* Image height in pixels */
byte width_low;
byte width_high; /* Image width in pixels */
byte unknown [20]; /* 20 unknown bytes */
} KPS_HEADER;
/*...e*/
typedef struct
{
char fn [600+1];
BOOLEAN kpl;
} KPS_PRIV;
/*...skps_qft:0:*/
GBM_ERR kps_qft(GBMFT *gbmft)
{
*gbmft = kps_gbmft;
return ( GBM_ERR_OK );
}
/*...e*/
/*...skps_rhdr:0:*/
GBM_ERR kps_rhdr(char *fn, int fd, GBM *gbm, char *opt)
{
BOOLEAN pal = ( find_word(opt, "pal") != NULL );
BOOLEAN kpl = ( find_word(opt, "kpl") != NULL );
KPS_HEADER kps_header;
KPS_PRIV *priv = (KPS_PRIV *) gbm -> priv;
int w, h;
if ( kpl && pal )
return ( GBM_ERR_BAD_OPTION );
read(fd, (char *) &kps_header, sizeof(KPS_HEADER));
if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
return ( GBM_ERR_BAD_MAGIC );
w = make_word(kps_header.width_low , kps_header.width_high );
h = make_word(kps_header.height_low, kps_header.height_high);
if ( w <= 0 || h <= 0 )
return ( GBM_ERR_BAD_SIZE );
gbm -> w = w;
gbm -> h = h;
gbm -> bpp = 8;
/* Keep these for a later kps_rpal() call */
strcpy(priv -> fn, fn);
priv -> kpl = kpl;
return ( GBM_ERR_OK );
}
/*...e*/
/*...skps_rpal:0:*/
GBM_ERR kps_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
{
KPS_PRIV *priv = (KPS_PRIV *) gbm -> priv;
char fn2 [600+1], *ext;
fd=fd; /* Suppress 'unref arg' compiler warning */
strcpy(fn2, priv -> fn);
ext = extension(fn2);
if ( priv -> kpl )
/*...sread a \46\kpl palette file:16:*/
{
int fd2, i, w, h;
byte p [3][0x100];
KPS_HEADER kps_header;
if ( ext != NULL )
strcpy(ext, "kpl");
else
strcat(fn2, ".kpl");
if ( (fd2 = open(fn2, O_RDONLY | O_BINARY)) == -1 )
return ( GBM_ERR_KPS_OPEN );
read(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
return ( GBM_ERR_BAD_MAGIC );
w = make_word(kps_header.width_low , kps_header.width_high );
h = make_word(kps_header.height_low, kps_header.height_high);
if ( w != 0x100 || h != 3 )
return ( GBM_ERR_BAD_SIZE );
read(fd2, &(p [0][0]), 0x300);
close(fd2);
for ( i = 0; i < 0x100; i++ )
{
gbmrgb [i].r = p [0][i];
gbmrgb [i].b = p [1][i];
gbmrgb [i].g = p [2][i];
}
}
/*...e*/
else
/*...sread a \46\pal palette file:16:*/
{
int fd2, i;
byte b [4];
if ( ext != NULL )
strcpy(ext, "pal");
else
strcat(fn2, ".pal");
if ( (fd2 = open(fn2, O_RDONLY | O_BINARY)) == -1 )
return ( GBM_ERR_KPS_OPEN );
for ( i = 0; i < 0x100; i++ )
{
read(fd2, (char *) b, 4);
gbmrgb [i].r = b [0];
gbmrgb [i].b = b [1];
gbmrgb [i].g = b [2];
}
close(fd2);
}
/*...e*/
return ( GBM_ERR_OK );
}
/*...e*/
/*...skps_rdata:0:*/
GBM_ERR kps_rdata(int fd, GBM *gbm, byte *data)
{
int i, stride;
byte *p;
stride = ((gbm -> w + 3) & ~3);
p = data + ((gbm -> h - 1) * stride);
for ( i = gbm -> h - 1; i >= 0; i-- )
{
read(fd, p, gbm -> w);
p -= stride;
}
return ( GBM_ERR_OK );
}
/*...e*/
/*...skps_w:0:*/
GBM_ERR kps_w(char *fn, int fd, GBM *gbm, GBMRGB *gbmrgb, byte *data, char *opt)
{
KPS_HEADER kps_header;
int i, stride;
byte *p;
char fn2 [600+1], *ext;
BOOLEAN pal = ( find_word(opt, "pal") != NULL );
BOOLEAN kpl = ( find_word(opt, "kpl") != NULL );
if ( gbm -> bpp != 8 )
return ( GBM_ERR_NOT_SUPP );
if ( pal && kpl )
return ( GBM_ERR_BAD_OPTION );
memcpy(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE));
kps_header.width_low = low_byte(gbm -> w);
kps_header.width_high = high_byte(gbm -> w);
kps_header.height_low = low_byte(gbm -> h);
kps_header.height_high = high_byte(gbm -> h);
kps_header.unknown [0] = 1;
memset(&kps_header.unknown [1], 0, 19);
write(fd, (char *) &kps_header, sizeof(KPS_HEADER));
stride = ((gbm -> w + 3) & ~3);
p = data + ((gbm -> h - 1) * stride);
for ( i = gbm -> h - 1; i >= 0; i-- )
{
write(fd, p, gbm -> w);
p -= stride;
}
strcpy(fn2, fn);
ext = extension(fn2);
if ( kpl )
/*...swrite a \46\kpl palette file:16:*/
{
int fd2, j;
byte palette [3][0x100];
if ( ext != NULL )
strcpy(ext, "kpl");
else
strcat(fn2, ".kpl");
if ( (fd2 = open(fn2, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 )
return ( GBM_ERR_KPS_CREATE );
kps_header.width_low = low_byte(0x100);
kps_header.width_high = high_byte(0x100);
kps_header.height_low = low_byte(3);
kps_header.height_high = high_byte(3);
write(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
for ( j = 0; j < 0x100; j++ )
{
palette [0][j] = gbmrgb [j].r;
palette [1][j] = gbmrgb [j].b;
palette [2][j] = gbmrgb [j].g;
}
write(fd2, &(palette [0][0]), 0x300);
close(fd2);
}
/*...e*/
else
/*...swrite a \46\pal palette file:16:*/
{
int fd2;
byte b [4];
if ( ext != NULL )
strcpy(ext, "pal");
else
strcat(fn2, ".pal");
if ( (fd2 = open(fn2, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 )
return ( GBM_ERR_KPS_CREATE );
b [3] = 0;
for ( i = 0; i < 0x100; i++ )
{
b [0] = gbmrgb [i].r;
b [1] = gbmrgb [i].b;
b [2] = gbmrgb [i].g;
write(fd2, (char *) b, 4);
}
close(fd2);
}
/*...e*/
return ( GBM_ERR_OK );
}
/*...e*/
/*...skps_err:0:*/
char *kps_err(GBM_ERR rc)
{
switch ( (int) rc )
{
case GBM_ERR_KPS_OPEN:
return ( "can't open complementary palette file" );
case GBM_ERR_KPS_CREATE:
return ( "can't create complementary palette file" );
}
return ( NULL );
}
/*...e*/