more JPEG support.

Wed, 19 Mar 2003 15:39:55 +0000

author
eric
date
Wed, 19 Mar 2003 15:39:55 +0000
changeset 139
ec2a06d8a2a6
parent 138
692e6411df52
child 140
3fe049d83e22

more JPEG support.

pdf_jpeg.c file | annotate | diff | revisions
semantics.c file | annotate | diff | revisions
tumble.c file | annotate | diff | revisions
tumble.h file | annotate | diff | revisions
     1.1 diff -r 692e6411df52 -r ec2a06d8a2a6 pdf_jpeg.c
     1.2 --- a/pdf_jpeg.c	Sun Mar 16 15:40:00 2003 +0000
     1.3 +++ b/pdf_jpeg.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   * PDF routines
     1.8 - * $Id: pdf_jpeg.c,v 1.2 2003/03/13 00:57:05 eric Exp $
     1.9 + * $Id: pdf_jpeg.c,v 1.3 2003/03/19 07:39:55 eric Exp $
    1.10   * Copyright 2003 Eric Smith <eric@brouhaha.com>
    1.11   *
    1.12   * This program is free software; you can redistribute it and/or modify
    1.13 @@ -40,9 +40,9 @@
    1.14  {
    1.15    double width, height;
    1.16    double x, y;
    1.17 +  bool color;  /* false for grayscale */
    1.18 +  uint32_t width_samples, height_samples;
    1.19    FILE *f;
    1.20 -  unsigned long Columns;
    1.21 -  unsigned long Rows;
    1.22    char XObject_name [4];
    1.23  };
    1.24  
    1.25 @@ -69,14 +69,13 @@
    1.26  					   void *app_data)
    1.27  {
    1.28    struct pdf_jpeg_image *image = app_data;
    1.29 -  FILE *f;
    1.30    int rlen, wlen;
    1.31    uint8_t *wp;
    1.32    uint8_t buffer [8192];
    1.33  
    1.34    while (! feof (image->f))
    1.35      {
    1.36 -      rlen = fread (& buffer [0], 1, JPEG_BUFFER_SIZE, f);
    1.37 +      rlen = fread (& buffer [0], 1, JPEG_BUFFER_SIZE, image->f);
    1.38        wp = & buffer [0];
    1.39        while (rlen)
    1.40  	{
    1.41 @@ -88,9 +87,11 @@
    1.42  	  rlen -= wlen;
    1.43  	  wp += wlen;
    1.44  	}
    1.45 -      if (ferror (f))
    1.46 +      if (ferror (image->f))
    1.47  	pdf_fatal ("error on input file\n");
    1.48      }
    1.49 +
    1.50 +  pdf_stream_printf (pdf_file, stream, "\r\n");
    1.51  }
    1.52  
    1.53  
    1.54 @@ -105,7 +106,6 @@
    1.55  
    1.56    struct pdf_obj *stream;
    1.57    struct pdf_obj *stream_dict;
    1.58 -  struct pdf_obj *decode_parms;
    1.59  
    1.60    struct pdf_obj *content_stream;
    1.61  
    1.62 @@ -117,10 +117,14 @@
    1.63    image->y = y;
    1.64  
    1.65    image->f = f;
    1.66 -#if 0
    1.67 -  image->Columns = bitmap->rect.max.x - bitmap->rect.min.x;
    1.68 -  image->Rows = bitmap->rect.max.y - bitmap->rect.min.y;
    1.69 -#endif
    1.70 +
    1.71 +  /* $$$ quick hack, should read these from file! */
    1.72 +  image->color = 1;
    1.73 +  image->width_samples = 71;
    1.74 +  image->height_samples = 88;
    1.75 +
    1.76 +  pdf_add_array_elem_unique (pdf_page->procset,
    1.77 +			     pdf_new_name (image->color ? "ImageC" : "ImageB"));
    1.78  
    1.79    stream_dict = pdf_new_obj (PT_DICTIONARY);
    1.80  
    1.81 @@ -135,26 +139,14 @@
    1.82  
    1.83    pdf_set_dict_entry (stream_dict, "Type",    pdf_new_name ("XObject"));
    1.84    pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
    1.85 -  pdf_set_dict_entry (stream_dict, "Name",    pdf_new_name (& image->XObject_name [0]));
    1.86 -  pdf_set_dict_entry (stream_dict, "Width",   pdf_new_integer (image->Columns));
    1.87 -  pdf_set_dict_entry (stream_dict, "Height",  pdf_new_integer (image->Rows));
    1.88 +// Name is required in PDF 1.0 but obsoleted in later PDF versions
    1.89 +//  pdf_set_dict_entry (stream_dict, "Name",    pdf_new_name (& image->XObject_name [0]));
    1.90 +  pdf_set_dict_entry (stream_dict, "Width",   pdf_new_integer (image->width_samples));
    1.91 +  pdf_set_dict_entry (stream_dict, "Height",  pdf_new_integer (image->height_samples));
    1.92 +  pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name (image->color ? "DeviceRGB" : "DeviceGray"));
    1.93    pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (8));
    1.94  
    1.95 -  decode_parms = pdf_new_obj (PT_DICTIONARY);
    1.96 -
    1.97 -  pdf_set_dict_entry (decode_parms,
    1.98 -		      "K",
    1.99 -		      pdf_new_integer (-1));
   1.100 -
   1.101 -  pdf_set_dict_entry (decode_parms,
   1.102 -		      "Columns",
   1.103 -		      pdf_new_integer (image->Columns));
   1.104 -
   1.105 -  pdf_set_dict_entry (decode_parms,
   1.106 -		      "Rows",
   1.107 -		      pdf_new_integer (image->Rows));
   1.108 -
   1.109 -  pdf_stream_add_filter (stream, "DCTDecode", decode_parms);
   1.110 +  pdf_stream_add_filter (stream, "DCTDecode", NULL);
   1.111  
   1.112    /* the following will write the stream, using our callback function to
   1.113       get the actual data */
   1.114 @@ -170,4 +162,3 @@
   1.115  
   1.116    pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
   1.117  }
   1.118 -
     2.1 diff -r 692e6411df52 -r ec2a06d8a2a6 semantics.c
     2.2 --- a/semantics.c	Sun Mar 16 15:40:00 2003 +0000
     2.3 +++ b/semantics.c	Wed Mar 19 15:39:55 2003 +0000
     2.4 @@ -2,7 +2,7 @@
     2.5   * tumble: build a PDF file from image files
     2.6   *
     2.7   * Semantic routines for spec file parser
     2.8 - * $Id: semantics.c,v 1.22 2003/03/16 05:58:25 eric Exp $
     2.9 + * $Id: semantics.c,v 1.23 2003/03/19 07:39:55 eric Exp $
    2.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    2.11   *
    2.12   * This program is free software; you can redistribute it and/or modify
    2.13 @@ -667,10 +667,10 @@
    2.14  	  i = 0;
    2.15  	  input_fn = get_input_filename (image->input_context);
    2.16  	  if (verbose)
    2.17 -	    fprintf (stderr, "opening TIFF file '%s'\n", input_fn);
    2.18 -	  if (! open_tiff_input_file (input_fn))
    2.19 +	    fprintf (stderr, "opening input file '%s'\n", input_fn);
    2.20 +	  if (! open_input_file (input_fn))
    2.21  	    {
    2.22 -	      fprintf (stderr, "error opening TIFF file '%s'\n", input_fn);
    2.23 +	      fprintf (stderr, "error opening input file '%s'\n", input_fn);
    2.24  	      return (0);
    2.25  	    }
    2.26  	}
     3.1 diff -r 692e6411df52 -r ec2a06d8a2a6 tumble.c
     3.2 --- a/tumble.c	Sun Mar 16 15:40:00 2003 +0000
     3.3 +++ b/tumble.c	Wed Mar 19 15:39:55 2003 +0000
     3.4 @@ -2,7 +2,7 @@
     3.5   * tumble: build a PDF file from image files
     3.6   *
     3.7   * Main program
     3.8 - * $Id: tumble.c,v 1.36 2003/03/16 05:58:26 eric Exp $
     3.9 + * $Id: tumble.c,v 1.37 2003/03/19 07:39:55 eric Exp $
    3.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    3.11   *
    3.12   * This program is free software; you can redistribute it and/or modify
    3.13 @@ -60,8 +60,18 @@
    3.14  int verbose;
    3.15  
    3.16  
    3.17 +typedef enum
    3.18 +  {
    3.19 +    INPUT_FILE_TYPE_NONE,
    3.20 +    INPUT_FILE_TYPE_TIFF,
    3.21 +    INPUT_FILE_TYPE_JPEG
    3.22 +  } input_file_type_t;
    3.23 +
    3.24 +
    3.25  char *in_filename;
    3.26 -TIFF *in;
    3.27 +input_file_type_t in_type;
    3.28 +FILE *in;
    3.29 +TIFF *tiff_in;
    3.30  output_file_t *output_files;
    3.31  output_file_t *out;
    3.32  
    3.33 @@ -92,6 +102,8 @@
    3.34  
    3.35  
    3.36  /* generate fatal error message to stderr, doesn't return */
    3.37 +void fatal (int ret, char *format, ...) __attribute__ ((noreturn));
    3.38 +
    3.39  void fatal (int ret, char *format, ...)
    3.40  {
    3.41    va_list ap;
    3.42 @@ -108,7 +120,7 @@
    3.43      fprintf (stderr, "\n");
    3.44    if (ret == 1)
    3.45      usage ();
    3.46 -  close_tiff_input_file ();
    3.47 +  close_input_file ();
    3.48    close_pdf_output_files ();
    3.49    exit (ret);
    3.50  }
    3.51 @@ -116,24 +128,49 @@
    3.52  
    3.53  bool close_tiff_input_file (void)
    3.54  {
    3.55 -  if (in)
    3.56 +  TIFFClose (tiff_in);
    3.57 +  return (1);
    3.58 +}
    3.59 +
    3.60 +
    3.61 +bool open_tiff_input_file (FILE *f, char *name)
    3.62 +{
    3.63 +  tiff_in = TIFFFdOpen (fileno (f), name, "r");
    3.64 +  if (! tiff_in)
    3.65      {
    3.66 +      fprintf (stderr, "can't open input file '%s'\n", name);
    3.67        free (in_filename);
    3.68 -      TIFFClose (in);
    3.69 +      return (0);
    3.70      }
    3.71 -  in = NULL;
    3.72 -  in_filename = NULL;
    3.73 +  in_type = INPUT_FILE_TYPE_TIFF;
    3.74    return (1);
    3.75  }
    3.76  
    3.77  
    3.78 -bool open_tiff_input_file (char *name)
    3.79 +bool close_jpeg_input_file (void)
    3.80 +{
    3.81 +  return (1);
    3.82 +}
    3.83 +
    3.84 +
    3.85 +bool open_jpeg_input_file (FILE *f, char *name)
    3.86  {
    3.87 +  in_type = INPUT_FILE_TYPE_JPEG;
    3.88 +  return (1);
    3.89 +}
    3.90 +
    3.91 +
    3.92 +bool open_input_file (char *name)
    3.93 +{
    3.94 +  bool result;
    3.95 +  uint8_t buf [2];
    3.96 +  size_t l;
    3.97 +
    3.98    if (in)
    3.99      {
   3.100        if (strcmp (name, in_filename) == 0)
   3.101  	return (1);
   3.102 -      close_tiff_input_file ();
   3.103 +      close_input_file ();
   3.104      }
   3.105    in_filename = strdup (name);
   3.106    if (! in_filename)
   3.107 @@ -141,17 +178,90 @@
   3.108        fprintf (stderr, "can't strdup input filename '%s'\n", name);
   3.109        return (0);
   3.110      }
   3.111 -  in = TIFFOpen (name, "r");
   3.112 +
   3.113 +  in = fopen (name, "rb");
   3.114    if (! in)
   3.115 +    return (0);
   3.116 +
   3.117 +  l = fread (& buf [0], 1, sizeof (buf), in);
   3.118 +  if (l != sizeof (buf))
   3.119 +    return (0);
   3.120 +
   3.121 +  rewind (in);
   3.122 +
   3.123 +  if ((buf [0] == 0x49) && (buf [1] == 0x49))
   3.124 +    result = open_tiff_input_file (in, name);
   3.125 +  else if ((buf [0] == 0xff) && (buf [1] == 0xd8))
   3.126 +    result = open_jpeg_input_file (in, name);
   3.127 +  else
   3.128 +    {
   3.129 +      fprintf (stderr, "unrecognized file header in file '%s'\n", name);
   3.130 +      result = 0;
   3.131 +    }
   3.132 +  if (! result)
   3.133 +    {
   3.134 +      if (in)
   3.135 +	fclose (in);
   3.136 +      in = NULL;
   3.137 +      in_type = INPUT_FILE_TYPE_NONE;
   3.138 +    }
   3.139 +  return (result);
   3.140 +}
   3.141 +
   3.142 +
   3.143 +bool close_input_file (void)
   3.144 +{
   3.145 +  bool result;
   3.146 +
   3.147 +  switch (in_type)
   3.148      {
   3.149 -      fprintf (stderr, "can't open input file '%s'\n", name);
   3.150 -      free (in_filename);
   3.151 -      return (0);
   3.152 +    case INPUT_FILE_TYPE_NONE:
   3.153 +      return (1);
   3.154 +    case INPUT_FILE_TYPE_TIFF:
   3.155 +      result = close_tiff_input_file ();
   3.156 +      break;
   3.157 +    case INPUT_FILE_TYPE_JPEG:
   3.158 +      result = close_jpeg_input_file ();
   3.159 +      break;
   3.160 +    default:
   3.161 +      fatal (3, "internal error: bad input file type\n");
   3.162      }
   3.163 +
   3.164 +  if (in_filename)
   3.165 +    free (in_filename);
   3.166 +  fclose (in);
   3.167 +  in = NULL;
   3.168 +
   3.169 +  return (result);
   3.170 +}
   3.171 +
   3.172 +
   3.173 +bool last_tiff_input_page (void)
   3.174 +{
   3.175 +  return (TIFFLastDirectory (tiff_in));
   3.176 +}
   3.177 +
   3.178 +
   3.179 +bool last_jpeg_input_page (void)
   3.180 +{
   3.181    return (1);
   3.182  }
   3.183  
   3.184  
   3.185 +bool last_input_page (void)
   3.186 +{
   3.187 +  switch (in_type)
   3.188 +    {
   3.189 +    case INPUT_FILE_TYPE_TIFF:
   3.190 +      return (last_tiff_input_page ());
   3.191 +    case INPUT_FILE_TYPE_JPEG:
   3.192 +      return (last_jpeg_input_page ());
   3.193 +    default:
   3.194 +      fatal (3, "internal error: bad input file type\n");
   3.195 +    }
   3.196 +}
   3.197 +
   3.198 +
   3.199  bool close_pdf_output_files (void)
   3.200  {
   3.201    output_file_t *o, *n;
   3.202 @@ -271,12 +381,6 @@
   3.203  #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
   3.204  
   3.205  
   3.206 -bool last_tiff_page (void)
   3.207 -{
   3.208 -  return (TIFFLastDirectory (in));
   3.209 -}
   3.210 -
   3.211 -
   3.212  static pdf_page_handle process_tiff_page (int image,  /* range 1 .. n */
   3.213  					  input_attributes_t input_attributes)
   3.214  {
   3.215 @@ -304,50 +408,50 @@
   3.216  
   3.217    pdf_page_handle page = NULL;
   3.218  
   3.219 -  if (! TIFFSetDirectory (in, image - 1))
   3.220 +  if (! TIFFSetDirectory (tiff_in, image - 1))
   3.221      {
   3.222        fprintf (stderr, "can't find page %d of input file\n", image);
   3.223        goto fail;
   3.224      }
   3.225 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGELENGTH, & image_length))
   3.226 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_length))
   3.227      {
   3.228        fprintf (stderr, "can't get image length\n");
   3.229        goto fail;
   3.230      }
   3.231 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGEWIDTH, & image_width))
   3.232 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width))
   3.233      {
   3.234        fprintf (stderr, "can't get image width\n");
   3.235        goto fail;
   3.236      }
   3.237  
   3.238 -  if (1 != TIFFGetField (in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   3.239 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   3.240      {
   3.241        fprintf (stderr, "can't get samples per pixel\n");
   3.242        goto fail;
   3.243      }
   3.244  
   3.245  #ifdef CHECK_DEPTH
   3.246 -  if (1 != TIFFGetField (in, TIFFTAG_IMAGEDEPTH, & image_depth))
   3.247 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth))
   3.248      {
   3.249        fprintf (stderr, "can't get image depth\n");
   3.250        goto fail;
   3.251      }
   3.252  #endif
   3.253  
   3.254 -  if (1 != TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   3.255 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   3.256      {
   3.257        fprintf (stderr, "can't get bits per sample\n");
   3.258        goto fail;
   3.259      }
   3.260  
   3.261 -  if (1 != TIFFGetField (in, TIFFTAG_PLANARCONFIG, & planar_config))
   3.262 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config))
   3.263      planar_config = 1;
   3.264  
   3.265 -  if (1 != TIFFGetField (in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   3.266 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   3.267      resolution_unit = 2;
   3.268 -  if (1 != TIFFGetField (in, TIFFTAG_XRESOLUTION, & x_resolution))
   3.269 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution))
   3.270      x_resolution = 300;
   3.271 -  if (1 != TIFFGetField (in, TIFFTAG_YRESOLUTION, & y_resolution))
   3.272 +  if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution))
   3.273      y_resolution = 300;
   3.274  
   3.275    if (samples_per_pixel != 1)
   3.276 @@ -412,7 +516,7 @@
   3.277      }
   3.278  
   3.279    for (row = 0; row < image_length; row++)
   3.280 -    if (1 != TIFFReadScanline (in,
   3.281 +    if (1 != TIFFReadScanline (tiff_in,
   3.282  			       bitmap->bits + row * bitmap->row_words,
   3.283  			       row,
   3.284  			       0))
   3.285 @@ -472,27 +576,26 @@
   3.286  }
   3.287  
   3.288  
   3.289 -#if 0
   3.290  pdf_page_handle process_jpeg_page (int image,  /* range 1 .. n */
   3.291  				   input_attributes_t input_attributes)
   3.292  {
   3.293 -  FILE *f;
   3.294    pdf_page_handle page;
   3.295 +  double width_points, height_points;  /* really 1/72 inch units rather than
   3.296 +					  points */
   3.297  
   3.298 -  f = fopen (filename, "rb");
   3.299 -  if (! f)
   3.300 -    fatal ("error opening input file '%s'\n", filename);
   3.301 +  /* $$$ need to get these from somewhere else, hardcoded for now */
   3.302 +  width_points = 4 * 72.0;
   3.303 +  height_points = 4 * 72.0;
   3.304  
   3.305    page = pdf_new_page (out->pdf, width_points, height_points);
   3.306  
   3.307    pdf_write_jpeg_image (page,
   3.308  			0, 0,  /* x, y */
   3.309  			width_points, height_points,
   3.310 -			f);
   3.311 +			in);
   3.312  
   3.313    return (page);
   3.314  }
   3.315 -#endif
   3.316  
   3.317  
   3.318  bool process_page (int image,  /* range 1 .. n */
   3.319 @@ -502,7 +605,17 @@
   3.320  {
   3.321    pdf_page_handle page;
   3.322  
   3.323 -  page = process_tiff_page (image, input_attributes);
   3.324 +  switch (in_type)
   3.325 +    {
   3.326 +    case INPUT_FILE_TYPE_TIFF:
   3.327 +      page = process_tiff_page (image, input_attributes);
   3.328 +      break;
   3.329 +    case INPUT_FILE_TYPE_JPEG:
   3.330 +      page = process_jpeg_page (image, input_attributes);
   3.331 +      break;
   3.332 +    default:
   3.333 +      fatal (3, "internal error: bad input file type\n");
   3.334 +    }
   3.335  
   3.336    while (bookmarks)
   3.337      {
   3.338 @@ -608,7 +721,7 @@
   3.339      fatal (3, "error opening output file \"%s\"\n", out_fn);
   3.340    for (i = 0; i < inf_count; i++)
   3.341      {
   3.342 -      if (! open_tiff_input_file (in_fn [i]))
   3.343 +      if (! open_input_file (in_fn [i]))
   3.344  	fatal (3, "error opening input file \"%s\"\n", in_fn [i]);
   3.345        for (ip = 1;; ip++)
   3.346  	{
   3.347 @@ -622,12 +735,12 @@
   3.348  			      bookmark_fmt ? & bookmark : NULL,
   3.349  			      NULL))
   3.350  	    fatal (3, "error processing page %d of input file \"%s\"\n", ip, in_fn [i]);
   3.351 -	  if (last_tiff_page ())
   3.352 +	  if (last_input_page ())
   3.353  	    break;
   3.354  	}
   3.355        if (verbose)
   3.356  	fprintf (stderr, "processed %d pages of input file \"%s\"\n", ip, in_fn [i]);
   3.357 -      if (! close_tiff_input_file ())
   3.358 +      if (! close_input_file ())
   3.359  	fatal (3, "error closing input file \"%s\"\n", in_fn [i]);
   3.360      }
   3.361    if (! close_pdf_output_files ())
   3.362 @@ -719,7 +832,7 @@
   3.363    else
   3.364      main_args (out_fn, inf_count, in_fn, bookmark_fmt);
   3.365    
   3.366 -  close_tiff_input_file ();
   3.367 +  close_input_file ();
   3.368    close_pdf_output_files ();
   3.369    exit (0);
   3.370  }
     4.1 diff -r 692e6411df52 -r ec2a06d8a2a6 tumble.h
     4.2 --- a/tumble.h	Sun Mar 16 15:40:00 2003 +0000
     4.3 +++ b/tumble.h	Wed Mar 19 15:39:55 2003 +0000
     4.4 @@ -1,7 +1,7 @@
     4.5  /*
     4.6   * tumble: build a PDF file from image files
     4.7   *
     4.8 - * $Id: tumble.h,v 1.15 2003/03/14 00:57:40 eric Exp $
     4.9 + * $Id: tumble.h,v 1.16 2003/03/19 07:39:55 eric Exp $
    4.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    4.11   *
    4.12   * This program is free software; you can redistribute it and/or modify
    4.13 @@ -39,8 +39,9 @@
    4.14    crop_t crop;
    4.15  } input_attributes_t;
    4.16  
    4.17 -bool open_tiff_input_file (char *name);
    4.18 -bool close_tiff_input_file (void);
    4.19 +
    4.20 +bool open_input_file (char *name);
    4.21 +bool close_input_file (void);
    4.22  
    4.23  
    4.24  typedef struct