|
|
1.1 ! root 1: /* ! 2: * $Source: /orpheus/u1/X11/NRFPT/puzzle/RCS/VEGview.c,v $ ! 3: * $Header: VEGview.c,v 1.1 87/09/08 17:25:06 swick Exp $ ! 4: */ ! 5: ! 6: #ifndef lint ! 7: static char *rcsid_VEGview_c = "$Header: VEGview.c,v 1.1 87/09/08 17:25:06 swick Exp $"; ! 8: #endif lint ! 9: ! 10: ! 11: #define DEBUG ! 12: ! 13: /* ! 14: * VEGview (c) 1987 Hewlett-Packard Labs. ! 15: * ! 16: * Author: Jack Palevich ! 17: * ! 18: * View Video Enhanced Graphics images on X-Windows ! 19: * Inspired by Ed Moy's Xdisp program ! 20: */ ! 21: ! 22: #include <stdio.h> ! 23: #include <sys/types.h> ! 24: #include <sys/file.h> ! 25: #include <fcntl.h> ! 26: ! 27: #include <X11/Xlib.h> ! 28: #include <X11/Xatom.h> ! 29: ! 30: #include "pmap.h" ! 31: #include "VEGview.h" ! 32: ! 33: #define PM_DISPLAY 0 ! 34: #define PM_CONVERT 1 ! 35: #define IFPMD if(program_mode == PM_DISPLAY) ! 36: #define IFPMC if(program_mode == PM_CONVERT) ! 37: ! 38: extern Display *dpy; ! 39: extern int screen; ! 40: extern GC gc; ! 41: extern Colormap PuzzleColormap; ! 42: ! 43: Pixmap VEGsetup(RasterFile,width,height) ! 44: char *RasterFile; ! 45: int *width, *height; ! 46: { ! 47: ! 48: int shades, red_shades, green_shades, blue_shades; ! 49: int i,j; ! 50: int numColors; ! 51: unsigned char *xmap, *data; ! 52: XColor *colormap; ! 53: pixel_map *pm; ! 54: Pixmap PicturePixmap; ! 55: ! 56: read_raster_file(&pm,RasterFile); ! 57: ! 58: switch ((*pm).type) { ! 59: case 3: shades = 16; ! 60: reduce_grey(pm, shades, &xmap, &colormap, &numColors); ! 61: break; ! 62: case 6: red_shades = 3; ! 63: green_shades = 4; ! 64: blue_shades = 2; ! 65: reduce_color(pm, red_shades, green_shades, blue_shades, ! 66: &xmap, &colormap, &numColors); ! 67: break; ! 68: default:fprintf(stderr, "Can't interpret this type of PMAP.\n"); ! 69: exit(1); ! 70: break; ! 71: } ! 72: ! 73: *width = (*pm).w; ! 74: *height = (*pm).h; ! 75: ! 76: if (get_ro_colors(colormap, numColors)) ! 77: exit(1); ! 78: ! 79: ! 80: /* Convert from virtual color_map to actual color_map */ ! 81: ! 82: for ( j = 0; j < pm->h; j++) { ! 83: data = xmap + pm->w * j; ! 84: for (i = 0; i < pm->w; i++) ! 85: data[i] = colormap[data[i]].pixel; ! 86: } ! 87: ! 88: /* Try to cache the data as a Pixmap on the server */ ! 89: ! 90: { ! 91: XImage image; ! 92: ! 93: image.width = pm->w; ! 94: image.height = pm->h; ! 95: image.xoffset = 0; ! 96: image.format = ZPixmap; ! 97: image.data = (char *) xmap; ! 98: image.byte_order = MSBFirst; ! 99: image.bitmap_unit = 8; ! 100: image.depth = 8; ! 101: image.bytes_per_line = pm->w; ! 102: image.bits_per_pixel = 8; ! 103: ! 104: PicturePixmap = XCreatePixmap(dpy,RootWindow(dpy,screen), ! 105: image.width,image.height,8); ! 106: XPutImage(dpy,PicturePixmap,gc,&image,0,0,0,0, ! 107: image.width,image.height); ! 108: } ! 109: return(PicturePixmap); ! 110: } ! 111: ! 112: /* Reduce the 8 bpp pixel map to at most 'shades' shades of ! 113: * grey, by using error diffusion. ! 114: * Floyd & Steinberg / "An Adaptive Algorithm for Spatial Greyscale " ! 115: * Proceeding of the S.I.D. Vol. 17/2 Second Quarter 1976 ! 116: * x x x A = 7/16 of the error ! 117: * x p A B = 1/16 of the error ! 118: * D C B C = 5/16 of the error ! 119: * D = 3/16 of the error ! 120: * pixel_map *pm - source pixel map ! 121: * int shades - number of shades of grey requested ! 122: * unsigned char **xmap - pointer to where to return pointer to reduced image ! 123: * Color *color_map - color map to fill in with shades we use. ! 124: * int *numColors - number of colors actually used. ! 125: */ ! 126: ! 127: reduce_grey(pm, shades, xmap, color_map_p, num_colors) ! 128: pixel_map *pm; ! 129: int shades; ! 130: unsigned char **xmap; ! 131: XColor **color_map_p; ! 132: int *num_colors; ! 133: { ! 134: int w, h, scale, h_scale, i, j, x, y, n, m; ! 135: short e, e1, e3, e5, e7, ea, eb; ! 136: unsigned char to_shade[256], *crow; ! 137: short *nrow, *nrow_p; ! 138: int *there; ! 139: float f; ! 140: unsigned char *data; ! 141: unsigned char *vgrey; ! 142: XColor *color_map; ! 143: ! 144: w = pm->w; ! 145: h = pm->h; ! 146: nrow_p = (short *) calloc(w+2, sizeof(*nrow)); ! 147: nrow = nrow_p + 1; /* vector is -1..w */ ! 148: ! 149: /* Fill to_shade table */ ! 150: if ( shades < 2 ) return(0); ! 151: scale = 255 / (shades - 1); ! 152: for ( i = 0; i < 256; i++) { ! 153: f = i / 255.0; ! 154: n = f * (shades-1) + 0.5; ! 155: m = n * scale; ! 156: if ( m > 255) m = 255; ! 157: to_shade[i] = m; ! 158: } ! 159: ! 160: /* Error diffuse */ ! 161: ! 162: for ( y = 0; y < h; y++ ) { ! 163: crow = (unsigned char *) (pm->pixels + (pm->stride * y)); ! 164: eb = 0; /* Traveling 'B' error term */ ! 165: ea = 0; /* Traveling 'A' error term */ ! 166: for ( x = 0; x < w; x++ ) { ! 167: n = crow[x] + nrow[x] + ea; ! 168: m = to_shade[n < 0 ? 0 : (n > 255 ? 255 : n)]; ! 169: crow[x] = m; ! 170: e = n - m; ! 171: e1 = e / 16; ! 172: e3 = e1 + e1 + e1; ! 173: e5 = e3 + e1 + e1; ! 174: e7 = e - e5 - e3 - e1; ! 175: nrow[x-1] += e3; /* 'D' term */ ! 176: nrow[x] = eb + e5; /* 'C' term and last 'B' term */ ! 177: eb = e1; /* new 'B' term */ ! 178: ea = e7; /* new 'A' term */ ! 179: } /* each pixel */ ! 180: } /* each row */ ! 181: free(nrow_p); ! 182: ! 183: /* Find out how many colors we actually used */ ! 184: ! 185: there = (int *) calloc(256, sizeof (*there)); ! 186: ! 187: for ( j = 0; j < pm->h; j++) { ! 188: data = (unsigned char *) pm->pixels + pm->stride * j; ! 189: for (i = 0; i < pm->w; i++) { ! 190: there[data[i]]++; ! 191: } ! 192: } ! 193: ! 194: /* Convert to a virtual color map */ ! 195: ! 196: vgrey = (unsigned char *) calloc(shades, sizeof(*vgrey)); ! 197: ! 198: i = 0; ! 199: for ( j = 0; j < 256; j++ ) { ! 200: if ( there[j] ) { ! 201: /* A new color */ ! 202: there[j] = i; ! 203: vgrey[i] = j; ! 204: i++; ! 205: } ! 206: } ! 207: ! 208: color_map = (XColor *) calloc(i, sizeof(XColor)); ! 209: ! 210: *color_map_p = color_map; ! 211: ! 212: *num_colors = i; ! 213: ! 214: for ( j = 0; j < i; j++) { ! 215: color_map[j].red = ! 216: color_map[j].green = ! 217: color_map[j].blue = ! 218: vgrey[j] << 8; ! 219: } ! 220: ! 221: free(vgrey); ! 222: ! 223: for ( j = 0; j < pm->h; j++) { ! 224: data = (unsigned char *) pm->pixels + pm->stride * j; ! 225: for (i = 0; i < pm->w; i++) { ! 226: data[i] = there[data[i]]; ! 227: } ! 228: } ! 229: ! 230: free(there); ! 231: ! 232: *xmap = (unsigned char *) pm->pixels; ! 233: ! 234: } ! 235: ! 236: ! 237: read_raster_file(ppm, name) ! 238: pixel_map **ppm; ! 239: char *name; ! 240: { ! 241: pixel_map *pm; ! 242: FILE *is; ! 243: ! 244: pm = new_pixel_map(); ! 245: *ppm = pm; ! 246: ! 247: if (NULL == (is = pixel_map_open(pm, name))) { ! 248: fprintf(stderr, "Couldn't open %s\n", name); ! 249: return(NULL); ! 250: } ! 251: if (NULL == pixel_map_alloc(pm)) { ! 252: fprintf(stderr, "Couldn't allocate storage for pixel map\n"); ! 253: fclose(is); ! 254: return(NULL); ! 255: } ! 256: if (0 == pixel_map_read(pm, is)) { ! 257: fprintf(stderr, "Couldn't read pixel map\n"); ! 258: fclose(is); ! 259: return(NULL); ! 260: } ! 261: fclose(is); ! 262: ! 263: if ( pm->type == YF_TYPE) { ! 264: pm->type = 3; ! 265: pm->stride = pm->stride / 2; ! 266: } ! 267: } ! 268: ! 269: get_ro_colors(color_map, numColors) ! 270: XColor *color_map; ! 271: int numColors; ! 272: { ! 273: int i; ! 274: XColor color; ! 275: ! 276: for (i = 0; i < numColors; i++) { ! 277: /* Need a read-only color for this value */ ! 278: if (!XAllocColor(dpy,PuzzleColormap,&color_map[i])) { ! 279: fprintf(stderr, "not enough colors (asked for %d, got %d).\n", ! 280: numColors, i); ! 281: return (-1); ! 282: } ! 283: #ifdef DEBUG ! 284: else ! 285: printf("color %d pixel value is %d\n",i,color_map[i].pixel); ! 286: #endif DEBUG ! 287: } ! 288: return(0); ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.