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