|
|
1.1 root 1: #include <stdio.h>
2: #include <sgtty.h>
3: #include <sys/types.h>
4: #include <sys/stat.h>
5: #include "piclib.h"
6:
7: extern char *malloc();
8: static getfile(), getwindow(), gettd(), unwind(), putwindow(), puttd(), tdheader();
9:
10: openf(s, image)
11: char *s;
12: struct pfile *image;
13: {
14: int fd;
15:
16: strcpy(image->name, s);
17: if ((fd = open(s, 0)) >= 0)
18: { fd = readheader(fd, image);
19: if (image->type != RUNCODE)
20: return fd;
21: }
22: return -1;
23: }
24:
25: newf(image)
26: struct pfile *image;
27: {
28: int w = image->r.corner.x - image->r.origin.x;
29: int h = image->r.corner.y - image->r.origin.y;
30:
31: switch (image->nchan) {
32: default: image->pixblu = (unsigned char *) malloc(w*h); /* fall through */
33: case 2: image->pixgrn = (unsigned char *) malloc(w*h); /* fall through */
34: case 1: image->pixred = (unsigned char *) malloc(w*h); break;
35: }
36: if (image->pixred == NULL)
37: return 0;
38: switch (image->nchan) {
39: default: break;
40: case 1: image->pixgrn = image->pixred; /* fall through */
41: case 2: image->pixblu = image->pixred; break;
42: }
43: return 1;
44: }
45:
46: closef(image)
47: struct pfile *image;
48: {
49: switch (image->nchan) {
50: case 3: if (image->pixblu) free(image->pixblu);
51: case 2: if (image->pixgrn) free(image->pixgrn);
52: case 1: if (image->pixred) free(image->pixred);
53: default: break;
54: }
55: }
56:
57: dumpf(s, image)
58: char *s;
59: struct pfile *image;
60: {
61: int fd, res=1;
62:
63: if ((fd = creat(s, 0666)) <= 0)
64: return 0;
65:
66: switch (image->type) {
67: case PICO:
68: res = putfile(fd, image);
69: break;
70: case RUNCODE:
71: case DUMP:
72: res = puttd(fd, image);
73: break;
74: }
75: close(fd);
76: return res;
77: }
78:
79: readheader(fd, files)
80: struct pfile *files;
81: { char line[512];
82: int i, a, b, c, d, n, sawtype=0;
83: extern double sqrt();
84: struct sgttyb sttybuf, sttysave;
85: struct stat stbuf;
86:
87: files->r.origin.x = files->r.origin.y = 0;
88: files->r.corner.x = files->r.corner.y = 0;
89: files->pixred = files->pixgrn = files->pixblu = NULL;
90: files->nchan = 1;
91: lseek(fd, 0L, 0);
92: for (;;)
93: { for (i = 0; i < 127; i++)
94: { read(fd, &line[i], 1);
95: if (line[i] == '\n')
96: { line[i] = '\0';
97: break;
98: } }
99: if (i == 0)
100: { if (sawtype)
101: return fd; /* end of header */
102: i = 127;
103: }
104: if (i == 127)
105: { lseek(fd, 0L, 0);
106: fstat(fd, &stbuf);
107: n = (int) sqrt(stbuf.st_size+1.0);
108: files->r.corner.x = files->r.corner.y = n;
109: files->type = PICO;
110: files->nchan = 1;
111: return fd; /* no header */
112: }
113: if (sscanf(line, "WINDOW=%d %d %d %d", &a, &b, &c, &d) == 4)
114: { if (a > c) i = a, a = c, c = i; /* flip */
115: if (b > d) i = b, b = d, d = i;
116: if (a < 0) c -= a, a = 0; /* normalize */
117: if (b < 0) d -= b, b = 0;
118: files->r.origin.x = a; files->r.origin.y = b;
119: files->r.corner.x = c; files->r.corner.y = d;
120: } else if (sscanf(line, "NCHAN=%d", &a) == 1)
121: { files->nchan = a;
122: } else if (strncmp(line, "CHAN=", 5) == 0
123: && (line[5] == 'm' || line[5] == 'r' ||
124: line[5] == 'b' || line[5] == 'g'))
125: /* files->nchan = 1 */;
126: else if (strcmp(line, "TYPE=dump") == 0)
127: { files->type = DUMP; sawtype = 1;
128: } else if (strcmp(line, "TYPE=runcode") == 0)
129: { files->type = RUNCODE; sawtype = 1;
130: } else if (strcmp(line, "TYPE=pico") == 0)
131: { files->type = PICO; sawtype = 1;
132: } else if (strcmp(line, "TYPE=binary") == 0)
133: { files->type = BINARY; sawtype = 1;
134: } else if (strncmp(line, "TYPE", 4) == 0)
135: return -1; /* unknown format */
136: }
137: }
138:
139: readf(fd, image)
140: struct pfile *image;
141: {
142: int w = image->r.corner.x - image->r.origin.x;
143: int h = image->r.corner.y - image->r.origin.y;
144:
145: if (w > 0 && h > 0 && (image->pixred != NULL || newf(image)))
146: switch (image->type) {
147: case BINARY:
148: case PICO:
149: return getfile(fd, image, w, h);
150: break;
151: case RUNCODE:
152: return -1;
153: case DUMP:
154: return gettd(fd, image, w, h);
155: break;
156: }
157: return 0;
158: }
159:
160: static getfile(fd, image, w, h)
161: struct pfile *image;
162: {
163: if (!getwindow(fd, image->pixred, w, h)) return 0;
164: if (image->nchan >= 2)
165: if (!getwindow(fd, image->pixgrn, w, h)) return 0;
166: if (image->nchan >= 3)
167: if (!getwindow(fd, image->pixblu, w, h)) return 0;
168: return 1;
169: }
170:
171: static getwindow(fd, dest, w, d)
172: unsigned char *dest;
173: {
174: int i; unsigned char *z = dest;
175:
176: for (i = 0; i < d; i++, z += w)
177: if (read(fd, z, w) != w)
178: return 0;
179: return 1;
180: }
181:
182: static gettd(fd, image, w, d)
183: struct pfile *image;
184: {
185: unsigned char *z = (unsigned char *) malloc(w * image->nchan);
186: unsigned char *r = image->pixred;
187: unsigned char *g = image->pixgrn;
188: unsigned char *b = image->pixblu;
189: int i, res=1, j = w*image->nchan;
190:
191: if (z == NULL)
192: return 0;
193: for (i = 0; i < d; i++)
194: { if (read(fd, z, j) != j || !unwind(z, r, g, b, w, image->nchan))
195: { res = 0;
196: break;
197: }
198: r += w; g += w; b += w;
199: }
200: free(z);
201: return res;
202: }
203:
204: static unwind(p, R, G, B, w, nchan)
205: unsigned char *p, *R, *G, *B;
206: {
207: register unsigned char *r = R, *g = G, *b = B;
208: register unsigned char *z = p;
209: register int i;
210:
211: switch (nchan) {
212: default: return 0; /* bad number of channels */
213: case 4: for(i=0; i<w; i++){ *r++=*z++; *g++=*z++; *b++=*z++; z++; } break;
214: case 3: for(i=0; i<w; i++){ *r++=*z++; *g++=*z++; *b++=*z++; } break;
215: case 2: for(i=0; i<w; i++){ *r++=*z++; *g++=*z++; } break;
216: case 1: for(i=0; i<w; i++){ *r++=*z++; } break;
217: }
218: return 1;
219: }
220:
221: putheader(fd, image)
222: struct pfile *image;
223: {
224: int w = image->r.corner.x - image->r.origin.x;
225: int d = image->r.corner.y - image->r.origin.y;
226:
227: if (image->nchan != 1 || w != d
228: || image->r.origin.x != 0
229: || image->r.origin.y != 0)
230: { if (image->type == PICO)
231: picoheader(fd, image);
232: else
233: tdheader(fd, image);
234: }
235: }
236:
237: putfile(fd, image)
238: struct pfile *image;
239: {
240: int w = image->r.corner.x - image->r.origin.x;
241: int d = image->r.corner.y - image->r.origin.y;
242:
243: if (image->nchan != 1 || w != d
244: || image->r.origin.x != 0
245: || image->r.origin.y != 0)
246: picoheader(fd, image);
247: if (!putwindow(fd, image->pixred, w, d))
248: return 0;
249: if (image->nchan >= 2)
250: { if (!putwindow(fd, image->pixgrn, w, d))
251: return 0;
252: }
253: if (image->nchan >= 3)
254: return putwindow(fd, image->pixblu, w, d);
255: return 1;
256: }
257:
258: static putwindow(fd, source, w, d)
259: unsigned char *source;
260: {
261: register unsigned char *z = source;
262: register int i;
263:
264: for (i = 0; i < d; i++, z += w)
265: if (write(fd, z, w) != w)
266: return 0;
267: return 1;
268: }
269:
270: static puttd(fd, image)
271: struct pfile *image;
272: {
273: unsigned char *r = image->pixred;
274: unsigned char *g = image->pixgrn;
275: unsigned char *b = image->pixblu;
276: int w = image->r.corner.x - image->r.origin.x;
277: int d = image->r.corner.y - image->r.origin.y;
278: int i, j, res=1;
279: unsigned char *zz, *tmp = (unsigned char *) malloc(w*image->nchan);
280:
281: if (tmp == NULL)
282: return 0;
283:
284: tdheader(fd, image);
285: for (i = 0; i < d; i++)
286: { switch (image->nchan) {
287: default: for (j = 0, zz = tmp; j < w; j++)
288: { *zz++ = *r++, *zz++ = *g++, *zz++ = *b++;
289: zz += image->nchan - 3;
290: }
291: break;
292: case 3: for (j = 0, zz = tmp; j < w; j++)
293: { *zz++ = *r++, *zz++ = *g++, *zz++ = *b++; }
294: break;
295: case 2: for (j = 0, zz = tmp; j < w; j++)
296: { *zz++ = *r++, *zz++ = *g++; }
297: break;
298: case 1: for (j = 0, zz = tmp; j < w; j++) *zz++ = *r++;
299: break;
300: }
301: if (write(fd, tmp, w*image->nchan) != w*image->nchan)
302: { res = 0;
303: break;
304: }
305: }
306: free(tmp);
307: return res;
308: }
309:
310: static tdheader(fd, image)
311: struct pfile *image;
312: { char line[128];
313: int n = image->nchan;
314: int a = image->r.origin.x;
315: int b = image->r.origin.y;
316: int c = image->r.corner.x;
317: int d = image->r.corner.y;
318:
319: sprintf(line, "TYPE=dump\nWINDOW=%d %d %d %d\nNCHAN=%d\n\n", a,b,c,d,n);
320: write(fd, line, strlen(line));
321: }
322:
323: picoheader(fd, image)
324: struct pfile *image;
325: { char line[128];
326: int n = image->nchan;
327: int a = image->r.origin.x;
328: int b = image->r.origin.y;
329: int c = image->r.corner.x;
330: int d = image->r.corner.y;
331:
332: sprintf(line, "TYPE=pico\nWINDOW=%d %d %d %d\nNCHAN=%d\n\n", a,b,c,d,n);
333: write(fd, line, strlen(line));
334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.