tumble.c

Tue, 01 Jan 2002 05:02:44 +0000

author
eric
date
Tue, 01 Jan 2002 05:02:44 +0000
changeset 28
ba8313d18bd3
parent 26
4368c5fd9242
child 29
c904ffd6a1cf
permissions
-rw-r--r--

create temporary TIFF file.

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