ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pict.c
Revision: 2.12
Committed: Fri Jul 19 17:37:56 2019 UTC (4 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.11: +2 -4 lines
Log Message:
Moved declarations and definitions for header.c from resolu.h to rtio.h

File Contents

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