ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pict.c
Revision: 2.11
Committed: Tue Mar 20 18:45:04 2018 UTC (6 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 2.10: +2 -1 lines
Log Message:
Added missing rtio.h include to redefine getc, putc, etc.

File Contents

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