ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pict.c
Revision: 2.10
Committed: Sun Mar 28 20:33:14 2004 UTC (20 years ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.9: +70 -31 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: ra_pict.c,v 2.9 2003/06/05 19:29:34 schorsch Exp $";
3 #endif
4 /* Convert an Radiance image to APPLE pict format.
5 *
6 * Orginally Iris to PICT by Paul Haeberli - 1990
7 * Hacked into Rad to PICT by Russell Street 1990
8 *
9 * History:
10 * V 1 -- Does basic conversion
11 * V 1.1 (2/11/91) -- Added options for Gamma
12 * -- verbose option
13 * -- man page
14 * -- better about allocating buffers
15 * V 1.2 (19/11/91) -- Revised to handle opening "The Radiance Way"
16 * -- Added exposure level adjustment
17 */
18
19 #include <stdio.h>
20 #include <math.h>
21 #include <time.h>
22
23 #include "platform.h"
24 #include "pict.h"
25 #include "color.h"
26 #include "resolu.h"
27
28 int outbytes; /* This had better be 32 bits! */
29 char *progname;
30 int verbose = 0;
31 float gamcor = 2.0;
32 int bradj = 0;
33
34 static void putrect(int xorg, int yorg, int xsize, int ysize);
35 static void putfprect(int xorg, int yorg, int xsize, int ysize);
36 static void putalong(long l);
37 static void putashort(short s);
38 static void putbyte(int b);
39 static void putbytes(unsigned char *buf, int n );
40 static void putpict(int xsize, int ysize);
41 static void getrow(FILE *in, char *cbuf, int xsize);
42 static int packbits(unsigned char *ibits, unsigned char *pbits, int nbits);
43 static void usage(void);
44
45
46 /* First some utility routines */
47 static void
48 putrect(
49 int xorg,
50 int yorg,
51 int xsize,
52 int ysize
53 )
54 {
55 putashort(yorg);
56 putashort(xorg);
57 putashort(ysize);
58 putashort(xsize);
59 }
60
61 static void
62 putfprect(
63 int xorg,
64 int yorg,
65 int xsize,
66 int ysize
67 )
68 {
69 putalong(yorg<<16);
70 putalong(xorg<<16);
71 putalong(ysize<<16);
72 putalong(xsize<<16);
73 }
74
75 static void
76 putalong(
77 long l
78 )
79 {
80 putbyte((l>>24)&0xff);
81 putbyte((l>>16)&0xff);
82 putbyte((l>>8)&0xff);
83 putbyte((l>>0)&0xff);
84 }
85
86 static void
87 putashort(
88 short s
89 )
90 {
91 putbyte((s>>8)&0xff);
92 putbyte((s>>0)&0xff);
93 }
94
95 static void
96 putbyte(
97 int b
98 )
99 {
100 if (putc(b,stdout) == EOF && ferror(stdout)) {
101 fprintf(stderr,"%s: error on write\n", progname);
102 exit(1);
103 }
104 outbytes++;
105 }
106
107 static void
108 putbytes(
109 unsigned char *buf,
110 int n
111 )
112 {
113 if(!fwrite(buf,n,1,stdout)) {
114 fprintf(stderr,"%s: error on write\n", progname);
115 exit(1);
116 }
117 outbytes+=n;
118 }
119
120 int
121 main(
122 int argc,
123 char **argv
124 )
125 {
126 int xsize, ysize;
127 int i, picsize;
128 int ssizepos, lsizepos;
129 SET_DEFAULT_BINARY();
130 SET_FILE_BINARY(stdin);
131 SET_FILE_BINARY(stdout);
132 progname = argv[0];
133
134 for (i = 1; i < argc ; i++)
135 if (argv[i][0] == '-')
136 switch (argv[i][1]) {
137 case 'g': gamcor = atof(argv[++i]);
138 break;
139
140 case 'e': if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
141 usage();
142 else
143 bradj = atoi(argv[++i]);
144 break;
145
146 case 'v': ;
147 verbose = 1;
148 break;
149
150 case 'r': fprintf(stderr, "Sorry. Get a Macintosh :-)\n");
151 exit(1);
152
153 case '-': i++;
154 goto outofparse;
155 break; /* NOTREACHED */
156
157 default:
158 usage();
159 break;
160 }
161 else
162 break;
163
164 outofparse:
165
166 if (i < argc - 2)
167 usage();
168
169 if (i <= argc - 1 && freopen(argv[i], "r", stdin) == NULL) {
170 fprintf(stderr, "%s: can not open input \"%s\"\n",
171 progname, argv[i]);
172 exit(1);
173 }
174
175 if (i <= argc - 2 && freopen(argv[i+1], "w", stdout) == NULL) {
176 fprintf(stderr, "%s: can not open input \"%s\"\n",
177 progname, argv[i+1]);
178 exit(1);
179 }
180
181 #ifdef DEBUG
182 fprintf(stderr, "Input file: %s\n", i <= argc - 1 ? argv[i] : "stdin");
183 fprintf(stderr, "Outut file: %s\n", i <= argc - 2 ? argv[i+1] : "stdout" );
184 fprintf(stderr, "Gamma: %f\n", gamcor);
185 fprintf(stderr, "Brightness adjust: %d\n", bradj);
186 fprintf(stderr, "Verbose: %s\n", verbose ? "on" : "off");
187 #endif
188
189
190 /* OK. Now we read the size of the Radiance picture */
191 if (checkheader(stdin, COLRFMT, NULL) < 0 ||
192 fgetresolu(&xsize, &ysize, stdin) < 0 /* != (YMAJOR|YDECR) */ ) {
193 fprintf(stderr, "%s: not a radiance picture\n", progname);
194 exit(1);
195 }
196
197 /* Set the gamma correction */
198
199 setcolrgam(gamcor);
200
201 for(i=0; i<HEADER_SIZE; i++)
202 putbyte(0);
203
204 ssizepos = outbytes;
205 putashort(0); /* low 16 bits of file size less HEADER_SIZE */
206 putrect(0,0,xsize,ysize); /* bounding box of picture */
207 putashort(PICT_picVersion);
208 putashort(0x02ff); /* version 2 pict */
209 putashort(PICT_reservedHeader); /* reserved header opcode */
210
211 lsizepos = outbytes;
212 putalong(0); /* full size of the file */
213 putfprect(0,0,xsize,ysize); /* fixed point bounding box of picture */
214 putalong(0); /* reserved */
215
216 putashort(PICT_clipRgn); /* the clip region */
217 putashort(10);
218 putrect(0,0,xsize,ysize);
219
220 if (verbose)
221 fprintf(stderr, "%s: The picture is %d by %d, with a gamma of %f\n",
222 progname, xsize, ysize, gamcor);
223
224
225 putpict(xsize, ysize); /* Here is where all the work is done */
226
227 putashort(PICT_EndOfPicture); /* end of pict */
228
229 picsize = outbytes-HEADER_SIZE;
230 fseek(stdout,ssizepos,0);
231 putashort(picsize&0xffff);
232 fseek(stdout,lsizepos,0);
233 putalong(picsize);
234
235 fclose(stdout);
236 fclose(stdin);
237
238 exit(0);
239 return 0; /* lint fodder */
240 }
241
242 static void
243 putpict(
244 int xsize,
245 int ysize
246 )
247 {
248 int y;
249 int nbytes, rowbytes;
250 char *cbuf, *pbuf;
251
252 cbuf = (char *)malloc(4 * xsize);
253
254 if (cbuf == NULL) {
255 fprintf(stderr, "%s: not enough memory\n", progname);
256 exit(1);
257 }
258
259 pbuf = (char *)malloc(4 * xsize);
260
261 if (pbuf == NULL) {
262 fprintf(stderr, "%s: not enough memory\n", progname);
263 exit(1);
264 }
265
266 putashort(PICT_Pack32BitsRect); /* 32 bit rgb */
267 rowbytes = 4*xsize;
268 putalong(0x000000ff); /* base address */
269
270
271 if(rowbytes&1)
272 rowbytes++;
273 putashort(rowbytes|0x8000); /* rowbytes */
274 putrect(0,0,xsize,ysize); /* bounds */
275 putashort(0); /* version */
276
277 putashort(4); /* packtype */
278 putalong(0); /* packsize */
279 putalong(72<<16); /* hres */
280 putalong(72<<16); /* vres */
281
282 putashort(16); /* pixeltype */
283 putashort(32); /* pixelsize */
284 putashort(3); /* cmpcount */
285
286
287 putashort(8); /* cmpsize */
288 putalong(0); /* planebytes */
289 putalong(0); /* pmtable */
290 putalong(0); /* pmreserved */
291
292
293 putrect(0,0,xsize,ysize); /* scr rect */
294 putrect(0,0,xsize,ysize); /* dest rect */
295
296
297 putashort(0x40); /* transfer mode */
298
299 for(y=0; y<ysize; y++) {
300 getrow(stdin, cbuf, xsize);
301
302 nbytes = packbits(cbuf,pbuf,24*xsize);
303 if(rowbytes>250)
304 putashort(nbytes);
305 else
306 putbyte(nbytes);
307 putbytes(pbuf,nbytes);
308 }
309
310 if(outbytes&1)
311 putbyte(0);
312
313 free(cbuf);
314 free(pbuf);
315 }
316
317 static void
318 getrow(
319 FILE *in,
320 char *cbuf,
321 int xsize
322 )
323 {
324 extern char *tempbuffer(); /* defined in color.c */
325 COLR *scanin = NULL;
326 int x;
327
328 if ((scanin = (COLR *)tempbuffer(xsize*sizeof(COLR))) == NULL) {
329 fprintf(stderr, "%s: not enough memory\n", progname);
330 exit(1);
331 }
332
333 if (freadcolrs(scanin, xsize, in) < 0) {
334 fprintf(stderr, "%s: read error\n", progname);
335 exit(1);
336 }
337
338 if (bradj) /* Adjust exposure level */
339 shiftcolrs(scanin, xsize, bradj);
340
341
342 colrs_gambs(scanin, xsize); /* Gamma correct it */
343
344 for (x = 0; x < xsize; x++) {
345 cbuf[x] = scanin[x][RED];
346 cbuf[xsize + x] = scanin[x][GRN];
347 cbuf[2*xsize + x] = scanin[x][BLU];
348 }
349
350 }
351
352
353 static int
354 packbits(
355 unsigned char *ibits,
356 unsigned char *pbits,
357 int nbits
358 )
359 {
360 unsigned char *sptr;
361 unsigned char *ibitsend;
362 unsigned char *optr = pbits;
363 int nbytes, todo, cc, count;
364
365 nbytes = ((nbits-1)/8)+1;
366 ibitsend = ibits+nbytes;
367 while(ibits<ibitsend) {
368 sptr = ibits;
369 ibits += 2;
370 while((ibits<ibitsend)&&((ibits[-2]!=ibits[-1])||(ibits[-1]!=ibits[0])))
371 ibits++;
372 if(ibits != ibitsend) {
373 ibits -= 2;
374 }
375 count = ibits-sptr;
376 while(count) {
377 todo = count>127 ? 127:count;
378 count -= todo;
379 *optr++ = todo-1;
380 while(todo--)
381 *optr++ = *sptr++;
382 }
383 if(ibits == ibitsend)
384 break;
385 sptr = ibits;
386 cc = *ibits++;
387 while( (ibits<ibitsend) && (*ibits == cc) )
388 ibits++;
389 count = ibits-sptr;
390 while(count) {
391 todo = count>128 ? 128:count;
392 count -= todo;
393 *optr++ = 257-todo;
394 *optr++ = cc;
395 }
396 }
397 return optr-pbits;
398 }
399
400 static void
401 usage(void)
402 {
403 fprintf(stderr, "Usage: %s [-v] [-g gamma] [infile [outfile]]\n",
404 progname);
405 exit(2);
406 }