ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/meta2tga.c
Revision: 1.9
Committed: Wed May 13 00:30:13 2020 UTC (3 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R3, HEAD
Changes since 1.8: +12 -23 lines
Log Message:
Minor code cleanup

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: meta2tga.c,v 1.8 2019/11/18 22:12:32 greg Exp $";
3 #endif
4 /*
5 * Program to convert meta-files to Targa 8-bit color-mapped format
6 */
7
8 #include "copyright.h"
9
10 #include "rtprocess.h"
11 #include "meta.h"
12 #include "plot.h"
13 #include "rast.h"
14 #include "targa.h"
15
16 #define MAXALLOC 100000
17 #define DXSIZE 400 /* default x resolution */
18 #define DYSIZE 400 /* default y resolution */
19 #define XCOM "pexpand +vOCImsp -DP %s | psort +y"
20
21
22 char *progname;
23
24 SCANBLOCK outblock;
25
26 int dxsiz = DXSIZE, dysiz = DYSIZE;
27
28 int maxalloc = MAXALLOC;
29
30 int ydown = 0;
31
32 static char outname[64];
33 static char *outtack = NULL;
34
35 static FILE *fout;
36
37 static int lineno = 0;
38
39 static short condonly = FALSE,
40 conditioned = FALSE;
41
42 static int putthead(struct hdStruct *hp, char *ip, FILE *fp);
43
44
45
46 char *
47 findtack(char *s) /* find place to tack on suffix */
48 {
49 while (*s && *s != '.')
50 s++;
51 return(s);
52 }
53
54
55 int
56 main(
57 int argc,
58 char **argv
59 )
60 {
61 FILE *fp;
62 char comargs[200], command[300];
63
64 fout = stdout;
65 progname = *argv++;
66 argc--;
67
68 condonly = FALSE;
69 conditioned = FALSE;
70
71 while (argc && **argv == '-') {
72 switch (*(*argv+1)) {
73 case 'c':
74 condonly = TRUE;
75 break;
76 case 'r':
77 conditioned = TRUE;
78 break;
79 case 'm':
80 minwidth = atoi(*++argv);
81 argc--;
82 break;
83 case 'x':
84 dxsiz = atoi(*++argv);
85 argc--;
86 break;
87 case 'y':
88 dysiz = atoi(*++argv);
89 argc--;
90 break;
91 case 'o':
92 strcpy(outname, *++argv);
93 outtack = findtack(outname);
94 argc--;
95 break;
96 default:
97 error(WARNING, "unknown option");
98 break;
99 }
100 argv++;
101 argc--;
102 }
103
104 if (conditioned) {
105 if (argc)
106 while (argc) {
107 fp = efopen(*argv, "r");
108 plot(fp);
109 fclose(fp);
110 argv++;
111 argc--;
112 }
113 else
114 plot(stdin);
115 if (lineno)
116 nextpage();
117 } else {
118 comargs[0] = '\0';
119 while (argc) {
120 strcat(comargs, " ");
121 strcat(comargs, *argv);
122 argv++;
123 argc--;
124 }
125 sprintf(command, XCOM, comargs);
126 if (condonly)
127 return(system(command));
128 else {
129 if ((fp = popen(command, "r")) == NULL)
130 error(SYSTEM, "cannot execute input filter");
131 plot(fp);
132 pclose(fp);
133 if (lineno)
134 nextpage();
135 }
136 }
137
138 return(0);
139 }
140
141
142 void
143 thispage(void) /* rewind current file */
144 {
145 if (lineno)
146 error(USER, "cannot restart page in thispage");
147 }
148
149
150 void
151 initfile(void) /* initialize this file */
152 {
153 static const unsigned char cmap[24] = {0,0,0, 0,0,255, 0,188,0, 255,152,0,
154 0,200,200, 255,0,255, 179,179,0, 255,255,255};
155 static int filenum = 0;
156 struct hdStruct thead;
157 int i;
158
159 if (outtack != NULL) {
160 sprintf(outtack, "%d.tga", ++filenum);
161 fout = efopen(outname, "w");
162 }
163 if (fout == NULL)
164 error(USER, "no output file");
165 thead.mapType = CM_HASMAP;
166 thead.dataType = IM_CCMAP;
167 thead.mapOrig = 0;
168 thead.mapLength = 256;
169 thead.CMapBits = 24;
170 thead.XOffset = 0;
171 thead.YOffset = 0;
172 thead.x = dxsiz;
173 thead.y = dysiz;
174 thead.dataBits = 8;
175 thead.imType = 0;
176 putthead(&thead, NULL, fout);
177 for (i = 0; i < 8*3; i++)
178 putc(cmap[i], fout);
179 while (i++ < 256*3)
180 putc(0, fout);
181 }
182
183
184 void
185 nextpage(void) /* advance to next page */
186 {
187
188 if (lineno == 0)
189 return;
190 if (fout != NULL) {
191 while (lineno < dysiz) {
192 nextblock();
193 outputblock();
194 }
195 fclose(fout);
196 fout = NULL;
197 }
198 lineno = 0;
199
200 }
201
202
203 #define MINRUN 4
204
205 void
206 printblock(void) /* output scanline block to file */
207 {
208 int i, c2;
209 unsigned char *scanline;
210 int j, beg, cnt = 0;
211
212 if (lineno == 0)
213 initfile();
214 for (i = outblock.ybot; i <= outblock.ytop && i < dysiz; i++) {
215 scanline = outblock.cols[i-outblock.ybot];
216 for (j = outblock.xleft; j <= outblock.xright; j += cnt) {
217 for (beg = j; beg <= outblock.xright; beg += cnt) {
218 for (cnt = 1; cnt < 128 && beg+cnt <= outblock.xright &&
219 scanline[beg+cnt] == scanline[beg]; cnt++)
220 ;
221 if (cnt >= MINRUN)
222 break; /* long enough */
223 }
224 while (j < beg) { /* write out non-run */
225 if ((c2 = beg-j) > 128) c2 = 128;
226 putc(c2-1, fout);
227 while (c2--)
228 putc(scanline[j++], fout);
229 }
230 if (cnt >= MINRUN) { /* write out run */
231 putc(127+cnt, fout);
232 putc(scanline[beg], fout);
233 } else
234 cnt = 0;
235 }
236 lineno++;
237 }
238
239 }
240
241
242 void
243 putint2( /* put a 2-byte positive integer */
244 int i,
245 FILE *fp
246 )
247 {
248 putc(i&0xff, fp);
249 putc(i>>8&0xff, fp);
250 }
251
252
253 int
254 putthead( /* write header to output */
255 struct hdStruct *hp,
256 char *ip,
257 FILE *fp
258 )
259 {
260 if (ip != NULL)
261 putc(strlen(ip), fp);
262 else
263 putc(0, fp);
264 putc(hp->mapType, fp);
265 putc(hp->dataType, fp);
266 putint2(hp->mapOrig, fp);
267 putint2(hp->mapLength, fp);
268 putc(hp->CMapBits, fp);
269 putint2(hp->XOffset, fp);
270 putint2(hp->YOffset, fp);
271 putint2(hp->x, fp);
272 putint2(hp->y, fp);
273 putc(hp->dataBits, fp);
274 putc(hp->imType, fp);
275
276 if (ip != NULL)
277 fputs(ip, fp);
278
279 return(ferror(fp) ? -1 : 0);
280 }