home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
PIC1600
/
F_16_16.C
next >
Wrap
C/C++ Source or Header
|
1996-06-12
|
12KB
|
427 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "piclib.h"
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
extern PicFunction PicFunction_25_7;
typedef struct {
FILE *fp;
unsigned short buffer[BUFFERSIZE];
Pixel *pixelbuffer;
unsigned int seek;
unsigned long totallength;
unsigned int nowpoint;
unsigned short nowcolor;
unsigned short nowlength;
PicReduceData *reduce;
} PicWork;
#ifdef LittleEndian
#define r_short(p) (((unsigned char*)(p))[0] * 256 + ((unsigned char*)(p))[1])
#define w_short(p,n) ((((unsigned char*)(p))[0] = (n)/256), (((unsigned char*)(p))[1] = (n)%256))
#else
#define r_short(p) (*((unsigned short *)(p)))
#define w_short(p,n) ((*((unsigned short *)(p))) = n)
#endif
static INLINE int getshort(FILE *fp)
{
int i;
i = fgetc(fp) * 256;
i += fgetc(fp);
return i;
}
static INLINE long getlong(FILE *fp)
{
long i;
i = getshort(fp) * 65536L;
i += getshort(fp);
return i;
}
int WritePicHeader_DPIC(PicHeader *ph, FILE *fp)
{
int i;
fprintf(fp, "image\r\n");
fprintf(fp, "mod %s\r\n", compresstoken[ph->mode]);
fprintf(fp, "pxn %d %d\r\n", ph->pixelX, ph->pixelY);
fprintf(fp, "pxs %d %d\r\n", ph->screenX, ph->screenY);
fprintf(fp, "pnt %d %d\r\n", ph->positionX, ph->positionY);
fprintf(fp, "frm %d\r\n", ph->frame);
fprintf(fp, "cst {\r\n");
for (i = 0; ph->storecolor[i] != 0; ++i) {
fprintf(fp, "%s %d\r\n", colortoken[ph->storecolor[i]], ph->storecolorbit[i]);
}
fprintf(fp, "}\r\ndst {\r\n");
for (i = 0; ph->storedata[i] != 0; ++i) {
fprintf(fp, "%s %d\r\n", datatoken[ph->storedata[i]], ph->storedatabit[i]);
}
fprintf(fp, "}\r\n\x1a");
if (ferror(fp)) return FALSE;
return TRUE;
}
int PicReadHeader_DPIC(PicHeader *ph, FILE *fp)
{
extern char *GetToken(char *buf, FILE *fp);
extern int GetIdentifier(char *string, char *select[]);
int i, j;
char str[STRING];
if (GetToken(str, fp) == NULL || strcmp(str, "image")) {
return FALSE;
}
ph->storecolor[0] = 0;
ph->storedata[0] = 0;
while (GetToken(str, fp) != NULL) {
if (ferror(fp)) return FALSE;
if (str[0] == EOFCODE) {
j = 0;
for (i = 0; ph->storecolor[i] != 0; ++i) {
j += ph->storecolorbit[i];
}
ph->colorbytes = (j - 1) / 8 + 1;
j = 0;
for (i = 0; ph->storedata[i] != 0; ++i) {
j += ph->storedatabit[i];
}
ph->databytes = (j - 1) / 8 + 1;
return TRUE;
} else if (i = GetIdentifier(str, identtoken), i != 0) {
switch(i) {
case MOD :
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
i = GetIdentifier(str, compresstoken);
if (i != 0) {
ph->mode = i;
} else {
return FALSE;
}
break;
case PXN :
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->pixelX = atoi(str);
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->pixelY = atoi(str);
break;
case PXS :
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->screenX = atoi(str);
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->screenY = atoi(str);
break;
case PNT :
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->positionX = atoi(str);
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->positionY = atoi(str);
break;
case FRM :
if (GetToken(str, fp) == NULL || str[0] == EOFCODE) {
return FALSE;
}
ph->frame = atoi(str);
break;
case CST :
if (GetToken(str, fp) == NULL || str[0] != '{') {
return FALSE;
}
j = 0;
while (GetToken(str, fp) != NULL && str[0] != EOFCODE && str[0] != '}') {
i = GetIdentifier(str, colortoken);
if (i == 0) {
break;
}
ph->storecolor[j] = i;
if (GetToken(str, fp) == NULL || str[0] == EOFCODE || str[0] == '}') {
break;
}
ph->storecolorbit[j++] = atoi(str);
}
if (str[0] != '}') {
return FALSE;
}
ph->storecolor[j] = 0;
ph->storecolorbit[j] = 0;
break;
case DST :
if (GetToken(str, fp) == NULL || str[0] != '{') {
return FALSE;
}
j = 0;
while (GetToken(str, fp) != NULL && str[0] != EOFCODE && str[0] != '}') {
i = GetIdentifier(str, datatoken);
if (i == 0) {
break;
}
ph->storedata[j] = i;
if (GetToken(str, fp) == NULL || str[0] == EOFCODE || str[0] == '}') {
break;
}
ph->storedatabit[j++] = atoi(str);
}
if (str[0] != '}') {
return FALSE;
}
ph->storedata[j] = 0;
ph->storedatabit[j] = 0;
break;
}
} else {
return FALSE;
}
}
return FALSE;
}
int PicReadHeader_16_16(PicData *pd, FILE *fp, unsigned char *magic)
{
PicHeader ph;
extern PicFunction PicFunction_16_16, PicFunction_25_7;
if (memcmp(magic, "image", 5) != 0) {
return FALSE;
}
if (PicReadHeader_DPIC(&ph, fp) == FALSE) {
return FALSE;
}
pd->pixelX = ph.pixelX;
pd->pixelY = ph.pixelY;
pd->mode = ph.mode;
if (ph.mode != RLN) {
return FALSE;
}
pd->datasize = getlong(fp);
if (ph.storedata[0] == COL && ph.storedata[1] == LEN) {
if (ph.storedatabit[0] == 16 && ph.storedatabit[1] == 16) {
pd->fullcolor = FALSE;
pd->func = &PicFunction_16_16;
return TRUE;
} else if (ph.storedatabit[0] == 25 && ph.storedatabit[1] == 7) {
pd->func = &PicFunction_25_7;
return TRUE;
}
}
return FALSE;
}
int PicOpen_16_16(PicData *pd, FILE *fp, int flag)
{
PicWork *work;
if (pd->flag == PIC_WRITE && flag == COMPRESS_TRUECOLOR) {
pd->func = &PicFunction_25_7;
return pd->func->PicOpen(pd, fp, 0);
}
if ((work = malloc(sizeof(PicWork))) == NULL) {
return FALSE;
}
pd->work = work;
work->fp = fp;
if (pd->flag == PIC_READ) {
fread(work->buffer, 1, BUFFERSIZE*sizeof(unsigned short), work->fp);
if (ferror(work->fp)) return FALSE;
work->nowpoint = 0;
work->nowcolor = r_short(work->buffer+work->nowpoint);work->nowpoint++;
work->nowlength = r_short(work->buffer+work->nowpoint);work->nowpoint++;
} else {
PicHeader ph;
ph.pixelX = pd->pixelX;
ph.pixelY = pd->pixelY;
ph.screenX = 4;
ph.screenY = 3;
ph.positionX = 0;
ph.positionY = 0;
ph.frame = 1;
ph.storecolor[0] = GRN; ph.storecolorbit[0] = 5;
ph.storecolor[1] = RED; ph.storecolorbit[1] = 5;
ph.storecolor[2] = BLU; ph.storecolorbit[2] = 5;
ph.storecolor[3] = TRP; ph.storecolorbit[3] = 1;
ph.storecolor[4] = 0; ph.storecolorbit[4] = 0;
ph.mode = RLN;
ph.storedata[0] = COL; ph.storedatabit[0] = 16;
ph.storedata[1] = LEN; ph.storedatabit[1] = 16;
ph.storedata[2] = 0; ph.storedatabit[2] = 0;
if (WritePicHeader_DPIC(&ph, fp) == FALSE) return FALSE;
work->reduce = NULL;
work->pixelbuffer = NULL;
if ((work->reduce = PicColorReduceOpen(pd->pixelX, flag)) == NULL) {
return FALSE;
}
if ((work->pixelbuffer = malloc(sizeof(Pixel) * pd->pixelX)) == NULL) {
return FALSE;
}
work->seek = ftell(work->fp);
work->nowpoint = 0;
w_short(work->buffer+work->nowpoint, 0);work->nowpoint++;
w_short(work->buffer+work->nowpoint, 0);work->nowpoint++;
work->nowcolor = 0;
work->nowlength = 0;
work->totallength = 0;
}
return TRUE;
}
static inline Pixel Convert_16_24(unsigned short color)
{
/* gggg grrr rrbb bbbt*/
/* gggg gggg rrrr rrrr bbbb bbbb tttt tttt*/
/*
return ((color & 0xf800) << 16)
| ((color & 0x07c0) << 13)
| ((color & 0x003e) << 10)
| ((color & 0x0001) ? 0xff : 0);
*/
Pixel c = ((unsigned long)(color & 0xf800) << 11L)
| ((unsigned long)(color & 0x07c0) << 8L)
| ((unsigned long)(color & 0x003e) << 5L);
return (c << 5L) | (c & 0x07070700L) | ((color & 0x0001) ? 0xff : 0);
}
static inline unsigned short Convert_24_16(Pixel p)
{
/*
return ((p & 0xf8000000) >> 16)
| ((p & 0x00f80000) >> 13)
| ((p & 0x0000f800) >> 10)
| ((p & 0x00000080) ? 1 : 0);
*/
return ((p & 0xf8000000L) >> 16)
| ((p & 0x00f80000L) >> 13)
| ((p & 0x0000f800L) >> 10)
| ((p & 0x000000ffL) > 250 ? 1 : 0);
}
int PicOutput_16_16(PicData *pd, Pixel *p)
{
int pixels = pd->pixelX;
PicWork *work = pd->work;
unsigned short nowlength = work->nowlength;
unsigned short nowcolor = work->nowcolor;
unsigned short color;
Pixel *pixel = work->pixelbuffer;
PicColorReduce(work->reduce, pixel, p);
for (; pixels > 0; --pixels) {
color = Convert_24_16(*pixel++);
if (color == nowcolor) {
if (nowlength == 65535) {
w_short(work->buffer+work->nowpoint, nowcolor);work->nowpoint++;
w_short(work->buffer+work->nowpoint, nowlength);work->nowpoint++;
if (work->nowpoint == BUFFERSIZE) {
fwrite(work->buffer, 1, BUFFERSIZE * sizeof(unsigned short), work->fp);
if (ferror(work->fp)) return FALSE;
work->totallength += BUFFERSIZE * 2;
work->nowpoint = 0;
}
nowlength = 0;
}
nowlength++;
} else {
if (nowlength > 0) {
w_short(work->buffer+work->nowpoint, nowcolor);work->nowpoint++;
w_short(work->buffer+work->nowpoint, nowlength);work->nowpoint++;
if (work->nowpoint == BUFFERSIZE) {
fwrite(work->buffer, 1, BUFFERSIZE * sizeof(unsigned short), work->fp);
if (ferror(work->fp)) return FALSE;
work->totallength += BUFFERSIZE * 2;
work->nowpoint = 0;
}
}
nowlength = 1;
nowcolor = color;
}
}
work->nowcolor = nowcolor;
work->nowlength = nowlength;
return TRUE;
}
int PicInput_16_16(PicData *pd, Pixel *pixel)
{
int pixels = pd->pixelX;
PicWork *work = pd->work;
Pixel nowpixel;
unsigned short nowlength = work->nowlength;
unsigned short nowcolor = work->nowcolor;
nowpixel = Convert_16_24(nowcolor);
while (nowlength <= pixels) {
pixels -= nowlength;
for (; nowlength > 0; --nowlength) {
*pixel++ = nowpixel;
}
nowcolor = r_short(work->buffer+work->nowpoint);work->nowpoint++;
nowlength = r_short(work->buffer+work->nowpoint);work->nowpoint++;
nowpixel = Convert_16_24(nowcolor);
if (work->nowpoint == BUFFERSIZE) {
fread(work->buffer, 1, BUFFERSIZE*sizeof(unsigned short), work->fp);
if (ferror(work->fp)) return FALSE;
work->nowpoint = 0;
}
}
nowlength -= pixels;
for (;pixels > 0; --pixels) {
*pixel++ = nowpixel;
}
work->nowlength = nowlength;
work->nowcolor = nowcolor;
return TRUE;
}
int PicClose_16_16(PicData *pd)
{
PicWork *work = pd->work;
if (pd->flag == PIC_WRITE) {
if (work->nowlength > 0) {
w_short(work->buffer+work->nowpoint, work->nowcolor);work->nowpoint++;
w_short(work->buffer+work->nowpoint, work->nowlength);work->nowpoint++;
}
if (work->nowpoint > 0) {
fwrite(work->buffer, 1, work->nowpoint * sizeof(unsigned short), work->fp);
if (ferror(work->fp)) return FALSE;
work->totallength += work->nowpoint * 2;
}
work->totallength -= 4;
fseek(work->fp, work->seek, SEEK_SET);
if (ferror(work->fp)) return FALSE;
fputc( work->totallength >> 24 , work->fp);
fputc((work->totallength >> 16) & 0xff, work->fp);
fputc((work->totallength >> 8) & 0xff, work->fp);
fputc((work->totallength ) & 0xff, work->fp);
PicColorReduceClose(work->reduce);
free(work->pixelbuffer);
}
fclose(work->fp);
free(work);
return TRUE;
}
PicFunction PicFunction_16_16 = {
"PIC",
PicReadHeader_16_16,
PicOpen_16_16,
PicOutput_16_16,
PicInput_16_16,
PicClose_16_16
};