tumble.c

changeset 139
ec2a06d8a2a6
parent 134
313aba417199
child 141
752599b50ff3
     1.1 diff -r 692e6411df52 -r ec2a06d8a2a6 tumble.c
     1.2 --- a/tumble.c	Sun Mar 16 15:40:00 2003 +0000
     1.3 +++ b/tumble.c	Wed Mar 19 15:39:55 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.36 2003/03/16 05:58:26 eric Exp $
     1.9 + * $Id: tumble.c,v 1.37 2003/03/19 07:39:55 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 @@ -60,8 +60,18 @@
    1.14  int verbose;
    1.15  
    1.16  
    1.17 +typedef enum
    1.18 +  {
    1.19 +    INPUT_FILE_TYPE_NONE,
    1.20 +    INPUT_FILE_TYPE_TIFF,
    1.21 +    INPUT_FILE_TYPE_JPEG
    1.22 +  } input_file_type_t;
    1.23 +
    1.24 +
    1.25  char *in_filename;
    1.26 -TIFF *in;
    1.27 +input_file_type_t in_type;
    1.28 +FILE *in;
    1.29 +TIFF *tiff_in;
    1.30  output_file_t *output_files;
    1.31  output_file_t *out;
    1.32  
    1.33 @@ -92,6 +102,8 @@
    1.34  
    1.35  
    1.36  /* generate fatal error message to stderr, doesn't return */
    1.37 +void fatal (int ret, char *format, ...) __attribute__ ((noreturn));
    1.38 +
    1.39  void fatal (int ret, char *format, ...)
    1.40  {
    1.41    va_list ap;
    1.42 @@ -108,7 +120,7 @@
    1.43      fprintf (stderr, "\n");
    1.44    if (ret == 1)
    1.45      usage ();
    1.46 -  close_tiff_input_file ();
    1.47 +  close_input_file ();
    1.48    close_pdf_output_files ();
    1.49    exit (ret);
    1.50  }
    1.51 @@ -116,24 +128,49 @@
    1.52  
    1.53  bool close_tiff_input_file (void)
    1.54  {
    1.55 -  if (in)
    1.56 +  TIFFClose (tiff_in);
    1.57 +  return (1);
    1.58 +}
    1.59 +
    1.60 +
    1.61 +bool open_tiff_input_file (FILE *f, char *name)
    1.62 +{
    1.63 +  tiff_in = TIFFFdOpen (fileno (f), name, "r");
    1.64 +  if (! tiff_in)
    1.65      {
    1.66 +      fprintf (stderr, "can't open input file '%s'\n", name);
    1.67        free (in_filename);
    1.68 -      TIFFClose (in);
    1.69 +      return (0);
    1.70      }
    1.71 -  in = NULL;
    1.72 -  in_filename = NULL;
    1.73 +  in_type = INPUT_FILE_TYPE_TIFF;
    1.74    return (1);
    1.75  }
    1.76  
    1.77  
    1.78 -bool open_tiff_input_file (char *name)
    1.79 +bool close_jpeg_input_file (void)
    1.80 +{
    1.81 +  return (1);
    1.82 +}
    1.83 +
    1.84 +
    1.85 +bool open_jpeg_input_file (FILE *f, char *name)
    1.86  {
    1.87 +  in_type = INPUT_FILE_TYPE_JPEG;
    1.88 +  return (1);
    1.89 +}
    1.90 +
    1.91 +
    1.92 +bool open_input_file (char *name)
    1.93 +{
    1.94 +  bool result;
    1.95 +  uint8_t buf [2];
    1.96 +  size_t l;
    1.97 +
    1.98    if (in)
    1.99      {
   1.100        if (strcmp (name, in_filename) == 0)
   1.101  	return (1);
   1.102 -      close_tiff_input_file ();
   1.103 +      close_input_file ();
   1.104      }
   1.105    in_filename = strdup (name);
   1.106    if (! in_filename)
   1.107 @@ -141,17 +178,90 @@
   1.108        fprintf (stderr, "can't strdup input filename '%s'\n", name);
   1.109        return (0);
   1.110      }
   1.111 -  in = TIFFOpen (name, "r");
   1.112 +
   1.113 +  in = fopen (name, "rb");
   1.114    if (! in)
   1.115 +    return (0);
   1.116 +
   1.117 +  l = fread (& buf [0], 1, sizeof (buf), in);
   1.118 +  if (l != sizeof (buf))
   1.119 +    return (0);
   1.120 +
   1.121 +  rewind (in);
   1.122 +
   1.123 +  if ((buf [0] == 0x49) && (buf [1] == 0x49))
   1.124 +    result = open_tiff_input_file (in, name);
   1.125 +  else if ((buf [0] == 0xff) && (buf [1] == 0xd8))
   1.126 +    result = open_jpeg_input_file (in, name);
   1.127 +  else
   1.128 +    {
   1.129 +      fprintf (stderr, "unrecognized file header in file '%s'\n", name);
   1.130 +      result = 0;
   1.131 +    }
   1.132 +  if (! result)
   1.133 +    {
   1.134 +      if (in)
   1.135 +	fclose (in);
   1.136 +      in = NULL;
   1.137 +      in_type = INPUT_FILE_TYPE_NONE;
   1.138 +    }
   1.139 +  return (result);
   1.140 +}
   1.141 +
   1.142 +
   1.143 +bool close_input_file (void)
   1.144 +{
   1.145 +  bool result;
   1.146 +
   1.147 +  switch (in_type)
   1.148      {
   1.149 -      fprintf (stderr, "can't open input file '%s'\n", name);
   1.150 -      free (in_filename);
   1.151 -      return (0);
   1.152 +    case INPUT_FILE_TYPE_NONE:
   1.153 +      return (1);
   1.154 +    case INPUT_FILE_TYPE_TIFF:
   1.155 +      result = close_tiff_input_file ();
   1.156 +      break;
   1.157 +    case INPUT_FILE_TYPE_JPEG:
   1.158 +      result = close_jpeg_input_file ();
   1.159 +      break;
   1.160 +    default:
   1.161 +      fatal (3, "internal error: bad input file type\n");
   1.162      }
   1.163 +
   1.164 +  if (in_filename)
   1.165 +    free (in_filename);
   1.166 +  fclose (in);
   1.167 +  in = NULL;
   1.168 +
   1.169 +  return (result);
   1.170 +}
   1.171 +
   1.172 +
   1.173 +bool last_tiff_input_page (void)
   1.174 +{
   1.175 +  return (TIFFLastDirectory (tiff_in));
   1.176 +}
   1.177 +
   1.178 +
   1.179 +bool last_jpeg_input_page (void)
   1.180 +{
   1.181    return (1);
   1.182  }
   1.183  
   1.184  
   1.185 +bool last_input_page (void)
   1.186 +{
   1.187 +  switch (in_type)
   1.188 +    {
   1.189 +    case INPUT_FILE_TYPE_TIFF:
   1.190 +      return (last_tiff_input_page ());
   1.191 +    case INPUT_FILE_TYPE_JPEG:
   1.192 +      return (last_jpeg_input_page ());
   1.193 +    default:
   1.194 +      fatal (3, "internal error: bad input file type\n");
   1.195 +    }
   1.196 +}
   1.197 +
   1.198 +
   1.199  bool close_pdf_output_files (void)
   1.200  {
   1.201    output_file_t *o, *n;
   1.202 @@ -271,12 +381,6 @@
   1.203  #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
   1.204  
   1.205  
   1.206 -bool last_tiff_page (void)
   1.207 -{
   1.208 -  return (TIFFLastDirectory (in));
   1.209 -}
   1.210 -
   1.211 -
   1.212  static pdf_page_handle process_tiff_page (int image,  /* range 1 .. n */
   1.213  					  input_attributes_t input_attributes)
   1.214  {
   1.215 @@ -304,50 +408,50 @@
   1.216  
   1.217    pdf_page_handle page = NULL;
   1.218  
   1.219 -  if (! TIFFSetDirectory (in, image - 1))
   1.220 +  if (! TIFFSetDirectory (tiff_in, image - 1))
   1.221      {
   1.222        fprintf (stderr, "can't find page %d of input file\n", image);
   1.223        goto fail;
   1.224      }
   1.225 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGELENGTH, & image_length))
   1.226 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_length))
   1.227      {
   1.228        fprintf (stderr, "can't get image length\n");
   1.229        goto fail;
   1.230      }
   1.231 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGEWIDTH, & image_width))
   1.232 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width))
   1.233      {
   1.234        fprintf (stderr, "can't get image width\n");
   1.235        goto fail;
   1.236      }
   1.237  
   1.238 -  if (1 != TIFFGetField (in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   1.239 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   1.240      {
   1.241        fprintf (stderr, "can't get samples per pixel\n");
   1.242        goto fail;
   1.243      }
   1.244  
   1.245  #ifdef CHECK_DEPTH
   1.246 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGEDEPTH, & image_depth))
   1.247 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth))
   1.248      {
   1.249        fprintf (stderr, "can't get image depth\n");
   1.250        goto fail;
   1.251      }
   1.252  #endif
   1.253  
   1.254 -  if (1 != TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   1.255 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   1.256      {
   1.257        fprintf (stderr, "can't get bits per sample\n");
   1.258        goto fail;
   1.259      }
   1.260  
   1.261 -  if (1 != TIFFGetField (in, TIFFTAG_PLANARCONFIG, & planar_config))
   1.262 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config))
   1.263      planar_config = 1;
   1.264  
   1.265 -  if (1 != TIFFGetField (in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   1.266 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   1.267      resolution_unit = 2;
   1.268 -  if (1 != TIFFGetField (in, TIFFTAG_XRESOLUTION, & x_resolution))
   1.269 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution))
   1.270      x_resolution = 300;
   1.271 -  if (1 != TIFFGetField (in, TIFFTAG_YRESOLUTION, & y_resolution))
   1.272 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution))
   1.273      y_resolution = 300;
   1.274  
   1.275    if (samples_per_pixel != 1)
   1.276 @@ -412,7 +516,7 @@
   1.277      }
   1.278  
   1.279    for (row = 0; row < image_length; row++)
   1.280 -    if (1 != TIFFReadScanline (in,
   1.281 +    if (1 != TIFFReadScanline (tiff_in,
   1.282  			       bitmap->bits + row * bitmap->row_words,
   1.283  			       row,
   1.284  			       0))
   1.285 @@ -472,27 +576,26 @@
   1.286  }
   1.287  
   1.288  
   1.289 -#if 0
   1.290  pdf_page_handle process_jpeg_page (int image,  /* range 1 .. n */
   1.291  				   input_attributes_t input_attributes)
   1.292  {
   1.293 -  FILE *f;
   1.294    pdf_page_handle page;
   1.295 +  double width_points, height_points;  /* really 1/72 inch units rather than
   1.296 +					  points */
   1.297  
   1.298 -  f = fopen (filename, "rb");
   1.299 -  if (! f)
   1.300 -    fatal ("error opening input file '%s'\n", filename);
   1.301 +  /* $$$ need to get these from somewhere else, hardcoded for now */
   1.302 +  width_points = 4 * 72.0;
   1.303 +  height_points = 4 * 72.0;
   1.304  
   1.305    page = pdf_new_page (out->pdf, width_points, height_points);
   1.306  
   1.307    pdf_write_jpeg_image (page,
   1.308  			0, 0,  /* x, y */
   1.309  			width_points, height_points,
   1.310 -			f);
   1.311 +			in);
   1.312  
   1.313    return (page);
   1.314  }
   1.315 -#endif
   1.316  
   1.317  
   1.318  bool process_page (int image,  /* range 1 .. n */
   1.319 @@ -502,7 +605,17 @@
   1.320  {
   1.321    pdf_page_handle page;
   1.322  
   1.323 -  page = process_tiff_page (image, input_attributes);
   1.324 +  switch (in_type)
   1.325 +    {
   1.326 +    case INPUT_FILE_TYPE_TIFF:
   1.327 +      page = process_tiff_page (image, input_attributes);
   1.328 +      break;
   1.329 +    case INPUT_FILE_TYPE_JPEG:
   1.330 +      page = process_jpeg_page (image, input_attributes);
   1.331 +      break;
   1.332 +    default:
   1.333 +      fatal (3, "internal error: bad input file type\n");
   1.334 +    }
   1.335  
   1.336    while (bookmarks)
   1.337      {
   1.338 @@ -608,7 +721,7 @@
   1.339      fatal (3, "error opening output file \"%s\"\n", out_fn);
   1.340    for (i = 0; i < inf_count; i++)
   1.341      {
   1.342 -      if (! open_tiff_input_file (in_fn [i]))
   1.343 +      if (! open_input_file (in_fn [i]))
   1.344  	fatal (3, "error opening input file \"%s\"\n", in_fn [i]);
   1.345        for (ip = 1;; ip++)
   1.346  	{
   1.347 @@ -622,12 +735,12 @@
   1.348  			      bookmark_fmt ? & bookmark : NULL,
   1.349  			      NULL))
   1.350  	    fatal (3, "error processing page %d of input file \"%s\"\n", ip, in_fn [i]);
   1.351 -	  if (last_tiff_page ())
   1.352 +	  if (last_input_page ())
   1.353  	    break;
   1.354  	}
   1.355        if (verbose)
   1.356  	fprintf (stderr, "processed %d pages of input file \"%s\"\n", ip, in_fn [i]);
   1.357 -      if (! close_tiff_input_file ())
   1.358 +      if (! close_input_file ())
   1.359  	fatal (3, "error closing input file \"%s\"\n", in_fn [i]);
   1.360      }
   1.361    if (! close_pdf_output_files ())
   1.362 @@ -719,7 +832,7 @@
   1.363    else
   1.364      main_args (out_fn, inf_count, in_fn, bookmark_fmt);
   1.365    
   1.366 -  close_tiff_input_file ();
   1.367 +  close_input_file ();
   1.368    close_pdf_output_files ();
   1.369    exit (0);
   1.370  }