1 /****************************************************************
2 * uoutput.c
3 *
4 * Copyright (C) 1995-2002 Klaus Ehrenfried
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 *************************************************************************/
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26
27 #include "upro.h"
28 #include <stdlib.h>
29
30 #define MAX_LEN 512
31
32 static char *command;
33 static int max_cmd_len = -1;
34
35 /****************************************************************
36 * piper_open
37 ****************************************************************/
38
xx_close(FILE * fp,char * filter)39 static void xx_close(FILE *fp, char *filter)
40 {
41 if (filter == NULL)
42 {
43 fclose(fp);
44 }
45 else
46 {
47 pclose(fp);
48 }
49 }
50
51 /****************************************************************
52 * piper_open
53 ****************************************************************/
54
xx_open(char * file_name,char * filter)55 static FILE *xx_open(char *file_name, char *filter)
56 {
57 FILE *fopen(), *fp;
58 int cmd_len;
59
60 if (filter == NULL)
61 {
62 if ((fp=fopen(file_name, "wb")) == NULL)
63 {
64 fprintf(stderr," Error opening file '%s'\n",file_name);
65 return(NULL);
66 }
67 return(fp);
68 }
69
70 cmd_len = strlen(filter);
71 if (cmd_len == 0)
72 {
73 fprintf(stderr,"No filter specified\n");
74 return(NULL);
75 }
76 cmd_len += strlen(file_name);
77 cmd_len += 10; /* for extra chars */
78
79 if (cmd_len >= max_cmd_len)
80 {
81 cmd_len += 10;
82 if (max_cmd_len > 0) free(command);
83 if ((command = (char *) malloc(cmd_len)) == NULL)
84 {
85 fprintf(stderr,"Can't allocate %d bytes\n",cmd_len);
86 return(NULL);
87 }
88 max_cmd_len = cmd_len;
89 }
90
91 sprintf(command,"%s > %s",filter,file_name);
92 fprintf(stdout," .... %s\n",command);
93
94 if ((fp = popen(command, "w")) == NULL)
95 {
96 fprintf(stderr,"Can't open file via pipe '%s'\n",command);
97 return(NULL);
98 }
99
100 return(fp);
101 }
102
103 /****************************************************************
104 * out_image
105 ****************************************************************/
106
out_image(unsigned char * image_buffer,unsigned char * color_table,int width,int height,int outtype,char * name_base,char * name_ext,int digits,int num,char * filter)107 int out_image
108 (
109 unsigned char *image_buffer,
110 unsigned char *color_table,
111 int width,
112 int height,
113 int outtype,
114 char *name_base,
115 char *name_ext,
116 int digits,
117 int num,
118 char *filter
119 )
120 {
121 FILE *fopen(), *fpout;
122 struct stat statbuf;
123 char out_name[MAX_LEN];
124 char digiter[MAX_LEN];
125 unsigned char *red, *green, *blue, *pp, *zz, *wbuff;
126 int m,n,i,j,ic, len, zsize;
127 int fbm_planes, fbm_bits, fbm_physbits;
128 int fbm_rowlen, fbm_plnlen, fbm_clrlen;
129 double fbm_aspect;
130
131 if (name_ext == NULL)
132 len=strlen(name_base)+digits+1;
133 else
134 len=strlen(name_base)+strlen(name_ext)+digits+1;
135
136 if (len > MAX_LEN)
137 {
138 fprintf(stderr,"Image %d: File name too long!\n",num);
139 return(0);
140 }
141
142 m=num;
143 for (i=(digits-1); i >= 0; i--)
144 {
145 n=m % 10;
146 switch (n)
147 {
148 case 0: digiter[i] = '0'; break;
149 case 1: digiter[i] = '1'; break;
150 case 2: digiter[i] = '2'; break;
151 case 3: digiter[i] = '3'; break;
152 case 4: digiter[i] = '4'; break;
153 case 5: digiter[i] = '5'; break;
154 case 6: digiter[i] = '6'; break;
155 case 7: digiter[i] = '7'; break;
156 case 8: digiter[i] = '8'; break;
157 case 9: digiter[i] = '9'; break;
158 default: break;
159 }
160 m = (m - n) / 10;
161 }
162 digiter[digits] = '\0';
163
164 if (name_ext == NULL)
165 sprintf(out_name,"%s.%s",name_base,digiter);
166 else
167 sprintf(out_name,"%s%s.%s",name_base,digiter,name_ext);
168
169 if (stat(out_name, &statbuf) == 0) /* exists already */
170 {
171 fprintf(stderr,
172 "Error: file '%s' already exists -- image %d not written\n",
173 out_name,num);
174 return(0);
175 }
176
177 if ((fpout=xx_open(out_name, filter)) == NULL) return(0);
178
179 fprintf(stdout,"Write '%s'\n",out_name);
180
181 red=&color_table[0];
182 green=&color_table[MAXCOLORS];
183 blue=&color_table[2*MAXCOLORS];
184
185 if (outtype == PPM_ASCII)
186 {
187 fprintf(fpout,"P3\n");
188 fprintf(fpout,"%d %d 255\n",width,height);
189
190 pp = image_buffer;
191 for (i = 0; i < (width*height); i++)
192 {
193 ic = *pp++;
194 fprintf(fpout,"%d %d %d\n",red[ic],green[ic],blue[ic]);
195 }
196 }
197 else if (outtype == PPM_RAW)
198 {
199 zsize = 3 * width;
200 wbuff = malloc(zsize);
201 if (wbuff == NULL)
202 {
203 fprintf(stderr,"Error allocating %d bytes\n",zsize);
204 xx_close(fpout,filter);
205 return(0);
206 }
207
208 fprintf(fpout,"P6\n");
209 fprintf(fpout,"%d %d 255\n",width,height);
210
211 pp = image_buffer;
212 for (j = 0; j < height; j++)
213 {
214 zz = wbuff;
215 for (i = 0; i < width; i++)
216 {
217 ic = *pp++;
218 *zz++ = red[ic];
219 *zz++ = green[ic];
220 *zz++ = blue[ic];
221 }
222 if (fwrite(wbuff, 1, zsize, fpout) != zsize)
223 {
224 fprintf(stderr,"Write error in row %d, '%s' is incomplete\n",
225 j, out_name);
226 xx_close(fpout,filter);
227 return(0);
228 }
229 }
230 free(wbuff);
231 }
232 else if (outtype == FBM_MAPPED)
233 {
234 zsize = 256;
235 wbuff = calloc(1, zsize);
236 if (wbuff == NULL)
237 {
238 fprintf(stderr,"Error allocating %d bytes\n", zsize);
239 xx_close(fpout,filter);
240 return(0);
241 }
242 fbm_planes = 1;
243 fbm_bits = fbm_physbits = 8;
244 fbm_rowlen = width;
245 fbm_plnlen = width * height;
246 fbm_clrlen = 3 * MAXCOLORS;
247 fbm_aspect = 1.0;
248 strncpy (&wbuff[0], "%bitmap", 8);
249 sprintf (&wbuff[8], "%7d", width);
250 sprintf (&wbuff[16], "%7d", height);
251 sprintf (&wbuff[24], "%7d", fbm_planes);
252 sprintf (&wbuff[32], "%7d", fbm_bits);
253 sprintf (&wbuff[40], "%7d", fbm_physbits);
254 sprintf (&wbuff[48], "%11d", fbm_rowlen);
255 sprintf (&wbuff[60], "%11d", fbm_plnlen);
256 sprintf (&wbuff[72], "%11d", fbm_clrlen);
257 sprintf (&wbuff[84], "%11.6f", fbm_aspect);
258 if (fwrite(wbuff, 1, zsize, fpout) != zsize)
259 {
260 fprintf(stderr,"Error writing fbm header, '%s' is incomplete\n",
261 out_name);
262 xx_close(fpout,filter);
263 return(0);
264 }
265 if (fwrite(color_table, 1, fbm_clrlen, fpout) != fbm_clrlen)
266 {
267 fprintf(stderr,"Error writing fbm color table, '%s' is incomplete\n",
268 out_name);
269 xx_close(fpout,filter);
270 return(0);
271 }
272 if (fwrite(image_buffer, 1, fbm_plnlen, fpout) != fbm_plnlen)
273 {
274 fprintf(stderr,"Error writing fbm image, '%s' is incomplete\n",
275 out_name);
276 xx_close(fpout,filter);
277 return(0);
278 }
279 }
280 else
281 {
282 fprintf(stderr,"Invalid output type\n");
283 xx_close(fpout,filter);
284 return(0);
285 }
286
287 if (ferror(fpout))
288 {
289 fprintf(stderr,"Error writing ppm\n");
290 xx_close(fpout,filter);
291 return(0);
292 }
293
294 xx_close(fpout,filter);
295
296 return(1);
297 }
298