static int NextInt(IOSTREAM *fstream) { int ch; int value = 0; int gotone = 0; int done = 0; /* loop, accumulate hex value until find delimiter */ /* skip any initial delimiters found in read stream */ while (!done) { if ( Sfeof(fstream) ) { value = -1; done++; } else { int dvalue; ch = Sgetc(fstream) & 0xff; if ( ch == '\r' ) continue; dvalue = hexTable[ch]; if ( dvalue >= 0 ) { value = (value << 4) + dvalue; gotone++; } else if ((hexTable[ch]) == -1 && gotone) done++; } } return value; }
static ssize_t ar_read(struct archive *a, void *cdata, const void **buffer) { archive_wrapper *ar = cdata; if ( Sfeof(ar->data) ) { return 0; } else { ssize_t bytes = ar->data->limitp - ar->data->bufp; *buffer = ar->data->bufp; ar->data->bufp = ar->data->limitp; ar->data->position->byteno += bytes; return bytes; } }
XImage * read_ppm_file(Display *disp, Colormap cmap, int depth, IOSTREAM *fd) { XImage *img; long here = Stell(fd); int c; int fmt, encoding; int width, height, bytes_per_line, scale=0; char *data; int allocdepth; int pad = XBitmapPad(disp); Visual *v = DefaultVisual(disp, DefaultScreen(disp)); ncolours = nmapped = nfailed = 0; /* statistics */ assert(pad%8 == 0); if ( (c=Sgetc(fd)) != 'P' ) { Sungetc(c, fd); return NULL; } if ( !cmap ) cmap = DefaultColormap(disp, DefaultScreen(disp)); c = Sgetc(fd); if ( c < '1' || c > '9' ) goto errout; c -= '0'; fmt = ((c - 1) % 3) + 1; encoding = c - fmt; width = getNum(fd); height = getNum(fd); if ( fmt == PNM_PBM ) { depth = 1; } else { scale = getNum(fd); if ( !depth ) depth = DefaultDepth(disp, DefaultScreen(disp)); } if ( width < 0 || height < 0 || scale < 0 ) goto errout; allocdepth = (depth >= 24 ? 32 : depth); bytes_per_line = roundup((width*allocdepth+7)/8, pad/8); data = (char *)pceMalloc(height * bytes_per_line); img = XCreateImage(disp, v, depth, fmt == PNM_PBM ? XYBitmap : ZPixmap, 0, data, width, height, pad, bytes_per_line); if ( !img ) { perror("XCreateImage"); pceFree(data); goto errout; } img->bits_per_pixel = depth; switch(encoding) { int x, y; case PNM_ASCII: { switch(fmt) { case PNM_PBM: for(y=0; y<height; y++) { for(x=0; x<width; x++) { int value = getNum(fd); if ( value < 0 || value > 1 ) goto errout; XPutPixel(img, x, y, value); } } break; case PNM_PGM: { Table t = newTable(64); for(y=0; y<height; y++) { for(x=0; x<width; x++) { int g = getNum(fd); unsigned long pixel; if ( g < 0 || g > scale ) goto errout; if ( scale != 255 ) g = rescale(g, scale, 255); pixel = colourPixel(disp, depth, cmap, t, g, g, g); XPutPixel(img, x, y, pixel); } } freeTable(t); break; } case PNM_PPM: { Table t = newTable(64); for(y=0; y<height; y++) { for(x=0; x<width; x++) { int r = getNum(fd); int g = getNum(fd); int b = getNum(fd); unsigned long pixel; if ( r < 0 || r > scale || g < 0 || g > scale || b < 0 || b > scale ) goto errout; if ( scale != 255 ) { r = rescale(r, scale, 255); g = rescale(g, scale, 255); b = rescale(b, scale, 255); } pixel = colourPixel(disp, depth, cmap, t, r, g, b); XPutPixel(img, x, y, pixel); } } freeTable(t); break; } break; } break; } case PNM_RAWBITS: { switch(fmt) { case PNM_PBM: { int byte = 0; int bit = 0; for(y=0; y<height; y++) { for(x=0; x<width; x++) { if ( !bit ) { byte = Sgetc(fd); bit = 8; } bit--; XPutPixel(img, x, y, (byte & (1<<bit)) ? 1 : 0); } bit = 0; /* scanlines are byte-aligned */ } break; } case PNM_PGM: { Table t = newTable(64); for(y=0; y<height; y++) { for(x=0; x<width; x++) { int g; unsigned long pixel; if ( Sfeof(fd) || (g=Sgetc(fd)) > scale ) goto errout; if ( scale != 255 ) g = rescale(g, scale, 255); pixel = colourPixel(disp, depth, cmap, t, g, g, g); XPutPixel(img, x, y, pixel); } } freeTable(t); break; } case PNM_PPM: { Table t = newTable(64); for(y=0; y<height; y++) { for(x=0; x<width; x++) { int r, g, b; unsigned long pixel; if ( Sfeof(fd) || (r=Sgetc(fd)) > scale || (g=Sgetc(fd)) > scale || (b=Sgetc(fd)) > scale ) goto errout; if ( scale != 255 ) { r = rescale(r, scale, 255); g = rescale(g, scale, 255); b = rescale(b, scale, 255); } pixel = colourPixel(disp, depth, cmap, t, r, g, b); XPutPixel(img, x, y, pixel); } } freeTable(t); break; } break; } break; } case PNM_RUNLEN: { int rlen = 0; unsigned long cpixel = NOPIXEL; switch(fmt) { case PNM_PGM: { Table t = newTable(64); DEBUG(NAME_pnm, Cprintf("Reading runlength encoded graymap\n")); for(y=0; y<height; y++) { for(x=0; x<width; x++) { if ( rlen-- > 0 ) { XPutPixel(img, x, y, cpixel); } else { int g; if ( (g=Sgetc(fd)) > scale || (rlen = Sgetc(fd)) == EOF ) goto errout; rlen &= 0xff; if ( scale != 255 ) g = rescale(g, scale, 255); cpixel = colourPixel(disp, depth, cmap, t, g, g, g); XPutPixel(img, x, y, cpixel); rlen--; } } } freeTable(t); break; } case PNM_PPM: { Table t = newTable(64); for(y=0; y<height; y++) { for(x=0; x<width; x++) { if ( rlen-- > 0 ) { XPutPixel(img, x, y, cpixel); } else { int r, g, b; if ( (r=Sgetc(fd)) > scale || (g=Sgetc(fd)) > scale || (b=Sgetc(fd)) > scale || (rlen = Sgetc(fd)) == EOF ) goto errout; rlen &= 0xff; if ( scale != 255 ) { r = rescale(r, scale, 255); g = rescale(g, scale, 255); b = rescale(b, scale, 255); } cpixel = colourPixel(disp, depth, cmap, t, r, g, b); XPutPixel(img, x, y, cpixel); rlen--; } } } freeTable(t); break; } } } } DEBUG(NAME_ppm, Cprintf("PNM: Converted %dx%dx%d image, %d colours (%d mapped, %d failed)\n", width, height, depth, ncolours, nmapped, nfailed)); return img; errout: DEBUG(NAME_ppm, Cprintf("PNM: Format error, index = %d\n", Stell(fd))); Sseek(fd, here, SEEK_SET); return NULL; }