Tue, 01 Jan 2002 05:02:44 +0000
create temporary TIFF file.
1 /*
2 * tiffg4: reencode a bilevel TIFF file as a single-strip TIFF Class F Group 4
3 * Main program
4 * $Id: t2p.c,v 1.9 2001/12/31 21:02:44 eric Exp $
5 * Copyright 2001 Eric Smith <eric@brouhaha.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. Note that permission is
10 * not granted to redistribute this program under the terms of any
11 * other version of the General Public License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <tiffio.h>
28 #include <panda/functions.h>
29 #include <panda/constants.h>
31 #include "type.h"
32 #include "bitblt.h"
33 #include "semantics.h"
34 #include "parser.tab.h"
35 #include "tiff2pdf.h"
38 #define POINTS_PER_INCH 72
40 /* page size limited by Acrobat Reader to 45 inches on a side */
41 #define PAGE_MAX_INCHES 45
42 #define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH)
45 typedef struct output_file_t
46 {
47 struct output_file_t *next;
48 char *name;
49 panda_pdf *pdf;
50 } output_file_t;
53 char *in_filename;
54 TIFF *in;
55 output_file_t *output_files;
56 output_file_t *out;
57 /* panda_pdf *out; */
60 boolean close_tiff_input_file (void)
61 {
62 if (in)
63 {
64 free (in_filename);
65 TIFFClose (in);
66 }
67 in = NULL;
68 in_filename = NULL;
69 return (1);
70 }
72 boolean open_tiff_input_file (char *name)
73 {
74 if (in)
75 {
76 if (strcmp (name, in_filename) == 0)
77 return (1);
78 close_tiff_input_file ();
79 }
80 in_filename = strdup (name);
81 if (! in_filename)
82 {
83 fprintf (stderr, "can't strdup input filename '%s'\n", name);
84 return (0);
85 }
86 in = TIFFOpen (name, "r");
87 if (! in)
88 {
89 fprintf (stderr, "can't open input file '%s'\n", name);
90 free (in_filename);
91 return (0);
92 }
93 return (1);
94 }
97 boolean close_pdf_output_files (void)
98 {
99 output_file_t *o, *n;
101 for (o = output_files; o; o = n)
102 {
103 n = o->next;
104 panda_close (o->pdf);
105 free (o->name);
106 free (o);
107 }
108 out = NULL;
109 output_files = NULL;
110 return (1);
111 }
113 boolean open_pdf_output_file (char *name)
114 {
115 output_file_t *o;
117 if (out && (strcmp (name, out->name) == 0))
118 return (1);
119 for (o = output_files; o; o = o->next)
120 if (strcmp (name, o->name) == 0)
121 {
122 out = o;
123 return (1);
124 }
125 o = calloc (1, sizeof (output_file_t));
126 if (! 0)
127 {
128 fprintf (stderr, "can't calloc output file struct for '%s'\n", name);
129 return (0);
130 }
132 o->name = strdup (name);
133 if (! o->name)
134 {
135 fprintf (stderr, "can't strdup output filename '%s'\n", name);
136 free (o);
137 return (0);
138 }
140 o->pdf = panda_open (name, "w");
141 if (! o->pdf)
142 {
143 fprintf (stderr, "can't open output file '%s'\n", name);
144 free (o->name);
145 free (o);
146 return (0);
147 }
149 /* prepend new output file onto list */
150 o->next = output_files;
151 output_files = o;
153 out = o;
154 return (1);
155 }
158 void process_page_numbers (int page_index,
159 int count,
160 int base,
161 page_label_t *page_label)
162 {
163 }
166 boolean process_page (int image, /* range 1 .. n */
167 input_attributes_t input_attributes,
168 bookmark_t *bookmarks)
169 {
170 u32 image_length, image_width;
171 #ifdef CHECK_DEPTH
172 u32 image_depth;
173 #endif
174 u16 bits_per_sample;
175 u16 planar_config;
176 u16 resolution_unit;
177 float x_resolution, y_resolution;
178 int width_points, height_points; /* really 1/72 inch units rather than
179 points */
182 char *buffer;
183 u32 row;
185 panda_page *page;
187 int tiff_temp_fd;
188 char tiff_temp_fn [] = "/var/tmp/tiff2pdf-XXXXXX\0";
189 TIFF *tiff_temp;
191 char pagesize [26]; /* Needs to hold two ints of four characters (0..3420),
192 two zeros, three spaces, two brackets, and a NULL.
193 Added an extra ten characters just in case. */
195 if (! TIFFSetDirectory (in, image - 1))
196 {
197 fprintf (stderr, "can't find page %d of input file\n", image);
198 goto fail;
199 }
200 if (1 != TIFFGetField (in, TIFFTAG_IMAGELENGTH, & image_length))
201 {
202 fprintf (stderr, "can't get image length\n");
203 goto fail;
204 }
205 if (1 != TIFFGetField (in, TIFFTAG_IMAGEWIDTH, & image_width))
206 {
207 fprintf (stderr, "can't get image width\n");
208 goto fail;
209 }
210 #ifdef CHECK_DEPTH
211 if (1 != TIFFGetField (in, TIFFTAG_IMAGEDEPTH, & image_depth))
212 {
213 fprintf (stderr, "can't get image depth\n");
214 goto fail;
215 }
216 #endif
218 if (1 != TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
219 {
220 fprintf (stderr, "can't get bits per sample\n");
221 goto fail;
222 }
224 if (1 != TIFFGetField (in, TIFFTAG_PLANARCONFIG, & planar_config))
225 planar_config = 1;
227 printf ("image length %u width %u, "
228 #ifdef CHECK_DEPTH
229 "depth %u, "
230 #endif
231 "planar config %u\n",
232 image_length, image_width,
233 #ifdef CHECK_DEPTH
234 image_depth,
235 #endif
236 planar_config);
238 if (1 != TIFFGetField (in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
239 resolution_unit = 2;
240 if (1 != TIFFGetField (in, TIFFTAG_XRESOLUTION, & x_resolution))
241 x_resolution = 300;
242 if (1 != TIFFGetField (in, TIFFTAG_YRESOLUTION, & y_resolution))
243 y_resolution = 300;
245 printf ("resolution unit %u, x resolution %f, y resolution %f\n",
246 resolution_unit, x_resolution, y_resolution);
248 #ifdef CHECK_DEPTH
249 if (image_depth != 1)
250 {
251 fprintf (stderr, "image depth %u, must be 1\n", image_depth);
252 goto fail;
253 }
254 #endif
256 if (bits_per_sample != 1)
257 {
258 fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample);
259 goto fail;
260 }
262 if (planar_config != 1)
263 {
264 fprintf (stderr, "planar config %u, must be 1\n", planar_config);
265 goto fail;
266 }
268 tiff_temp_fd = mkstemp (tiff_temp_fn);
269 if (tiff_temp_fd < 0)
270 {
271 fprintf (stderr, "can't create temporary TIFF file\n");
272 goto fail;
273 }
275 tiff_temp = TIFFFdOpen (tiff_temp_fd, tiff_temp_fn, "w");
276 if (! out)
277 {
278 fprintf (stderr, "can't open temporary TIFF file '%s'\n", tiff_temp_fn);
279 goto fail;
280 }
282 TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, image_length);
283 TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, image_width);
284 TIFFSetField (tiff_temp, TIFFTAG_PLANARCONFIG, planar_config);
286 TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, image_length);
288 TIFFSetField (tiff_temp, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
289 TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, x_resolution);
290 TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, y_resolution);
292 TIFFSetField (tiff_temp, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
293 TIFFSetField (tiff_temp, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
294 TIFFSetField (tiff_temp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
296 buffer = _TIFFmalloc (TIFFScanlineSize (in));
297 if (! buffer)
298 {
299 fprintf (stderr, "failed to allocate buffer\n");
300 goto fail;
301 }
303 for (row = 0; row < image_length; row++)
304 {
305 TIFFReadScanline (in, buffer, row, 0);
306 TIFFWriteScanline (tiff_temp, buffer, row, 0);
307 }
309 _TIFFfree (buffer);
310 TIFFClose (tiff_temp);
312 height_points = (image_width / x_resolution) * POINTS_PER_INCH;
313 width_points = (image_length / y_resolution) * POINTS_PER_INCH;
315 if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
316 {
317 fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
318 goto fail;
319 }
321 printf ("height_points %d, width_points %d\n", height_points, width_points);
323 sprintf (pagesize, "[0 0 %d %d]", width_points, height_points);
325 page = panda_newpage (out->pdf, pagesize);
326 panda_imagebox (out->pdf,
327 page,
328 0, /* top */
329 0, /* left */
330 height_points, /* bottom */
331 width_points, /* right */
332 tiff_temp_fn,
333 panda_image_tiff);
335 unlink (tiff_temp_fn);
337 return (1);
339 fail:
340 return (0);
341 }
344 int main (int argc, char *argv[])
345 {
346 int result = 0;
348 panda_init ();
350 if (argc != 2)
351 {
352 fprintf (stderr, "usage: %s spec\n", argv [0]);
353 result = 1;
354 goto fail;
355 }
357 if (! parse_spec_file (argv [1]))
358 {
359 result = 2;
360 goto fail;
361 }
363 if (! process_specs ())
364 {
365 result = 3;
366 goto fail;
367 }
369 fail:
370 close_tiff_input_file ();
371 close_pdf_output_files ();
372 return (result);
373 }