📄 image.c
字号:
/*
* image.c -- funcs to use with GIMP C-Source dumps.
*
* (C)2000 Jordan DeLong & Dan Potter
*
* Adapted by Dan Potter to load PCXs from disk instead of using
* source dumps.
*
* For copying information, please see main.c
./dc/image.c:267: warning: type mismatch with previous implicit declaration
./dc/image.c:258: warning: previous implicit declaration of `alphacombine'
./dc/image.c:267: warning: `alphacombine' was previously implicitly declared to
return `int'
*/
#include "dream.h"
//#include "cdfs.h"
#include "image.h"
/* Port of an OLD OLD PCX loading function =) */
struct pcx_hdr {
char Mfg; /* manufacturer, always 0xa0 */
char Ver; /* encoder version number (5) */
char Enc; /* encoding code, always 1 */
char Bpp; /* bits per pixel, 8 in mode 0x13 */
uint16 Xmin,Ymin; /* image origin, usually 0,0 */
uint16 Xmax,Ymax; /* image dimensions */
uint16 Hres; /* horizontal resolution value */
uint16 Vres; /* vertical resolution value */
char Pal[48]; /* palette (not in mode 0x13) */
char Reserved; /* who knows? */
char ClrPlanes; /* number of planes, 1 in mode 0x13 */
uint16 Bpl; /* bytes per line, 80 in mode 0x13 */
uint16 plType; /* Grey or Color palette flag */
char Filler[58]; /* Zsoft wanted a 128 byte header */
};
unsigned short alphacombine(unsigned short clr0, unsigned char a0, unsigned short clr1, unsigned char a1) {
int r0 = (clr0 & 0xf800) >> 11;
int g0 = (clr0 & 0x07c0) >> 5;
int b0 = clr0 &0x001f;
int r1 = (clr1 & 0xf800) >> 11;
int g1 = (clr1 & 0x07c0) >> 5;
int b1 = clr1 &0x001f;
int r, g, b;
r = (r0 * a0 / 256) + (r1 * a1 / 256);
g = (g0 * a0 / 256) + (g1 * a1 / 256);
b = (b0 * a0 / 256) + (b1 * a1 / 256);
return (r << 11) | (g << 5) | b;
}
/* This function is now crufty beyond belief.. but whattadahell, it
seems to work alright =) */
Image *load_pcx_ex(unsigned char *pcx, int x) {
int fd;
int bytes = 0; /* counts unpacked bytes */
char c; /* byte being processed */
int runlen, i; /* length of packet */
int num_bytes;
struct pcx_hdr pcxh;
unsigned char *pcxpal;
Image *rv;
num_bytes=73814;
/* Wastes memory right now: but we have 8 megs to blow, so whassaaa.. */
// pcx = (unsigned char*)malloc(num_bytes);
if (x) for (i=0; i<num_bytes; i++) pcx[i] ^= x;
/* Load the PCX header */
// memcpy(&pcxh, pcx, sizeof(pcxh)); pcx += sizeof(pcxh);
// if (pcxh.Bpp!=8) {
// serial_printf("PCX data is not 8bpp\r\n");
// return 0;
// }
/* Allocate the output structure */
// rv = (Image*)malloc(sizeof(Image));
rv->width = pcxh.Xmax + 1;
rv->height = pcxh.Ymax + 1;
num_bytes = rv->width * rv->height;
// serial_printf("Image %s is %dx%d (%d bytes)\r\n", fn, rv->width, rv->height, num_bytes);
// rv->pixel_data = (unsigned short *)malloc(num_bytes * 2);
/* Do the RLE decoding */
serial_printf("Doing RLE decode\r\n");
{
unsigned char image[num_bytes];
do {
c = *pcx++; /* Read one byte */
if ((c & 0xc0) == 0xc0) { /* high 2 bits set is packet */
runlen = (c & 0x3f); /* AND off the high bits */
c = *pcx++;;
while(runlen--)
image[bytes++] = c;
}
else
image[bytes++] = c;
} while (bytes < num_bytes);
/* Load the palette */
serial_printf("Loading palette\r\n");
pcx++; /* This is a marker before the palette */
pcxpal = pcx;
/* Decode the image into RGB565 */
serial_printf("Doing palette decode\r\n");
for (i=0; i<num_bytes; i++) {
int v = image[i];
int r = pcxpal[v*3+0];
int g = pcxpal[v*3+1];
int b = pcxpal[v*3+2];
v = (((r >> 3) & 0x1f) << 11)
| (((g >> 2) & 0x3f) << 5)
| (((b >> 3) & 0x1f) << 0);
rv->pixel_data[i] = v;
}
}
serial_printf("Done, returning %08x\r\n", rv);
return rv;
}
Image *load_pcx(unsigned char *fn) { return load_pcx_ex(fn, 0); }
char *load_misc(char *fn) {
int fd, num_bytes;
char *rv;
/* Open the file (or die trying!! =) */
fd = iso_open(fn, O_RDONLY);
if (fd < 0) {
serial_printf("Couldn't open misc file %s\r\n", fn);
return NULL;
}
/* Assess the size of the file and make a temp buffer; thankfully
this old crufty hack still works =) */
iso_seek(fd, 0, SEEK_END);
num_bytes = iso_tell(fd);
iso_seek(fd, 0, SEEK_SET);
serial_printf("%s: loading %d bytes\r\n", fn, num_bytes);
/* Wastes memory right now: but we have 8 megs to blow, so whassaaa.. */
rv = (char*)malloc(num_bytes);
/* Load the PCX file */
iso_read(fd, rv, num_bytes);
iso_close(fd);
return rv;
}
void cpyrect(int width, int height, unsigned short *img, unsigned short *vptr) {
short x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
*vptr++ = *img++;
}
vptr += 640 - width;
img += 640 - width;
}
}
void putimage(int xpos, int ypos, Image *img, unsigned short *vptr) {
unsigned long width;
unsigned long height;
unsigned short *imgdata;
short x, y;
width = img->width;
height = img->height;
imgdata = img->pixel_data;
vptr += xpos + ypos * 640;
for (y = ypos; y < height + ypos; y++) {
for (x = xpos; x < width + xpos; x++) {
*vptr++ = *imgdata++;
}
vptr += 640 - width;
}
}
void eraseimage(int xpos, int ypos, Image *img, unsigned short *vptr) {
unsigned long width;
unsigned long height;
short x, y;
width = img->width;
height = img->height;
vptr += xpos + ypos * 640;
for (y = ypos; y < height + ypos; y++) {
for (x = xpos; x < width + xpos; x++) {
*vptr++ = 0x0000;
}
vptr += 640 - width;
}
}
void putimagetrans(int xpos, int ypos, Image *img, unsigned short *vptr) {
unsigned long width;
unsigned long height;
unsigned short *imgdata;
short x, y;
width = img->width;
height = img->height;
imgdata = img->pixel_data;
vptr += xpos + ypos * 640;
for (y = ypos; y < height + ypos; y++) {
for (x = xpos; x < width + xpos; x++) {
if (*imgdata != 0xf01e) {
*vptr = *imgdata;
}
vptr++;
imgdata++;
}
vptr += 640 - width;
}
}
/* put the shad using the aformentioned transparency shieBe in *img */
/* also do some clippage to prevent wrappage */
void putalphashadow(int xpos, int ypos, Image *img, unsigned short *vptr, unsigned char alpha) {
unsigned long width;
unsigned long height;
unsigned short *imgdata;
short x, y;
width = img->width;
height = img->height;
imgdata = img->pixel_data;
/* clipping, only neccessary on the left and right. so don't make negative shadowdirs */
if (xpos >= 640)
return;
if (ypos >= 480)
return;
if (xpos + width >= 640)
width = 639 - xpos;
if (ypos + height >= 480)
height = 479 - ypos;
vptr += xpos + ypos * 640;
for (y = ypos; y < height + ypos; y++) {
for (x = xpos; x < width + xpos; x++) {
if (*imgdata != 0xf01e) {
*vptr = alphacombine(0x0000, alpha, *vptr, 256 - alpha);
}
vptr++;
imgdata++;
}
vptr += 640 - width;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -