tumble.c

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