|
|
1.1 root 1: /*
2: * $Source: /orpheus/u1/X11/NRFPT/puzzle/RCS/pmap.c,v $
3: * $Header: pmap.c,v 1.1 87/09/08 17:26:40 swick Exp $
4: */
5:
6: #ifndef lint
7: static char *rcsid_pmap_c = "$Header: pmap.c,v 1.1 87/09/08 17:26:40 swick Exp $";
8: #endif lint
9:
10: /*
11: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12: ;
13: ; File: pmap.c
14: ; SCCS: %A% %G% %U%
15: ; Description: Pixel Map I/O in C
16: ; Author: Jack Palevich, VGD, ITL, DCC, HP Labs
17: ; Created: 29-Jan-86
18: ; Modified: 7-Jul-86 12:31:59 (Jack Palevich)
19: ; Language: Text
20: ; Package: PSL
21: ; Status: Experimental (Do Not Distribute)
22: ;
23: ; (c) Copyright 1986, Hewlett-Packard Company, all rights reserved.
24: ;
25: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26: */
27:
28: #include <stdio.h>
29: #include <string.h>
30: #include "pmap.h"
31:
32: /*
33: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34: % File i/o for pixel maps
35: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36: %
37: % "PMAP" file format is an ad-hoc standard developed for storing pixel maps on
38: % secondary storage and for transfering pixel maps between C, Pascal programs
39: % and the Prism environment.
40: %
41: % A "PMAP" file consists of a 512-byte header block followed by one or more
42: % 512-byte blocks of data.
43: %
44: % The header block consists of the following information:
45: %
46: % byte(s) Information
47: % ======= ===========
48: % 0..1 The number of pixels in the X direction (1..65535)
49: % 2..3 The number of pixels in the Y direction (1..65535)
50: % 4..7 The number of bytes in the whole data section (1..2^32-1)
51: % 8..9 The number of bits per pixel (1..32)
52: % 10..11 The type of pixel (0..6) where:
53: % 0 is undefined
54: % 1 is BMM, 1 bit/pixel
55: % 2 is GSM, 4 bits/pixel
56: % 3 is GSM', 8 bits/pixel
57: % 4 is BMC, 8 bits/pixel
58: % 5 is GSC, 32 bits/pixel
59: % 6 is GSC', 32 bits/pixel (Gator-c display)
60: % 7 is 2 bits per pixel
61: % 8 is YF, 16 bits/pixel, stored in files as two planes, Y, then F.
62: %
63: % 12..13 The number of bytes per row of pixels; the stride (1..65535)
64: % 14..15 The version of encoding used (currently 0) (0..65535)
65: % 16..19 The ASCII letters PMAP, as a signature. (Check this first!)
66: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67: */
68:
69: unsigned char pixel_map_bpp[] = { 0, 1, 4, 8, 8, 32, 32, 2, 16};
70:
71: /*
72: * FILE *pixel_map_open(pixel_map, file_name)
73: *
74: * Determine the dimensions of the pixel map, and fill in the w, h, and type
75: * parts of the pixel map structure
76: * returns a file descripter if no error, else returns NULL
77: * If the file exists, but is not a PMAP file, then we return NULL.
78: */
79:
80: FILE *pixel_map_open(pm, file_name)
81: pixel_map *pm;
82: char *file_name;
83: {
84: FILE *fp;
85: unsigned char buf[512];
86:
87: if ((fp = fopen(file_name,"r")) == NULL)
88: return(fp);
89:
90: if (fread(buf, 1, 512, fp) != 512 || /* can we read it? */
91: pixel_map_parse_header(pm, buf) == 0) {
92: fclose(fp);
93: return(NULL);
94: }
95: return(fp);
96: }
97:
98: /* isphead.h - declaration for HP-ISP image file header */
99:
100: /* Ho John Lee, HP Labs 10-6-84 */
101:
102: #define SHORT 2
103: #define LONG 4
104:
105: typedef struct
106: {
107: short filetype; /* mark what kind of file we have */
108: short bpp; /* bits per pixel, 1, 4, 8, 24, 32 */
109: short rows; /* up to 1024 */
110: short cols; /* up to 1024 */
111: short vectortype; /* so far, 0 = rectangular blocks */
112: short vectorsize; /* so far, 16 for 4x4 square blocks */
113: long nvectors; /* up to 65536 */
114: short brows; /* number of block rows */
115: short bcols; /* number of block cols */
116: short vrows; /* number of vector rows */
117: short vcols; /* number of vector cols */
118: short packed; /* format of data */
119: char reserved[128 - 11*SHORT - LONG];
120: /* pad variable space to 128 bytes */
121: char user[128]; /* user application space */
122: char comment[256]; /* rest of 1st block for comments */
123: } ISP_file_header;
124:
125: #define FHDRSIZE sizeof(ISP_file_header)
126:
127: /*
128: * int pixel_map_parse_header(pixel_map, header)
129: *
130: * Determine the dimensions of the pixel map, and fill in the w, h, and type
131: * parts of the pixel map structure.
132: * (header is a 512 byte buffer).
133: * Reads packed ISP and Glamor PMAP formats.
134: * returns 1 if no problem.
135: * If the data is not a PMAP or ISP header, we return 0.
136: *
137: * BUGS: buffer must be word aligned, or else ISP files will generate bus errors.
138: */
139:
140: int pixel_map_parse_header(pm, buf)
141: pixel_map *pm;
142: unsigned char *buf;
143: {
144: ISP_file_header *isp;
145:
146: if (strncmp((char *) buf+16, "PMAP", 4) == 0) { /* check if it's a PMAP file */
147: /* it is a PMAP file. */
148: if (buf[14] != 0 || buf[15] != 0) /* check encoding = 0 */
149: return(0);
150:
151: /* get pixel data */
152: pm->w = (buf[0] << 8) | buf[1];
153: pm->h = (buf[2] << 8) | buf[3];
154: pm->type = (buf[10] << 8) | buf[11];
155: pm->stride = (buf[12] << 8) | buf[13];
156: pm->bpp = (buf[8] << 8) | buf[9];
157: return(1);
158: }
159:
160: /* check if it's an ISP file */
161: isp = (ISP_file_header *) buf;
162:
163: if (isp->filetype == 0 &&
164: (isp->bpp >= 8 ||
165: isp->packed == 1)) { /* it MIGHT be an ISP file.... */
166: pm->w = isp->cols;
167: pm->h = isp->rows;
168: pm->bpp = isp->bpp;
169: switch(pm->bpp) {
170: case 1: pm->type = 1; break;
171: case 2: pm->type = 7; break;
172: case 4: pm->type = 2; break;
173: case 8: pm->type = 3; break;
174: case 32: pm->type = 5; break;
175: default:
176: /* not an ISP file */
177:
178: return(0);
179: break;
180: }
181: pm->stride = (pm->w * pm->bpp) >> 3;
182: return(1);
183: } /* if */
184: return(0);
185: }
186:
187: int pixel_map_read(pm, fp)
188: pixel_map *pm;
189: FILE *fp;
190: {
191: return pm-> h == fread(pm->pixels, pm->stride, pm->h, fp);
192: }
193:
194: /*
195: * pixel_map_write -- returns 1 if successful, else returns 0
196: */
197:
198: int pixel_map_write(pm, fp)
199: pixel_map *pm;
200: FILE *fp;
201: {
202: char block[512];
203: short unsigned int h, w, stride, type, *block_2b;
204: unsigned int size, *block_4b;
205:
206: block_2b = (short unsigned int *) block;
207: block_4b = (unsigned int *) block;
208:
209: w = pm->w;
210: h = pm->h;
211: stride = pm->stride;
212: type = pm->type;
213: size=h*stride;
214:
215: block_2b[0] = w;
216: block_2b[1] = h;
217: block_4b[1] = size;
218:
219: block_2b[4] = pixel_map_bpp[type];
220: block_2b[5] = type;
221:
222: block_2b[6] = stride;
223: block_2b[7] = 0;
224: block[16] = 'P';
225: block[17] = 'M';
226: block[18] = 'A';
227: block[19] = 'P';
228:
229: return (512 == fwrite(block, 1, 512, fp)
230: && size == fwrite(pm->pixels, 1, size, fp));
231: }
232:
233: int pixel_map_close(fp)
234: FILE *fp;
235: {
236: return fclose(fp);
237: }
238:
239: char *pixel_map_alloc(pm)
240: pixel_map *pm;
241: {
242: char *calloc();
243: if(pm->stride == 0)
244: pm->stride =
245: (31 + pm->w * pixel_map_bpp[pm->type]) >> 3;
246: return (pm->pixels = calloc(pm->h, pm->stride));
247: }
248:
249: int pixel_map_free(pm)
250: pixel_map *pm;
251: {
252: free(pm->pixels);
253: free(pm);
254: }
255:
256: pixel_map *new_pixel_map()
257: {
258: pixel_map *joe;
259: joe = (pixel_map *) calloc(1, sizeof(pixel_map));
260: return(joe);
261: }
262:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.