📄 devimage.c
字号:
static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage){ char buf[256], *p; int type = PNM_TYPE_NOTPNM, binary = 0, gothdrs = 0, scale = 0; int ch, x = 0, y = 0, i, n, mask, col1, col2, col3; 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 0x01000000static 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 + -