📄 devimage.c
字号:
bseek(src, 0L, 0);
if(!bgets(src,buf, 4)) return 0;
if(!strcmp("P1\n", buf)) type = PNM_TYPE_PBM;
else if(!strcmp("P2\n", buf)) type = PNM_TYPE_PGM;
else if(!strcmp("P3\n", buf)) type = PNM_TYPE_PPM;
else if(!strcmp("P4\n", buf)) {
type = PNM_TYPE_PBM;
binary = 1;
}
else if(!strcmp("P5\n", buf)) {
type = PNM_TYPE_PGM;
binary = 1;
}
else if(!strcmp("P6\n", buf)) {
type = PNM_TYPE_PPM;
binary = 1;
}
if(type == PNM_TYPE_NOTPNM) return 0;
n = 0;
while((p = bgets(src, buf, 256))) {
if(*buf == '#') continue;
if(type == PNM_TYPE_PBM) {
if(sscanf(buf, "%i %i", &pimage->width,
&pimage->height) == 2) {
pimage->bpp = 1;
gothdrs = 1;
if(!(pimage->palette = malloc(
sizeof(MWPALENTRY) * 2))) {
EPRINTF("Out of memory\n");
return 2;
}
pimage->palsize = 2;
pimage->palette[0].r = 0xff;
pimage->palette[0].g = 0xff;
pimage->palette[0].b = 0xff;
pimage->palette[1].r = 0;
pimage->palette[1].g = 0;
pimage->palette[1].b = 0;
}
break;
}
if((type == PNM_TYPE_PGM) || (type == PNM_TYPE_PPM)) {
if(!n++) {
if(sscanf(buf, "%i %i", &pimage->width,
&pimage->height) != 2) break;
} else {
if(sscanf(buf, "%i", &i) != 1) break;
pimage->bpp = 24;
if(i > 255) {
EPRINTF("LoadPNM: PPM files must be "
"24bpp\n");
return 2;
}
for(scale = 7, n = 2; scale; scale--, n *= 2)
if(i < n) break;
gothdrs = 1;
break;
}
}
}
if(!gothdrs) {
EPRINTF("LoadPNM: bad image headers\n");
if(pimage->palette) free(pimage->palette);
return 2;
}
pimage->planes = 1;
ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
&pimage->bytesperpixel);
pimage->compression = MWIMAGE_RGB;
if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
EPRINTF("LoadPNM: couldn't allocate memory for image\n");
if(pimage->palette) free(pimage->palette);
return 2;
}
p = pimage->imagebits;
if(type == PNM_TYPE_PBM) {
if(binary) {
x = 0;
y = 0;
while((ch = bgetc(src)) != EOF) {
for(i = 0; i < 8; i++) {
mask = 0x80 >> i;
if(ch & mask) *p |= mask;
else *p &= ~mask;
if(++x == pimage->width) {
if(++y == pimage->height)
return 1;
p = pimage->imagebits - 1 +
(y * pimage->pitch);
x = 0;
break;
}
}
p++;
}
} else {
n = 0;
while((ch = bgetc(src)) != EOF) {
if(isspace(ch)) continue;
mask = 0x80 >> n;
if(ch == '1') *p |= mask;
else if(ch == '0') *p &= ~mask;
else goto baddata;
if(++n == 8) {
n = 0;
p++;
}
if(++x == pimage->width) {
if(++y == pimage->height)
return 1;
p = pimage->imagebits +
(y * pimage->pitch);
n = 0;
x = 0;
}
}
}
} else {
while(1) {
if(type == PNM_TYPE_PGM) {
if(binary) {
if((ch = bgetc(src)) == EOF)
goto baddata;
} else {
// if(fscanf(fp, "%i", &ch) != 1)
goto baddata;
}
*p++ = ch << scale;
*p++ = ch << scale;
*p++ = ch << scale;
} else {
if(binary) {
if(((col1 = bgetc(src)) == EOF) ||
((col2 = bgetc(src)) == EOF) ||
((col3 = bgetc(src)) == EOF))
goto baddata;
} else {
// if(fscanf(fp, "%i %i %i", &col1, &col2,
// &col3) != 3)
goto baddata;
}
*p++ = col1 << scale;
*p++ = col2 << scale;
*p++ = col3 << scale;
}
if(++x == pimage->width) {
if(++y == pimage->height) return 1;
p = pimage->imagebits + (y * pimage->pitch);
x = 0;
}
}
}
baddata:
EPRINTF("LoadPNM: bad image data\n");
free(pimage->imagebits);
if(pimage->palette) free(pimage->palette);
return 2;
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT) */
#if defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)
struct xpm_cmap {
char mapstr[3];
long palette_entry;
long color;
struct xpm_cmap *next;
};
static long XPM_parse_color(char *color)
{
/* This will parse the string into a color value of some sort */
if (color[0] != '#')
{
if (!strcmp(color, "None"))
return(-1); /* Transparent */
else
return(0); /* If its an X color, then we bail */
}
else
{
/* This is ugly! */
char *sptr = color + 1;
char rstr[5], gstr[5], bstr[5];
long r,g,b;
switch(strlen(sptr))
{
case 6:
return(strtol(sptr, NULL, 16));
case 9: /* RRRGGGBBB */
strncpy(rstr, sptr, 3);
strncpy(gstr, sptr + 3, 3);
strncpy(bstr, sptr + 6, 3);
rstr[3] = 0;
gstr[3] = 0;
bstr[3] = 0;
r = strtol(rstr, NULL, 16) >> 4;
g = strtol(gstr, NULL, 16) >> 4;
b = strtol(bstr, NULL, 16) >> 4;
return( (long) ( r << 16 | g << 8 | b));
case 12:
strncpy(rstr, sptr, 4);
strncpy(gstr, sptr + 4, 4);
strncpy(bstr, sptr + 8, 4);
rstr[4] = 0;
gstr[4] = 0;
bstr[4] = 0;
r = strtol(rstr, NULL, 16) >> 8;
g = strtol(gstr, NULL, 16) >> 8;
b = strtol(bstr, NULL, 16) >> 8;
return( (long) ( (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)));
}
}
return(0);
}
/* A series of status indicators that let us know whats going on */
/* It could be an enum if you want */
#define LOAD_HEADER 1
#define LOAD_COLORS 2
#define LOAD_PALETTE 3
#define LOAD_PIXELS 4
#define LOAD_DONE 5
/* The magic that "should" indicate an XPM (does it really?) */
#define XPM_MAGIC "/* XPM */"
#define XPM_TRANSCOLOR 0x01000000
static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd)
{
struct xpm_cmap *colorheap = 0; /* A "heap" of color structs */
struct xpm_cmap *colormap[256]; /* A quick hash of 256 spots for colors */
unsigned char *imageptr = 0;
MWSCREENINFO sinfo;
char xline[300];
char dline[300];
char *c;
int a;
int col, row, colors, cpp;
int in_color = 0;
int read_xline = 0;
int status = LOAD_HEADER;
/* Very first thing, get the screen info */
GdGetScreenInfo(psd, &sinfo);
for(a = 0; a < 256; a++)
colormap[a] = 0;
pimage->imagebits = NULL;
pimage->palette = NULL;
/* Start over at the beginning with the file */
bseek(src, 0, SEEK_SET);
bgets(src, xline, 300);
/* Chop the EOL */
xline[strlen(xline) - 1] = 0;
/* Check the magic */
if (strncmp(xline, XPM_MAGIC, sizeof(XPM_MAGIC))) return(0);
while(!beof(src))
{
/* Get the next line from the file */
bgets(src,xline, 300);
xline[strlen(xline) - 1] = 0;
/* Check it out */
if (xline[0] == '/' && xline[1] == '*') /* Comment */
continue;
if (xline[0] != '\"')
continue;
/* remove the quotes from the line */
for(c = xline + 1, a = 0; *c != '\"' && *c != 0; c++, a++)
dline[a] = *c;
dline[a] = 0;
/* Is it the header? */
if (status == LOAD_HEADER)
{
sscanf(dline, "%i %i %i %i", &col, &row, &colors, &cpp);
pimage->width = col;
pimage->height = row;
pimage->planes = 1;
if (sinfo.bpp <= 8)
{
pimage->bpp = sinfo.bpp;
pimage->compression = 0;
pimage->transcolor = -1;
}
else
{
pimage->bpp = 32;
pimage->transcolor = XPM_TRANSCOLOR;
pimage->compression = MWIMAGE_BGR;
}
pimage->palsize = colors;
ComputePitch(pimage->bpp, col, &pimage->pitch, &pimage->bytesperpixel);
pimage->imagebits = malloc(pimage->pitch * pimage->height);
imageptr = (unsigned char *) pimage->imagebits;
/* Allocate enough room for all the colors */
colorheap = (struct xpm_cmap *) malloc(colors * sizeof(struct xpm_cmap));
/* Allocate the palette space (if required) */
if (sinfo.bpp <= 8)
pimage->palette = malloc(256*sizeof(MWPALENTRY));
if (!colorheap)
{
EPRINTF("Couldn't allocate any memory for the colors\n");
return(0);
}
status = LOAD_COLORS;
in_color = 0;
continue;
}
/* Are we in load colors? */
if (status == LOAD_COLORS)
{
struct xpm_cmap *n;
char tstr[5];
char cstr[256];
unsigned char m;
c = dline;
/* Go at at least 1 charater, and then count until we have
two spaces in a row */
strncpy(tstr, c, cpp);
c += cpp;
for(; *c == '\t' || *c == ' '; c++); /* Skip over whitespace */
/* FIXME: We assume that a 'c' follows. What if it doesn't? */
c +=2;
tstr[cpp] = 0;
/* Now we put it into the array for easy lookup */
/* We base it off the first charater, even though */
/* there may be up to 4 */
m = tstr[0];
if (colormap[m])
{
n = colormap[m];
while(n->next) n = n->next;
n->next = &colorheap[in_color];
n = n->next;
}
else
{
colormap[m] = &colorheap[in_color];
n = colormap[m];
}
n->next = 0;
/* Record the string */
strncpy(n->mapstr, tstr, cpp);
n->mapstr[cpp] = 0;
/* Now record the palette entry */
n->palette_entry = (long) in_color;
/* This is the color */
sscanf(c, "%65535s", cstr);
/* Turn it into a real value */
n->color = XPM_parse_color(cstr);
/* If we are in palette mode, then we need to */
/* load the palette (duh..) */
if (sinfo.bpp <= 8)
{
if (n->color == -1)
{
pimage->transcolor = in_color;
n->color = -1;
}
pimage->palette[in_color].r = (n->color >> 16) & 0xFF;
pimage->palette[in_color].g = (n->color >> 8) & 0xFF;
pimage->palette[in_color].b = n->color & 0xFF;
}
else
{
if (n->color == -1)
n->color = XPM_TRANSCOLOR;
}
if (++in_color == colors)
{
read_xline = 0;
status = LOAD_PIXELS;
}
continue;
}
if (status == LOAD_PIXELS)
{
int bytecount = 0;
int bitcount = 0;
long dwordcolor = 0;
int i;
char pxlstr[3];
c = dline;
while(*c)
{
unsigned char z = 0;
if (cpp == 1)
{
z = *c;
if (!colormap[z])
{
EPRINTF("No color entry for (%c)\n", z);
return(0);
}
if (sinfo.bpp <= 8)
dwordcolor = (long) colormap[z]->palette_entry;
else
dwordcolor = colormap[z]->color;
c++;
}
else
{
struct xpm_cmap *n;
/* We grab the largest possible, and then compare */
strncpy(pxlstr, c, cpp);
z = pxlstr[0];
if (!colormap[z])
{
EPRINTF("No color entry for (%s)\n", pxlstr);
return(0);
}
n = colormap[z];
while(n)
{
if (!strncmp(n->mapstr, pxlstr, cpp))
break;
n = n->next;
}
if (!n)
{
EPRINTF("No color found for (%s)\n", pxlstr);
return(0);
}
if (sinfo.bpp <= 8)
dwordcolor = (long) n->palette_entry;
else
dwordcolor = n->color;
c += cpp;
}
/*
* This ugly thing is needed to ensure that we
* work well in all modes.
*/
switch(sinfo.bpp)
{
case 2:
if (bitcount == 0)
imageptr[0] = 0;
imageptr[0] |= (dwordcolor & 0x3) << (4 - bitcount);
bitcount++;
if (bitcount == 4)
{
imageptr++;
bytecount += pimage->bytesperpixel;
bitcount = 0;
}
break;
case 4:
if (bitcount == 0)
imageptr[0] = 0;
imageptr[0] |= (dwordcolor & 0xF) << (2 - bitcount);
bitcount++;
if (bitcount == 2)
{
imageptr++;
bytecount += pimage->bytesperpixel;
bitcount = 0;
}
break;
case 8:
case 16:
case 24:
case 32:
for(i = 0; i < pimage->bytesperpixel; i++)
imageptr[i] = (dwordcolor >> (8 * i)) & 0xFF;
imageptr += pimage->bytesperpixel;
bytecount += pimage->bytesperpixel;
break;
#ifdef NOTUSED
case 8:
imageptr[0] = (unsigned char) (dwordcolor & 0xFF);
imageptr += pimage->bytesperpixel;
bytecount += pimage->bytesperpixel;
break;
case 16:
case 24:
case 32:
imageptr[0] = (unsigned char) (dwordcolor >> 24) & 0xFF;
imageptr[1] = (unsigned char) (dwordcolor >> 16) & 0xFF;
imageptr[2] = (unsigned char) (dwordcolor >> 8) & 0xFF;
imageptr[3] = (unsigned char) (dwordcolor & 0xFF);
imageptr += pimage->bytesperpixel;
bytecount += pimage->bytesperpixel;
break;
#endif
}
}
/* Pad to the end of the line */
if (bytecount < pimage->pitch)
for(i = 0; i < (pimage->pitch - bytecount); i++)
*imageptr++ = 0x00;
read_xline++;
if (read_xline == row)
status = LOAD_DONE;
continue;
}
}
free(colorheap);
if (status != LOAD_DONE)
return(-1);
return(1);
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)*/
#endif /* defined(HAVE_FILEIO)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -