#ifndef lint static char sccsid[] = "@(#)sgigt.c 1.4 3/21/89"; #endif #include #include #include #include "tiffio.h" static int width, height; extern char *getenv(); static int length; static u_long *raster; /* displayable image */ static Cursor hourglass = { 0x1ff0, 0x1ff0, 0x0820, 0x0820, 0x0820, 0x0c60, 0x06c0, 0x0100, 0x0100, 0x06c0, 0x0c60, 0x0820, 0x0820, 0x0820, 0x1ff0, 0x1ff0 }; main(argc, argv) char *argv[]; { int i, xoff, yoff; char *origin, *pausetime, *cp, *rindex(), *getenv(); short c, val; TIFFDirectory *td; TIFF *tif; tif = TIFFOpen(argv[1], "r"); if (tif == NULL) exit(-1); if (argc > 1) { i = atoi(argv[2])-1; while (i > 0 && TIFFReadDirectory(tif)) i--; if (i > 0) { fprintf(stderr, "%s: Not that many directories.\n", argv[2]); exit(-1); } } td = tif->tif_dir; if (td->td_bitspersample != 1 && td->td_bitspersample != 4 && td->td_bitspersample != 8 && td->td_bitspersample != 16) { fprintf(stderr, "Sorry, can only handle 1, 4, and 8-bit pictures\n"); exit(-1); } if (td->td_samplesperpixel != 1 && td->td_samplesperpixel != 3 && td->td_samplesperpixel != 4) { fprintf(stderr, "Sorry, can only handle 1-channel gray scale or 3-channel color images\n"); exit(-1); } width = td->td_imagewidth; if (width > 1100) /* big windows crash system */ width = 1100; height = td->td_imagelength; origin = getenv("DSPYORIGIN"); if (origin && sscanf(origin, "%d,%d", &xoff, &yoff) == 2) prefposition(xoff, xoff + width - 1, yoff, yoff + height - 1); else prefsize(width, height); cp = rindex(argv[1], '/'); if (cp == NULL) cp = argv[1]; else cp++; if (winopen(cp) < 0) { fprintf(stderr, "Can't create window.\n"); exit(-1); } raster = (u_long *)malloc(width * height * sizeof (long)); if (raster == 0) { fprintf(stderr, "No space for raster buffer\n"); exit(-1); } pseudorgb(); curstype(C16X1); defcursor(1, hourglass); setcursor(1, 0, 0); if (gt(tif, width, height, raster)) { setcursor(0, 0, 0); TIFFClose(tif); for (;;) { lrectwrite(0, 0, width-1, height-1, raster); while (qread(&val) != REDRAW) ; } } exit(0); } #define howmany(x, y) (((x)+((y)-1))/(y)) static gt(tif, w, h, raster) TIFF *tif; int w, h; u_long *raster; { register u_char *pp; register u_long *cp; register RGBvalue c; register int x, range; register u_short *wp; RGBvalue *Map = NULL; int scanline; u_char *buf; TIFFDirectory *td; td = tif->tif_dir; scanline = td->td_bitspersample * td->td_imagewidth; if (td->td_planarconfig == PLANARCONFIG_CONTIG) scanline *= td->td_samplesperpixel; buf = (u_char *)malloc(howmany(scanline, 8)); if (buf == 0) { fprintf(stderr, "No space for scanline buffer\n"); return (0); } if (td->td_photometric != PHOTOMETRIC_RGB || td->td_minsamplevalue != 0 || td->td_maxsamplevalue != 255) { range = td->td_maxsamplevalue - td->td_minsamplevalue + 1; Map = (RGBvalue *)malloc(range * sizeof (RGBvalue)); if (Map == NULL) { fprintf(stderr, "No space for mapping table\n"); return; } switch (td->td_photometric) { case PHOTOMETRIC_RGB: case PHOTOMETRIC_MINISBLACK: for (x = 0; x < range; x++) Map[x] = (x * 255) / range; break; case PHOTOMETRIC_MINISWHITE: for (x = 0; x < range; x++) Map[x] = ((range - x) * 255) / range; break; } } while (h-- > 0 && TIFFReadScanline(tif, buf) > 0) { pp = buf; cp = raster + (h-1)*w; switch (td->td_photometric) { case PHOTOMETRIC_RGB: switch (td->td_bitspersample) { case 8: if (td->td_samplesperpixel == 4) { lrectwrite(0, h-1, w-1, h, buf); continue; } for (x = w; x-- > 0;) { *cp++ = rgbi(pp[0], pp[1], pp[2]); pp += 3; } break; case 16: wp = (u_short *)pp; for (x = w; x-- > 0;) { *cp++ = rgbi(Map[wp[0]], Map[wp[1]], Map[wp[2]]); wp += td->td_samplesperpixel; } break; } break; case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISBLACK: switch (td->td_bitspersample) { case 1: for (x = 0; x < w; x += 8) { c = Map[(*pp >> 7) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 6) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 5) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 4) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 3) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 2) & 1]; *cp++ = rgbi(c, c, c); c = Map[(*pp >> 1) & 1]; *cp++ = rgbi(c, c, c); c = Map[*pp++ & 1]; *cp++ = rgbi(c, c, c); } break; case 4: for (x = 0; x < w; x += 2) { c = Map[*pp >> 4]; *cp++ = rgbi(c, c, c); c = Map[*pp++ & 0xf]; *cp++ = rgbi(c, c, c); } break; case 8: for (x = w; x-- > 0;) { c = Map[*pp++]; *cp++ = rgbi(c, c, c); } break; } break; } } done: if (Map) free((char *)Map); free((char *)buf); }