Wed, 19 Mar 2003 15:39:55 +0000
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