|
|
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.