tumble.c

changeset 141
752599b50ff3
parent 139
ec2a06d8a2a6
child 149
460c336ec8d7
     1.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble.c
     1.2 --- a/tumble.c	Thu Mar 20 01:08:05 2003 +0000
     1.3 +++ b/tumble.c	Thu Mar 20 06:54:08 2003 +0000
     1.4 @@ -2,7 +2,7 @@
     1.5   * tumble: build a PDF file from image files
     1.6   *
     1.7   * Main program
     1.8 - * $Id: tumble.c,v 1.37 2003/03/19 07:39:55 eric Exp $
     1.9 + * $Id: tumble.c,v 1.38 2003/03/19 22:54:07 eric Exp $
    1.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    1.11   *
    1.12   * This program is free software; you can redistribute it and/or modify
    1.13 @@ -30,25 +30,17 @@
    1.14  #include <string.h>
    1.15  #include <unistd.h>
    1.16  
    1.17 -#include <tiffio.h>
    1.18 -#define TIFF_REVERSE_BITS
    1.19  
    1.20 -#include "bitblt.h"
    1.21  #include "semantics.h"
    1.22  #include "parser.tab.h"
    1.23  #include "tumble.h"
    1.24 +#include "bitblt.h"
    1.25  #include "pdf.h"
    1.26 +#include "tumble_input.h"
    1.27  
    1.28  
    1.29  #define MAX_INPUT_FILES 5000
    1.30  
    1.31 -#define POINTS_PER_INCH 72
    1.32 -
    1.33 -/* page size limited by Acrobat Reader to 45 inches on a side */
    1.34 -#define PAGE_MAX_INCHES 45
    1.35 -#define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH)
    1.36 -
    1.37 -
    1.38  typedef struct output_file_t
    1.39  {
    1.40    struct output_file_t *next;
    1.41 @@ -60,18 +52,6 @@
    1.42  int verbose;
    1.43  
    1.44  
    1.45 -typedef enum
    1.46 -  {
    1.47 -    INPUT_FILE_TYPE_NONE,
    1.48 -    INPUT_FILE_TYPE_TIFF,
    1.49 -    INPUT_FILE_TYPE_JPEG
    1.50 -  } input_file_type_t;
    1.51 -
    1.52 -
    1.53 -char *in_filename;
    1.54 -input_file_type_t in_type;
    1.55 -FILE *in;
    1.56 -TIFF *tiff_in;
    1.57  output_file_t *output_files;
    1.58  output_file_t *out;
    1.59  
    1.60 @@ -79,7 +59,6 @@
    1.61  char *progname;
    1.62  
    1.63  
    1.64 -bool close_tiff_input_file (void);
    1.65  bool close_pdf_output_files (void);
    1.66  
    1.67  
    1.68 @@ -126,142 +105,6 @@
    1.69  }
    1.70  
    1.71  
    1.72 -bool close_tiff_input_file (void)
    1.73 -{
    1.74 -  TIFFClose (tiff_in);
    1.75 -  return (1);
    1.76 -}
    1.77 -
    1.78 -
    1.79 -bool open_tiff_input_file (FILE *f, char *name)
    1.80 -{
    1.81 -  tiff_in = TIFFFdOpen (fileno (f), name, "r");
    1.82 -  if (! tiff_in)
    1.83 -    {
    1.84 -      fprintf (stderr, "can't open input file '%s'\n", name);
    1.85 -      free (in_filename);
    1.86 -      return (0);
    1.87 -    }
    1.88 -  in_type = INPUT_FILE_TYPE_TIFF;
    1.89 -  return (1);
    1.90 -}
    1.91 -
    1.92 -
    1.93 -bool close_jpeg_input_file (void)
    1.94 -{
    1.95 -  return (1);
    1.96 -}
    1.97 -
    1.98 -
    1.99 -bool open_jpeg_input_file (FILE *f, char *name)
   1.100 -{
   1.101 -  in_type = INPUT_FILE_TYPE_JPEG;
   1.102 -  return (1);
   1.103 -}
   1.104 -
   1.105 -
   1.106 -bool open_input_file (char *name)
   1.107 -{
   1.108 -  bool result;
   1.109 -  uint8_t buf [2];
   1.110 -  size_t l;
   1.111 -
   1.112 -  if (in)
   1.113 -    {
   1.114 -      if (strcmp (name, in_filename) == 0)
   1.115 -	return (1);
   1.116 -      close_input_file ();
   1.117 -    }
   1.118 -  in_filename = strdup (name);
   1.119 -  if (! in_filename)
   1.120 -    {
   1.121 -      fprintf (stderr, "can't strdup input filename '%s'\n", name);
   1.122 -      return (0);
   1.123 -    }
   1.124 -
   1.125 -  in = fopen (name, "rb");
   1.126 -  if (! in)
   1.127 -    return (0);
   1.128 -
   1.129 -  l = fread (& buf [0], 1, sizeof (buf), in);
   1.130 -  if (l != sizeof (buf))
   1.131 -    return (0);
   1.132 -
   1.133 -  rewind (in);
   1.134 -
   1.135 -  if ((buf [0] == 0x49) && (buf [1] == 0x49))
   1.136 -    result = open_tiff_input_file (in, name);
   1.137 -  else if ((buf [0] == 0xff) && (buf [1] == 0xd8))
   1.138 -    result = open_jpeg_input_file (in, name);
   1.139 -  else
   1.140 -    {
   1.141 -      fprintf (stderr, "unrecognized file header in file '%s'\n", name);
   1.142 -      result = 0;
   1.143 -    }
   1.144 -  if (! result)
   1.145 -    {
   1.146 -      if (in)
   1.147 -	fclose (in);
   1.148 -      in = NULL;
   1.149 -      in_type = INPUT_FILE_TYPE_NONE;
   1.150 -    }
   1.151 -  return (result);
   1.152 -}
   1.153 -
   1.154 -
   1.155 -bool close_input_file (void)
   1.156 -{
   1.157 -  bool result;
   1.158 -
   1.159 -  switch (in_type)
   1.160 -    {
   1.161 -    case INPUT_FILE_TYPE_NONE:
   1.162 -      return (1);
   1.163 -    case INPUT_FILE_TYPE_TIFF:
   1.164 -      result = close_tiff_input_file ();
   1.165 -      break;
   1.166 -    case INPUT_FILE_TYPE_JPEG:
   1.167 -      result = close_jpeg_input_file ();
   1.168 -      break;
   1.169 -    default:
   1.170 -      fatal (3, "internal error: bad input file type\n");
   1.171 -    }
   1.172 -
   1.173 -  if (in_filename)
   1.174 -    free (in_filename);
   1.175 -  fclose (in);
   1.176 -  in = NULL;
   1.177 -
   1.178 -  return (result);
   1.179 -}
   1.180 -
   1.181 -
   1.182 -bool last_tiff_input_page (void)
   1.183 -{
   1.184 -  return (TIFFLastDirectory (tiff_in));
   1.185 -}
   1.186 -
   1.187 -
   1.188 -bool last_jpeg_input_page (void)
   1.189 -{
   1.190 -  return (1);
   1.191 -}
   1.192 -
   1.193 -
   1.194 -bool last_input_page (void)
   1.195 -{
   1.196 -  switch (in_type)
   1.197 -    {
   1.198 -    case INPUT_FILE_TYPE_TIFF:
   1.199 -      return (last_tiff_input_page ());
   1.200 -    case INPUT_FILE_TYPE_JPEG:
   1.201 -      return (last_jpeg_input_page ());
   1.202 -    default:
   1.203 -      fatal (3, "internal error: bad input file type\n");
   1.204 -    }
   1.205 -}
   1.206 -
   1.207 -
   1.208  bool close_pdf_output_files (void)
   1.209  {
   1.210    output_file_t *o, *n;
   1.211 @@ -335,287 +178,23 @@
   1.212  }
   1.213  
   1.214  
   1.215 -/* frees original! */
   1.216 -static Bitmap *resize_bitmap (Bitmap *src,
   1.217 -			      double x_resolution,
   1.218 -			      double y_resolution,
   1.219 -			      input_attributes_t input_attributes)
   1.220 -{
   1.221 -  Rect src_rect;
   1.222 -  Point dest_min;
   1.223 -  Bitmap *dest;
   1.224 -
   1.225 -  int width_pixels = input_attributes.page_size.width * x_resolution;
   1.226 -  int height_pixels = input_attributes.page_size.height * y_resolution;
   1.227 -
   1.228 -  src_rect.min.x = (rect_width (& src->rect) - width_pixels) / 2;
   1.229 -  src_rect.min.y = (rect_height (& src->rect) - height_pixels) / 2;
   1.230 -  src_rect.max.x = src_rect.min.x + width_pixels;
   1.231 -  src_rect.max.y = src_rect.min.y + height_pixels;
   1.232 -
   1.233 -  dest_min.x = 0;
   1.234 -  dest_min.y = 0;
   1.235 -
   1.236 -  dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0);
   1.237 -  free_bitmap (src);
   1.238 -  return (dest);
   1.239 -}
   1.240 -
   1.241 -
   1.242 -/* "in place" rotation */
   1.243 -static void rotate_bitmap (Bitmap *src,
   1.244 -			   input_attributes_t input_attributes)
   1.245 -{
   1.246 -  switch (input_attributes.rotation)
   1.247 -    {
   1.248 -    case 0: break;
   1.249 -    case 90: rot_90 (src); break;
   1.250 -    case 180: rot_180 (src); break;
   1.251 -    case 270: rot_270 (src); break;
   1.252 -    default:
   1.253 -      fprintf (stderr, "rotation must be 0, 90, 180, or 270\n");
   1.254 -    }
   1.255 -}
   1.256 -
   1.257 -
   1.258 -#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
   1.259 -
   1.260 -
   1.261 -static pdf_page_handle process_tiff_page (int image,  /* range 1 .. n */
   1.262 -					  input_attributes_t input_attributes)
   1.263 -{
   1.264 -  uint32_t image_length, image_width;
   1.265 -  uint32_t dest_image_length, dest_image_width;
   1.266 -#ifdef CHECK_DEPTH
   1.267 -  uint32_t image_depth;
   1.268 -#endif
   1.269 -
   1.270 -  uint16_t samples_per_pixel;
   1.271 -  uint16_t bits_per_sample;
   1.272 -  uint16_t planar_config;
   1.273 -
   1.274 -  uint16_t resolution_unit;
   1.275 -  float x_resolution, y_resolution;
   1.276 -  double dest_x_resolution, dest_y_resolution;
   1.277 -
   1.278 -  double width_points, height_points;  /* really 1/72 inch units rather than
   1.279 -					  points */
   1.280 -
   1.281 -  Rect rect;
   1.282 -  Bitmap *bitmap = NULL;
   1.283 -
   1.284 -  int row;
   1.285 -
   1.286 -  pdf_page_handle page = NULL;
   1.287 -
   1.288 -  if (! TIFFSetDirectory (tiff_in, image - 1))
   1.289 -    {
   1.290 -      fprintf (stderr, "can't find page %d of input file\n", image);
   1.291 -      goto fail;
   1.292 -    }
   1.293 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_length))
   1.294 -    {
   1.295 -      fprintf (stderr, "can't get image length\n");
   1.296 -      goto fail;
   1.297 -    }
   1.298 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width))
   1.299 -    {
   1.300 -      fprintf (stderr, "can't get image width\n");
   1.301 -      goto fail;
   1.302 -    }
   1.303 -
   1.304 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   1.305 -    {
   1.306 -      fprintf (stderr, "can't get samples per pixel\n");
   1.307 -      goto fail;
   1.308 -    }
   1.309 -
   1.310 -#ifdef CHECK_DEPTH
   1.311 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth))
   1.312 -    {
   1.313 -      fprintf (stderr, "can't get image depth\n");
   1.314 -      goto fail;
   1.315 -    }
   1.316 -#endif
   1.317 -
   1.318 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   1.319 -    {
   1.320 -      fprintf (stderr, "can't get bits per sample\n");
   1.321 -      goto fail;
   1.322 -    }
   1.323 -
   1.324 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config))
   1.325 -    planar_config = 1;
   1.326 -
   1.327 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   1.328 -    resolution_unit = 2;
   1.329 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution))
   1.330 -    x_resolution = 300;
   1.331 -  if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution))
   1.332 -    y_resolution = 300;
   1.333 -
   1.334 -  if (samples_per_pixel != 1)
   1.335 -    {
   1.336 -      fprintf (stderr, "samples per pixel %u, must be 1\n", samples_per_pixel);
   1.337 -      goto fail;
   1.338 -    }
   1.339 -
   1.340 -#ifdef CHECK_DEPTH
   1.341 -  if (image_depth != 1)
   1.342 -    {
   1.343 -      fprintf (stderr, "image depth %u, must be 1\n", image_depth);
   1.344 -      goto fail;
   1.345 -    }
   1.346 -#endif
   1.347 -
   1.348 -  if (bits_per_sample != 1)
   1.349 -    {
   1.350 -      fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample);
   1.351 -      goto fail;
   1.352 -    }
   1.353 -
   1.354 -  if (planar_config != 1)
   1.355 -    {
   1.356 -      fprintf (stderr, "planar config %u, must be 1\n", planar_config);
   1.357 -      goto fail;
   1.358 -    }
   1.359 -
   1.360 -  if (input_attributes.has_resolution)
   1.361 -    {
   1.362 -      x_resolution = input_attributes.x_resolution;
   1.363 -      y_resolution = input_attributes.y_resolution;
   1.364 -    }
   1.365 -
   1.366 -  if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   1.367 -    {
   1.368 -      dest_image_width  = image_length;
   1.369 -      dest_image_length = image_width;
   1.370 -      dest_x_resolution = y_resolution;
   1.371 -      dest_y_resolution = x_resolution;
   1.372 -      SWAP (double, width_points, height_points);  /* $$$ not yet set!!! */
   1.373 -    }
   1.374 -  else
   1.375 -    {
   1.376 -      dest_image_width = image_width;
   1.377 -      dest_image_length = image_length;
   1.378 -      dest_x_resolution = x_resolution;
   1.379 -      dest_y_resolution = y_resolution;
   1.380 -    }
   1.381 -
   1.382 -  rect.min.x = 0;
   1.383 -  rect.min.y = 0;
   1.384 -  rect.max.x = image_width;
   1.385 -  rect.max.y = image_length;
   1.386 -
   1.387 -  bitmap = create_bitmap (& rect);
   1.388 -
   1.389 -  if (! bitmap)
   1.390 -    {
   1.391 -      fprintf (stderr, "can't allocate bitmap\n");
   1.392 -      goto fail;
   1.393 -    }
   1.394 -
   1.395 -  for (row = 0; row < image_length; row++)
   1.396 -    if (1 != TIFFReadScanline (tiff_in,
   1.397 -			       bitmap->bits + row * bitmap->row_words,
   1.398 -			       row,
   1.399 -			       0))
   1.400 -      {
   1.401 -	fprintf (stderr, "can't read TIFF scanline\n");
   1.402 -	goto fail;
   1.403 -      }
   1.404 -
   1.405 -#ifdef TIFF_REVERSE_BITS
   1.406 -  reverse_bits ((uint8_t *) bitmap->bits,
   1.407 -		image_length * bitmap->row_words * sizeof (word_t));
   1.408 -#endif /* TIFF_REVERSE_BITS */
   1.409 -
   1.410 -#if 0
   1.411 -  if (input_attributes.has_page_size)
   1.412 -    bitmap = resize_bitmap (bitmap,
   1.413 -			    x_resolution,
   1.414 -			    y_resolution,
   1.415 -			    input_attributes);
   1.416 -#endif
   1.417 -
   1.418 -  rotate_bitmap (bitmap,
   1.419 -		 input_attributes);
   1.420 -
   1.421 -  width_points = (rect_width (& bitmap->rect) / dest_x_resolution) * POINTS_PER_INCH;
   1.422 -  height_points = (rect_height (& bitmap->rect) / dest_y_resolution) * POINTS_PER_INCH;
   1.423 -
   1.424 -  if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
   1.425 -    {
   1.426 -      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   1.427 -      goto fail;
   1.428 -    }
   1.429 -
   1.430 -  page = pdf_new_page (out->pdf, width_points, height_points);
   1.431 -
   1.432 -#if 0
   1.433 -  pdf_write_text (page);
   1.434 -#else
   1.435 -  pdf_write_g4_fax_image (page,
   1.436 -			  0, 0,  /* x, y */
   1.437 -			  width_points, height_points,
   1.438 -			  bitmap,
   1.439 -			  0, /* ImageMask */
   1.440 -			  0, 0, 0,  /* r, g, b */
   1.441 -			  0); /* BlackIs1 */
   1.442 -#endif
   1.443 -
   1.444 -  if (bitmap)
   1.445 -    free_bitmap (bitmap);
   1.446 -  return (page);
   1.447 -
   1.448 - fail:
   1.449 -  if (bitmap)
   1.450 -    free_bitmap (bitmap);
   1.451 -
   1.452 -  return (NULL);
   1.453 -}
   1.454 -
   1.455 -
   1.456 -pdf_page_handle process_jpeg_page (int image,  /* range 1 .. n */
   1.457 -				   input_attributes_t input_attributes)
   1.458 -{
   1.459 -  pdf_page_handle page;
   1.460 -  double width_points, height_points;  /* really 1/72 inch units rather than
   1.461 -					  points */
   1.462 -
   1.463 -  /* $$$ need to get these from somewhere else, hardcoded for now */
   1.464 -  width_points = 4 * 72.0;
   1.465 -  height_points = 4 * 72.0;
   1.466 -
   1.467 -  page = pdf_new_page (out->pdf, width_points, height_points);
   1.468 -
   1.469 -  pdf_write_jpeg_image (page,
   1.470 -			0, 0,  /* x, y */
   1.471 -			width_points, height_points,
   1.472 -			in);
   1.473 -
   1.474 -  return (page);
   1.475 -}
   1.476 -
   1.477 -
   1.478  bool process_page (int image,  /* range 1 .. n */
   1.479  		   input_attributes_t input_attributes,
   1.480  		   bookmark_t *bookmarks,
   1.481  		   page_label_t *page_label)
   1.482  {
   1.483    pdf_page_handle page;
   1.484 +  image_info_t image_info;
   1.485 +  
   1.486 +  if (! get_image_info (image, input_attributes, & image_info))
   1.487 +    return (0);
   1.488  
   1.489 -  switch (in_type)
   1.490 -    {
   1.491 -    case INPUT_FILE_TYPE_TIFF:
   1.492 -      page = process_tiff_page (image, input_attributes);
   1.493 -      break;
   1.494 -    case INPUT_FILE_TYPE_JPEG:
   1.495 -      page = process_jpeg_page (image, input_attributes);
   1.496 -      break;
   1.497 -    default:
   1.498 -      fatal (3, "internal error: bad input file type\n");
   1.499 -    }
   1.500 +  page = pdf_new_page (out->pdf,
   1.501 +		       image_info.width_points,
   1.502 +		       image_info.height_points);
   1.503 +
   1.504 +  if (! process_image (image, input_attributes, & image_info, page))
   1.505 +    return (0);
   1.506  
   1.507    while (bookmarks)
   1.508      {
   1.509 @@ -769,6 +348,9 @@
   1.510  
   1.511    pdf_init ();
   1.512  
   1.513 +  init_tiff_handler ();
   1.514 +  init_jpeg_handler ();
   1.515 +
   1.516    while (--argc)
   1.517      {
   1.518        if (argv [1][0] == '-')