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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.10 static const char RCSid[] = "$Id: ra_pict.c,v 2.9 2003/06/05 19:29:34 schorsch Exp $";
3 greg 1.1 #endif
4 greg 2.5 /* Convert an Radiance image to APPLE pict format.
5 greg 2.2 *
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 greg 1.1 #include <stdio.h>
20 greg 2.6 #include <math.h>
21 greg 2.8 #include <time.h>
22 greg 2.2
23 schorsch 2.9 #include "platform.h"
24 greg 1.1 #include "pict.h"
25     #include "color.h"
26 greg 1.4 #include "resolu.h"
27 greg 2.3
28 greg 2.2 int outbytes; /* This had better be 32 bits! */
29     char *progname;
30     int verbose = 0;
31 greg 2.7 float gamcor = 2.0;
32 greg 2.2 int bradj = 0;
33 greg 1.1
34 schorsch 2.10 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 greg 2.2 /* First some utility routines */
47 schorsch 2.10 static void
48     putrect(
49     int xorg,
50     int yorg,
51     int xsize,
52     int ysize
53     )
54 greg 1.1 {
55     putashort(yorg);
56     putashort(xorg);
57     putashort(ysize);
58     putashort(xsize);
59     }
60    
61 schorsch 2.10 static void
62     putfprect(
63     int xorg,
64     int yorg,
65     int xsize,
66     int ysize
67     )
68 greg 1.1 {
69     putalong(yorg<<16);
70     putalong(xorg<<16);
71     putalong(ysize<<16);
72     putalong(xsize<<16);
73     }
74    
75 schorsch 2.10 static void
76     putalong(
77     long l
78     )
79 greg 1.1 {
80     putbyte((l>>24)&0xff);
81     putbyte((l>>16)&0xff);
82     putbyte((l>>8)&0xff);
83     putbyte((l>>0)&0xff);
84     }
85    
86 schorsch 2.10 static void
87     putashort(
88     short s
89     )
90 greg 1.1 {
91     putbyte((s>>8)&0xff);
92     putbyte((s>>0)&0xff);
93     }
94    
95 schorsch 2.10 static void
96     putbyte(
97     int b
98     )
99 greg 1.1 {
100 greg 2.2 if (putc(b,stdout) == EOF && ferror(stdout)) {
101     fprintf(stderr,"%s: error on write\n", progname);
102 greg 1.1 exit(1);
103     }
104     outbytes++;
105     }
106    
107 schorsch 2.10 static void
108     putbytes(
109     unsigned char *buf,
110     int n
111     )
112 greg 1.1 {
113 greg 2.2 if(!fwrite(buf,n,1,stdout)) {
114     fprintf(stderr,"%s: error on write\n", progname);
115 greg 1.1 exit(1);
116     }
117     outbytes+=n;
118     }
119    
120 schorsch 2.10 int
121     main(
122     int argc,
123     char **argv
124     )
125 greg 1.1 {
126     int xsize, ysize;
127     int i, picsize;
128     int ssizepos, lsizepos;
129 schorsch 2.9 SET_DEFAULT_BINARY();
130     SET_FILE_BINARY(stdin);
131     SET_FILE_BINARY(stdout);
132 greg 2.2 progname = argv[0];
133 greg 1.1
134 greg 2.2 for (i = 1; i < argc ; i++)
135 greg 2.5 if (argv[i][0] == '-')
136 greg 2.2 switch (argv[i][1]) {
137 greg 2.7 case 'g': gamcor = atof(argv[++i]);
138 greg 2.2 break;
139 greg 1.1
140 greg 2.2 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 schorsch 2.10 default:
158     usage();
159 greg 2.2 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 greg 1.1 exit(1);
173     }
174    
175 greg 2.2 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 greg 1.1 exit(1);
179     }
180 greg 2.2
181     #ifdef DEBUG
182     fprintf(stderr, "Input file: %s\n", i <= argc - 1 ? argv[i] : "stdin");
183 greg 2.5 fprintf(stderr, "Outut file: %s\n", i <= argc - 2 ? argv[i+1] : "stdout" );
184 greg 2.7 fprintf(stderr, "Gamma: %f\n", gamcor);
185 greg 2.2 fprintf(stderr, "Brightness adjust: %d\n", bradj);
186 greg 2.5 fprintf(stderr, "Verbose: %s\n", verbose ? "on" : "off");
187 greg 2.2 #endif
188 greg 1.1
189 greg 2.2
190 greg 2.5 /* OK. Now we read the size of the Radiance picture */
191 greg 2.2 if (checkheader(stdin, COLRFMT, NULL) < 0 ||
192 greg 2.5 fgetresolu(&xsize, &ysize, stdin) < 0 /* != (YMAJOR|YDECR) */ ) {
193     fprintf(stderr, "%s: not a radiance picture\n", progname);
194     exit(1);
195 greg 2.2 }
196 greg 1.1
197 greg 2.2 /* Set the gamma correction */
198 greg 1.1
199 greg 2.7 setcolrgam(gamcor);
200 greg 2.2
201 greg 1.1 for(i=0; i<HEADER_SIZE; i++)
202     putbyte(0);
203 greg 2.2
204 greg 1.1 ssizepos = outbytes;
205 greg 2.5 putashort(0); /* low 16 bits of file size less HEADER_SIZE */
206 greg 1.1 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 greg 2.5 putalong(0); /* full size of the file */
213     putfprect(0,0,xsize,ysize); /* fixed point bounding box of picture */
214     putalong(0); /* reserved */
215 greg 1.1
216 greg 2.5 putashort(PICT_clipRgn); /* the clip region */
217 greg 1.1 putashort(10);
218     putrect(0,0,xsize,ysize);
219    
220 greg 2.2 if (verbose)
221     fprintf(stderr, "%s: The picture is %d by %d, with a gamma of %f\n",
222 greg 2.7 progname, xsize, ysize, gamcor);
223 greg 1.1
224 greg 2.2
225     putpict(xsize, ysize); /* Here is where all the work is done */
226    
227 greg 1.1 putashort(PICT_EndOfPicture); /* end of pict */
228    
229     picsize = outbytes-HEADER_SIZE;
230 greg 2.2 fseek(stdout,ssizepos,0);
231 greg 1.1 putashort(picsize&0xffff);
232 greg 2.2 fseek(stdout,lsizepos,0);
233 greg 1.1 putalong(picsize);
234    
235 greg 2.2 fclose(stdout);
236     fclose(stdin);
237    
238 greg 1.1 exit(0);
239 greg 2.2 return 0; /* lint fodder */
240 greg 1.1 }
241    
242 schorsch 2.10 static void
243     putpict(
244     int xsize,
245     int ysize
246     )
247 greg 1.1 {
248 greg 2.2 int y;
249     int nbytes, rowbytes;
250     char *cbuf, *pbuf;
251 greg 1.1
252 greg 2.8 cbuf = (char *)malloc(4 * xsize);
253 greg 2.2
254     if (cbuf == NULL) {
255     fprintf(stderr, "%s: not enough memory\n", progname);
256     exit(1);
257     }
258    
259 greg 2.8 pbuf = (char *)malloc(4 * xsize);
260 greg 2.2
261     if (pbuf == NULL) {
262     fprintf(stderr, "%s: not enough memory\n", progname);
263     exit(1);
264     }
265    
266 greg 1.1 putashort(PICT_Pack32BitsRect); /* 32 bit rgb */
267     rowbytes = 4*xsize;
268     putalong(0x000000ff); /* base address */
269    
270 greg 2.2
271 greg 1.1 if(rowbytes&1)
272     rowbytes++;
273 greg 2.5 putashort(rowbytes|0x8000); /* rowbytes */
274 greg 1.1 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 greg 2.2
287 greg 1.1 putashort(8); /* cmpsize */
288     putalong(0); /* planebytes */
289     putalong(0); /* pmtable */
290     putalong(0); /* pmreserved */
291    
292 greg 2.2
293 greg 1.1 putrect(0,0,xsize,ysize); /* scr rect */
294     putrect(0,0,xsize,ysize); /* dest rect */
295    
296 greg 2.2
297 greg 1.1 putashort(0x40); /* transfer mode */
298 greg 2.2
299 greg 1.1 for(y=0; y<ysize; y++) {
300 greg 2.2 getrow(stdin, cbuf, xsize);
301 greg 1.1
302     nbytes = packbits(cbuf,pbuf,24*xsize);
303     if(rowbytes>250)
304     putashort(nbytes);
305     else
306     putbyte(nbytes);
307     putbytes(pbuf,nbytes);
308 greg 2.2 }
309 greg 1.1
310     if(outbytes&1)
311     putbyte(0);
312 greg 2.2
313     free(cbuf);
314     free(pbuf);
315 greg 1.1 }
316    
317 schorsch 2.10 static void
318     getrow(
319     FILE *in,
320     char *cbuf,
321     int xsize
322     )
323 greg 1.1 {
324 greg 2.5 extern char *tempbuffer(); /* defined in color.c */
325 greg 2.2 COLR *scanin = NULL;
326 greg 1.1 int x;
327    
328 greg 2.2 if ((scanin = (COLR *)tempbuffer(xsize*sizeof(COLR))) == NULL) {
329     fprintf(stderr, "%s: not enough memory\n", progname);
330     exit(1);
331 greg 1.1 }
332    
333     if (freadcolrs(scanin, xsize, in) < 0) {
334 greg 2.5 fprintf(stderr, "%s: read error\n", progname);
335     exit(1);
336     }
337 greg 1.1
338 greg 2.2 if (bradj) /* Adjust exposure level */
339     shiftcolrs(scanin, xsize, bradj);
340    
341    
342     colrs_gambs(scanin, xsize); /* Gamma correct it */
343 greg 1.1
344     for (x = 0; x < xsize; x++) {
345 greg 2.2 cbuf[x] = scanin[x][RED];
346     cbuf[xsize + x] = scanin[x][GRN];
347     cbuf[2*xsize + x] = scanin[x][BLU];
348     }
349    
350 greg 1.1 }
351    
352 greg 2.2
353 schorsch 2.10 static int
354     packbits(
355     unsigned char *ibits,
356     unsigned char *pbits,
357     int nbits
358     )
359 greg 1.1 {
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 greg 2.2 while(ibits<ibitsend) {
368 greg 1.1 sptr = ibits;
369     ibits += 2;
370     while((ibits<ibitsend)&&((ibits[-2]!=ibits[-1])||(ibits[-1]!=ibits[0])))
371     ibits++;
372 greg 2.5 if(ibits != ibitsend) {
373 greg 1.1 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 greg 2.2 }
399    
400 schorsch 2.10 static void
401     usage(void)
402 greg 2.2 {
403     fprintf(stderr, "Usage: %s [-v] [-g gamma] [infile [outfile]]\n",
404     progname);
405     exit(2);
406 greg 1.1 }