Thu, 20 Mar 2003 06:54:08 +0000
more JPEG support. added input file handler API.
Makefile | file | annotate | diff | revisions | |
README | file | annotate | diff | revisions | |
pdf.h | file | annotate | diff | revisions | |
tumble.c | file | annotate | diff | revisions | |
tumble.h | file | annotate | diff | revisions | |
tumble_input.c | file | annotate | diff | revisions | |
tumble_input.h | file | annotate | diff | revisions | |
tumble_jpeg.c | file | annotate | diff | revisions | |
tumble_tiff.c | file | annotate | diff | revisions |
1.1 diff -r 3fe049d83e22 -r 752599b50ff3 Makefile 1.2 --- a/Makefile Thu Mar 20 01:08:05 2003 +0000 1.3 +++ b/Makefile Thu Mar 20 06:54:08 2003 +0000 1.4 @@ -1,6 +1,6 @@ 1.5 # tumble: build a PDF file from image files 1.6 # Makefile 1.7 -# $Id: Makefile,v 1.34 2003/03/16 07:40:00 eric Exp $ 1.8 +# $Id: Makefile,v 1.35 2003/03/19 22:54:07 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 @@ -23,7 +23,7 @@ 1.13 # "0" value is considered true by make, so to disable conditionals comment 1.14 # them out or set them to a null string. 1.15 1.16 -#DEBUG=1 1.17 +DEBUG=1 1.18 #EFENCE=1 1.19 #STATIC=1 1.20 1.21 @@ -57,19 +57,20 @@ 1.22 # let me know why so I can improve this Makefile. 1.23 # ----------------------------------------------------------------------------- 1.24 1.25 -VERSION = 0.28 1.26 +VERSION = 0.29 1.27 1.28 PACKAGE = tumble 1.29 1.30 TARGETS = tumble 1.31 1.32 CSRCS = tumble.c semantics.c \ 1.33 + tumble_input.c tumble_tiff.c tumble_jpeg.c \ 1.34 bitblt.c bitblt_table_gen.c bitblt_g4.c g4_table_gen.c \ 1.35 pdf.c pdf_util.c pdf_prim.c pdf_name_tree.c \ 1.36 pdf_bookmark.c pdf_page_label.c \ 1.37 pdf_text.c pdf_g4.c pdf_jpeg.c 1.38 OSRCS = scanner.l parser.y 1.39 -HDRS = tumble.h semantics.h bitblt.h bitblt_tables.h \ 1.40 +HDRS = tumble.h tumble_input.h semantics.h bitblt.h bitblt_tables.h \ 1.41 pdf.h pdf_private.h pdf_util.h pdf_prim.h pdf_name_tree.h 1.42 MISC = COPYING README INSTALL Makefile 1.43 1.44 @@ -90,7 +91,9 @@ 1.45 all: $(TARGETS) $(TEST_TARGETS) 1.46 1.47 1.48 -tumble: tumble.o scanner.o semantics.o parser.tab.o \ 1.49 +tumble: tumble.o semantics.o \ 1.50 + tumble_input.o tumble_tiff.o tumble_jpeg.o \ 1.51 + scanner.o parser.tab.o \ 1.52 bitblt.o bitblt_g4.o bitblt_tables.o g4_tables.o \ 1.53 pdf.o pdf_util.o pdf_prim.o pdf_name_tree.o \ 1.54 pdf_bookmark.o pdf_page_label.o \
2.1 diff -r 3fe049d83e22 -r 752599b50ff3 README 2.2 --- a/README Thu Mar 20 01:08:05 2003 +0000 2.3 +++ b/README Thu Mar 20 06:54:08 2003 +0000 2.4 @@ -1,15 +1,14 @@ 2.5 tumble: build a PDF file from image files 2.6 Copyright 2003 Eric Smith <eric@brouhaha.com> 2.7 -$Id: README,v 1.1 2003/03/16 07:37:16 eric Exp $ 2.8 +$Id: README,v 1.2 2003/03/19 22:54:07 eric Exp $ 2.9 2.10 Tumble is a utility to construct PDF files from one or more image 2.11 -files. Currently the only input image format supported is black & 2.12 -white TIFF files, which may be either single- or multi-page files. In 2.13 -the future additional file formats will be supported, including gray 2.14 -scale and color. Black and white images will be encoded in the PDF 2.15 -output using lossless Group 4 fax compression (ITU-T recommendation 2.16 -T.6). This provides a very good compression ratio for text and line 2.17 -art. 2.18 +files. Supported input image file formats are JPEG, and black and 2.19 +white TIFF (single- or multi-page). Black and white images will be 2.20 +encoded in the PDF output using lossless Group 4 fax compression 2.21 +(ITU-T recommendation T.6). This provides a very good compression 2.22 +ratio for text and line art. JPEG images will be preserved with the 2.23 +original coding. 2.24 2.25 The current version of Tumble will only work on little-endian systems, 2.26 such as x86, VAX, and Alpha. The byte order dependencies will be fixed 2.27 @@ -21,7 +20,7 @@ 2.28 2.29 The general command line syntax is: 2.30 2.31 - tumble [options] <input.tif>... -o <output.pdf> 2.32 + tumble [options] <input>... -o <output.pdf> 2.33 2.34 The options in this mode are: 2.35
3.1 diff -r 3fe049d83e22 -r 752599b50ff3 pdf.h 3.2 --- a/pdf.h Thu Mar 20 01:08:05 2003 +0000 3.3 +++ b/pdf.h Thu Mar 20 06:54:08 2003 +0000 3.4 @@ -2,7 +2,7 @@ 3.5 * tumble: build a PDF file from image files 3.6 * 3.7 * PDF routines 3.8 - * $Id: pdf.h,v 1.11 2003/03/14 00:57:40 eric Exp $ 3.9 + * $Id: pdf.h,v 1.12 2003/03/19 22:54:07 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 @@ -22,6 +22,13 @@ 3.14 */ 3.15 3.16 3.17 +#define POINTS_PER_INCH 72 3.18 + 3.19 +/* page size limited by Acrobat Reader to 45 inches on a side */ 3.20 +#define PAGE_MAX_INCHES 45 3.21 +#define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH) 3.22 + 3.23 + 3.24 typedef struct pdf_file *pdf_file_handle; 3.25 3.26 typedef struct pdf_page *pdf_page_handle;
4.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble.c 4.2 --- a/tumble.c Thu Mar 20 01:08:05 2003 +0000 4.3 +++ b/tumble.c Thu Mar 20 06:54:08 2003 +0000 4.4 @@ -2,7 +2,7 @@ 4.5 * tumble: build a PDF file from image files 4.6 * 4.7 * Main program 4.8 - * $Id: tumble.c,v 1.37 2003/03/19 07:39:55 eric Exp $ 4.9 + * $Id: tumble.c,v 1.38 2003/03/19 22:54:07 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 @@ -30,25 +30,17 @@ 4.14 #include <string.h> 4.15 #include <unistd.h> 4.16 4.17 -#include <tiffio.h> 4.18 -#define TIFF_REVERSE_BITS 4.19 4.20 -#include "bitblt.h" 4.21 #include "semantics.h" 4.22 #include "parser.tab.h" 4.23 #include "tumble.h" 4.24 +#include "bitblt.h" 4.25 #include "pdf.h" 4.26 +#include "tumble_input.h" 4.27 4.28 4.29 #define MAX_INPUT_FILES 5000 4.30 4.31 -#define POINTS_PER_INCH 72 4.32 - 4.33 -/* page size limited by Acrobat Reader to 45 inches on a side */ 4.34 -#define PAGE_MAX_INCHES 45 4.35 -#define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH) 4.36 - 4.37 - 4.38 typedef struct output_file_t 4.39 { 4.40 struct output_file_t *next; 4.41 @@ -60,18 +52,6 @@ 4.42 int verbose; 4.43 4.44 4.45 -typedef enum 4.46 - { 4.47 - INPUT_FILE_TYPE_NONE, 4.48 - INPUT_FILE_TYPE_TIFF, 4.49 - INPUT_FILE_TYPE_JPEG 4.50 - } input_file_type_t; 4.51 - 4.52 - 4.53 -char *in_filename; 4.54 -input_file_type_t in_type; 4.55 -FILE *in; 4.56 -TIFF *tiff_in; 4.57 output_file_t *output_files; 4.58 output_file_t *out; 4.59 4.60 @@ -79,7 +59,6 @@ 4.61 char *progname; 4.62 4.63 4.64 -bool close_tiff_input_file (void); 4.65 bool close_pdf_output_files (void); 4.66 4.67 4.68 @@ -126,142 +105,6 @@ 4.69 } 4.70 4.71 4.72 -bool close_tiff_input_file (void) 4.73 -{ 4.74 - TIFFClose (tiff_in); 4.75 - return (1); 4.76 -} 4.77 - 4.78 - 4.79 -bool open_tiff_input_file (FILE *f, char *name) 4.80 -{ 4.81 - tiff_in = TIFFFdOpen (fileno (f), name, "r"); 4.82 - if (! tiff_in) 4.83 - { 4.84 - fprintf (stderr, "can't open input file '%s'\n", name); 4.85 - free (in_filename); 4.86 - return (0); 4.87 - } 4.88 - in_type = INPUT_FILE_TYPE_TIFF; 4.89 - return (1); 4.90 -} 4.91 - 4.92 - 4.93 -bool close_jpeg_input_file (void) 4.94 -{ 4.95 - return (1); 4.96 -} 4.97 - 4.98 - 4.99 -bool open_jpeg_input_file (FILE *f, char *name) 4.100 -{ 4.101 - in_type = INPUT_FILE_TYPE_JPEG; 4.102 - return (1); 4.103 -} 4.104 - 4.105 - 4.106 -bool open_input_file (char *name) 4.107 -{ 4.108 - bool result; 4.109 - uint8_t buf [2]; 4.110 - size_t l; 4.111 - 4.112 - if (in) 4.113 - { 4.114 - if (strcmp (name, in_filename) == 0) 4.115 - return (1); 4.116 - close_input_file (); 4.117 - } 4.118 - in_filename = strdup (name); 4.119 - if (! in_filename) 4.120 - { 4.121 - fprintf (stderr, "can't strdup input filename '%s'\n", name); 4.122 - return (0); 4.123 - } 4.124 - 4.125 - in = fopen (name, "rb"); 4.126 - if (! in) 4.127 - return (0); 4.128 - 4.129 - l = fread (& buf [0], 1, sizeof (buf), in); 4.130 - if (l != sizeof (buf)) 4.131 - return (0); 4.132 - 4.133 - rewind (in); 4.134 - 4.135 - if ((buf [0] == 0x49) && (buf [1] == 0x49)) 4.136 - result = open_tiff_input_file (in, name); 4.137 - else if ((buf [0] == 0xff) && (buf [1] == 0xd8)) 4.138 - result = open_jpeg_input_file (in, name); 4.139 - else 4.140 - { 4.141 - fprintf (stderr, "unrecognized file header in file '%s'\n", name); 4.142 - result = 0; 4.143 - } 4.144 - if (! result) 4.145 - { 4.146 - if (in) 4.147 - fclose (in); 4.148 - in = NULL; 4.149 - in_type = INPUT_FILE_TYPE_NONE; 4.150 - } 4.151 - return (result); 4.152 -} 4.153 - 4.154 - 4.155 -bool close_input_file (void) 4.156 -{ 4.157 - bool result; 4.158 - 4.159 - switch (in_type) 4.160 - { 4.161 - case INPUT_FILE_TYPE_NONE: 4.162 - return (1); 4.163 - case INPUT_FILE_TYPE_TIFF: 4.164 - result = close_tiff_input_file (); 4.165 - break; 4.166 - case INPUT_FILE_TYPE_JPEG: 4.167 - result = close_jpeg_input_file (); 4.168 - break; 4.169 - default: 4.170 - fatal (3, "internal error: bad input file type\n"); 4.171 - } 4.172 - 4.173 - if (in_filename) 4.174 - free (in_filename); 4.175 - fclose (in); 4.176 - in = NULL; 4.177 - 4.178 - return (result); 4.179 -} 4.180 - 4.181 - 4.182 -bool last_tiff_input_page (void) 4.183 -{ 4.184 - return (TIFFLastDirectory (tiff_in)); 4.185 -} 4.186 - 4.187 - 4.188 -bool last_jpeg_input_page (void) 4.189 -{ 4.190 - return (1); 4.191 -} 4.192 - 4.193 - 4.194 -bool last_input_page (void) 4.195 -{ 4.196 - switch (in_type) 4.197 - { 4.198 - case INPUT_FILE_TYPE_TIFF: 4.199 - return (last_tiff_input_page ()); 4.200 - case INPUT_FILE_TYPE_JPEG: 4.201 - return (last_jpeg_input_page ()); 4.202 - default: 4.203 - fatal (3, "internal error: bad input file type\n"); 4.204 - } 4.205 -} 4.206 - 4.207 - 4.208 bool close_pdf_output_files (void) 4.209 { 4.210 output_file_t *o, *n; 4.211 @@ -335,287 +178,23 @@ 4.212 } 4.213 4.214 4.215 -/* frees original! */ 4.216 -static Bitmap *resize_bitmap (Bitmap *src, 4.217 - double x_resolution, 4.218 - double y_resolution, 4.219 - input_attributes_t input_attributes) 4.220 -{ 4.221 - Rect src_rect; 4.222 - Point dest_min; 4.223 - Bitmap *dest; 4.224 - 4.225 - int width_pixels = input_attributes.page_size.width * x_resolution; 4.226 - int height_pixels = input_attributes.page_size.height * y_resolution; 4.227 - 4.228 - src_rect.min.x = (rect_width (& src->rect) - width_pixels) / 2; 4.229 - src_rect.min.y = (rect_height (& src->rect) - height_pixels) / 2; 4.230 - src_rect.max.x = src_rect.min.x + width_pixels; 4.231 - src_rect.max.y = src_rect.min.y + height_pixels; 4.232 - 4.233 - dest_min.x = 0; 4.234 - dest_min.y = 0; 4.235 - 4.236 - dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0); 4.237 - free_bitmap (src); 4.238 - return (dest); 4.239 -} 4.240 - 4.241 - 4.242 -/* "in place" rotation */ 4.243 -static void rotate_bitmap (Bitmap *src, 4.244 - input_attributes_t input_attributes) 4.245 -{ 4.246 - switch (input_attributes.rotation) 4.247 - { 4.248 - case 0: break; 4.249 - case 90: rot_90 (src); break; 4.250 - case 180: rot_180 (src); break; 4.251 - case 270: rot_270 (src); break; 4.252 - default: 4.253 - fprintf (stderr, "rotation must be 0, 90, 180, or 270\n"); 4.254 - } 4.255 -} 4.256 - 4.257 - 4.258 -#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 4.259 - 4.260 - 4.261 -static pdf_page_handle process_tiff_page (int image, /* range 1 .. n */ 4.262 - input_attributes_t input_attributes) 4.263 -{ 4.264 - uint32_t image_length, image_width; 4.265 - uint32_t dest_image_length, dest_image_width; 4.266 -#ifdef CHECK_DEPTH 4.267 - uint32_t image_depth; 4.268 -#endif 4.269 - 4.270 - uint16_t samples_per_pixel; 4.271 - uint16_t bits_per_sample; 4.272 - uint16_t planar_config; 4.273 - 4.274 - uint16_t resolution_unit; 4.275 - float x_resolution, y_resolution; 4.276 - double dest_x_resolution, dest_y_resolution; 4.277 - 4.278 - double width_points, height_points; /* really 1/72 inch units rather than 4.279 - points */ 4.280 - 4.281 - Rect rect; 4.282 - Bitmap *bitmap = NULL; 4.283 - 4.284 - int row; 4.285 - 4.286 - pdf_page_handle page = NULL; 4.287 - 4.288 - if (! TIFFSetDirectory (tiff_in, image - 1)) 4.289 - { 4.290 - fprintf (stderr, "can't find page %d of input file\n", image); 4.291 - goto fail; 4.292 - } 4.293 - if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_length)) 4.294 - { 4.295 - fprintf (stderr, "can't get image length\n"); 4.296 - goto fail; 4.297 - } 4.298 - if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width)) 4.299 - { 4.300 - fprintf (stderr, "can't get image width\n"); 4.301 - goto fail; 4.302 - } 4.303 - 4.304 - if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel)) 4.305 - { 4.306 - fprintf (stderr, "can't get samples per pixel\n"); 4.307 - goto fail; 4.308 - } 4.309 - 4.310 -#ifdef CHECK_DEPTH 4.311 - if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth)) 4.312 - { 4.313 - fprintf (stderr, "can't get image depth\n"); 4.314 - goto fail; 4.315 - } 4.316 -#endif 4.317 - 4.318 - if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample)) 4.319 - { 4.320 - fprintf (stderr, "can't get bits per sample\n"); 4.321 - goto fail; 4.322 - } 4.323 - 4.324 - if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config)) 4.325 - planar_config = 1; 4.326 - 4.327 - if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit)) 4.328 - resolution_unit = 2; 4.329 - if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution)) 4.330 - x_resolution = 300; 4.331 - if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution)) 4.332 - y_resolution = 300; 4.333 - 4.334 - if (samples_per_pixel != 1) 4.335 - { 4.336 - fprintf (stderr, "samples per pixel %u, must be 1\n", samples_per_pixel); 4.337 - goto fail; 4.338 - } 4.339 - 4.340 -#ifdef CHECK_DEPTH 4.341 - if (image_depth != 1) 4.342 - { 4.343 - fprintf (stderr, "image depth %u, must be 1\n", image_depth); 4.344 - goto fail; 4.345 - } 4.346 -#endif 4.347 - 4.348 - if (bits_per_sample != 1) 4.349 - { 4.350 - fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample); 4.351 - goto fail; 4.352 - } 4.353 - 4.354 - if (planar_config != 1) 4.355 - { 4.356 - fprintf (stderr, "planar config %u, must be 1\n", planar_config); 4.357 - goto fail; 4.358 - } 4.359 - 4.360 - if (input_attributes.has_resolution) 4.361 - { 4.362 - x_resolution = input_attributes.x_resolution; 4.363 - y_resolution = input_attributes.y_resolution; 4.364 - } 4.365 - 4.366 - if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270)) 4.367 - { 4.368 - dest_image_width = image_length; 4.369 - dest_image_length = image_width; 4.370 - dest_x_resolution = y_resolution; 4.371 - dest_y_resolution = x_resolution; 4.372 - SWAP (double, width_points, height_points); /* $$$ not yet set!!! */ 4.373 - } 4.374 - else 4.375 - { 4.376 - dest_image_width = image_width; 4.377 - dest_image_length = image_length; 4.378 - dest_x_resolution = x_resolution; 4.379 - dest_y_resolution = y_resolution; 4.380 - } 4.381 - 4.382 - rect.min.x = 0; 4.383 - rect.min.y = 0; 4.384 - rect.max.x = image_width; 4.385 - rect.max.y = image_length; 4.386 - 4.387 - bitmap = create_bitmap (& rect); 4.388 - 4.389 - if (! bitmap) 4.390 - { 4.391 - fprintf (stderr, "can't allocate bitmap\n"); 4.392 - goto fail; 4.393 - } 4.394 - 4.395 - for (row = 0; row < image_length; row++) 4.396 - if (1 != TIFFReadScanline (tiff_in, 4.397 - bitmap->bits + row * bitmap->row_words, 4.398 - row, 4.399 - 0)) 4.400 - { 4.401 - fprintf (stderr, "can't read TIFF scanline\n"); 4.402 - goto fail; 4.403 - } 4.404 - 4.405 -#ifdef TIFF_REVERSE_BITS 4.406 - reverse_bits ((uint8_t *) bitmap->bits, 4.407 - image_length * bitmap->row_words * sizeof (word_t)); 4.408 -#endif /* TIFF_REVERSE_BITS */ 4.409 - 4.410 -#if 0 4.411 - if (input_attributes.has_page_size) 4.412 - bitmap = resize_bitmap (bitmap, 4.413 - x_resolution, 4.414 - y_resolution, 4.415 - input_attributes); 4.416 -#endif 4.417 - 4.418 - rotate_bitmap (bitmap, 4.419 - input_attributes); 4.420 - 4.421 - width_points = (rect_width (& bitmap->rect) / dest_x_resolution) * POINTS_PER_INCH; 4.422 - height_points = (rect_height (& bitmap->rect) / dest_y_resolution) * POINTS_PER_INCH; 4.423 - 4.424 - if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS)) 4.425 - { 4.426 - fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES); 4.427 - goto fail; 4.428 - } 4.429 - 4.430 - page = pdf_new_page (out->pdf, width_points, height_points); 4.431 - 4.432 -#if 0 4.433 - pdf_write_text (page); 4.434 -#else 4.435 - pdf_write_g4_fax_image (page, 4.436 - 0, 0, /* x, y */ 4.437 - width_points, height_points, 4.438 - bitmap, 4.439 - 0, /* ImageMask */ 4.440 - 0, 0, 0, /* r, g, b */ 4.441 - 0); /* BlackIs1 */ 4.442 -#endif 4.443 - 4.444 - if (bitmap) 4.445 - free_bitmap (bitmap); 4.446 - return (page); 4.447 - 4.448 - fail: 4.449 - if (bitmap) 4.450 - free_bitmap (bitmap); 4.451 - 4.452 - return (NULL); 4.453 -} 4.454 - 4.455 - 4.456 -pdf_page_handle process_jpeg_page (int image, /* range 1 .. n */ 4.457 - input_attributes_t input_attributes) 4.458 -{ 4.459 - pdf_page_handle page; 4.460 - double width_points, height_points; /* really 1/72 inch units rather than 4.461 - points */ 4.462 - 4.463 - /* $$$ need to get these from somewhere else, hardcoded for now */ 4.464 - width_points = 4 * 72.0; 4.465 - height_points = 4 * 72.0; 4.466 - 4.467 - page = pdf_new_page (out->pdf, width_points, height_points); 4.468 - 4.469 - pdf_write_jpeg_image (page, 4.470 - 0, 0, /* x, y */ 4.471 - width_points, height_points, 4.472 - in); 4.473 - 4.474 - return (page); 4.475 -} 4.476 - 4.477 - 4.478 bool process_page (int image, /* range 1 .. n */ 4.479 input_attributes_t input_attributes, 4.480 bookmark_t *bookmarks, 4.481 page_label_t *page_label) 4.482 { 4.483 pdf_page_handle page; 4.484 + image_info_t image_info; 4.485 + 4.486 + if (! get_image_info (image, input_attributes, & image_info)) 4.487 + return (0); 4.488 4.489 - switch (in_type) 4.490 - { 4.491 - case INPUT_FILE_TYPE_TIFF: 4.492 - page = process_tiff_page (image, input_attributes); 4.493 - break; 4.494 - case INPUT_FILE_TYPE_JPEG: 4.495 - page = process_jpeg_page (image, input_attributes); 4.496 - break; 4.497 - default: 4.498 - fatal (3, "internal error: bad input file type\n"); 4.499 - } 4.500 + page = pdf_new_page (out->pdf, 4.501 + image_info.width_points, 4.502 + image_info.height_points); 4.503 + 4.504 + if (! process_image (image, input_attributes, & image_info, page)) 4.505 + return (0); 4.506 4.507 while (bookmarks) 4.508 { 4.509 @@ -769,6 +348,9 @@ 4.510 4.511 pdf_init (); 4.512 4.513 + init_tiff_handler (); 4.514 + init_jpeg_handler (); 4.515 + 4.516 while (--argc) 4.517 { 4.518 if (argv [1][0] == '-')
5.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble.h 5.2 --- a/tumble.h Thu Mar 20 01:08:05 2003 +0000 5.3 +++ b/tumble.h Thu Mar 20 06:54:08 2003 +0000 5.4 @@ -1,7 +1,7 @@ 5.5 /* 5.6 * tumble: build a PDF file from image files 5.7 * 5.8 - * $Id: tumble.h,v 1.16 2003/03/19 07:39:55 eric Exp $ 5.9 + * $Id: tumble.h,v 1.17 2003/03/19 22:54:07 eric Exp $ 5.10 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 5.11 * 5.12 * This program is free software; you can redistribute it and/or modify 5.13 @@ -17,7 +17,8 @@ 5.14 * 5.15 * You should have received a copy of the GNU General Public License 5.16 * along with this program; if not, write to the Free Software 5.17 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA */ 5.18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 5.19 + */ 5.20 5.21 5.22 extern int verbose;
6.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble_input.c 6.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 +++ b/tumble_input.c Thu Mar 20 06:54:08 2003 +0000 6.4 @@ -0,0 +1,140 @@ 6.5 +/* 6.6 + * tumble: build a PDF file from image files 6.7 + * 6.8 + * Input handler dispatch 6.9 + * $Id: tumble_input.c,v 1.1 2003/03/19 22:54:08 eric Exp $ 6.10 + * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 6.11 + * 6.12 + * This program is free software; you can redistribute it and/or modify 6.13 + * it under the terms of the GNU General Public License version 2 as 6.14 + * published by the Free Software Foundation. Note that permission is 6.15 + * not granted to redistribute this program under the terms of any 6.16 + * other version of the General Public License. 6.17 + * 6.18 + * This program is distributed in the hope that it will be useful, 6.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.21 + * GNU General Public License for more details. 6.22 + * 6.23 + * You should have received a copy of the GNU General Public License 6.24 + * along with this program; if not, write to the Free Software 6.25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 6.26 + */ 6.27 + 6.28 + 6.29 +#include <stdbool.h> 6.30 +#include <stdint.h> 6.31 +#include <stdio.h> 6.32 +#include <stdlib.h> 6.33 +#include <string.h> 6.34 + 6.35 + 6.36 +#include "semantics.h" 6.37 +#include "tumble.h" 6.38 +#include "bitblt.h" 6.39 +#include "pdf.h" 6.40 +#include "tumble_input.h" 6.41 + 6.42 + 6.43 +#define MAX_INPUT_HANDLERS 10 6.44 + 6.45 +static int input_handler_count = 0; 6.46 + 6.47 +static input_handler_t *input_handlers [MAX_INPUT_HANDLERS]; 6.48 + 6.49 + 6.50 +static char *in_filename; 6.51 +static FILE *in; 6.52 +static input_handler_t *current_input_handler; 6.53 + 6.54 + 6.55 +void install_input_handler (input_handler_t *handler) 6.56 +{ 6.57 + if (input_handler_count >= MAX_INPUT_HANDLERS) 6.58 + fprintf (stderr, "Too many input handlers, table only has room for %d\n", MAX_INPUT_HANDLERS); 6.59 + else 6.60 + input_handlers [input_handler_count++] = handler; 6.61 +} 6.62 + 6.63 + 6.64 +bool open_input_file (char *name) 6.65 +{ 6.66 + int i; 6.67 + 6.68 + if (in) 6.69 + { 6.70 + if (strcmp (name, in_filename) == 0) 6.71 + return (1); 6.72 + close_input_file (); 6.73 + } 6.74 + in_filename = strdup (name); 6.75 + if (! in_filename) 6.76 + { 6.77 + fprintf (stderr, "can't strdup input filename '%s'\n", name); 6.78 + goto fail; 6.79 + } 6.80 + 6.81 + in = fopen (name, "rb"); 6.82 + if (! in) 6.83 + goto fail; 6.84 + 6.85 + for (i = 0; i < input_handler_count; i++) 6.86 + { 6.87 + if (input_handlers [i]->open_input_file (in, name)) 6.88 + break; 6.89 + } 6.90 + if (i >= input_handler_count) 6.91 + { 6.92 + fprintf (stderr, "unrecognized format for input file '%s'\n", name); 6.93 + goto fail; 6.94 + } 6.95 + current_input_handler = input_handlers [i]; 6.96 + return (1); 6.97 + 6.98 + fail: 6.99 + if (in) 6.100 + fclose (in); 6.101 + in = NULL; 6.102 + return (0); 6.103 +} 6.104 + 6.105 + 6.106 +bool close_input_file (void) 6.107 +{ 6.108 + bool result; 6.109 + 6.110 + result = current_input_handler->close_input_file (); 6.111 + if (in_filename) 6.112 + free (in_filename); 6.113 + fclose (in); 6.114 + in = NULL; 6.115 + 6.116 + return (result); 6.117 +} 6.118 + 6.119 + 6.120 +bool last_input_page (void) 6.121 +{ 6.122 + return (current_input_handler->last_input_page ()); 6.123 +} 6.124 + 6.125 + 6.126 +bool get_image_info (int image, 6.127 + input_attributes_t input_attributes, 6.128 + image_info_t *image_info) 6.129 +{ 6.130 + return (current_input_handler->get_image_info (image, 6.131 + input_attributes, 6.132 + image_info)); 6.133 +} 6.134 + 6.135 +bool process_image (int image, 6.136 + input_attributes_t input_attributes, 6.137 + image_info_t *image_info, 6.138 + pdf_page_handle page) 6.139 +{ 6.140 + return (current_input_handler->process_image (image, 6.141 + input_attributes, 6.142 + image_info, 6.143 + page)); 6.144 +}
7.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble_input.h 7.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 +++ b/tumble_input.h Thu Mar 20 06:54:08 2003 +0000 7.4 @@ -0,0 +1,64 @@ 7.5 +/* 7.6 + * tumble: build a PDF file from image files 7.7 + * 7.8 + * $Id: tumble_input.h,v 1.1 2003/03/19 22:54:08 eric Exp $ 7.9 + * Copyright 2003 Eric Smith <eric@brouhaha.com> 7.10 + * 7.11 + * This program is free software; you can redistribute it and/or modify 7.12 + * it under the terms of the GNU General Public License version 2 as 7.13 + * published by the Free Software Foundation. Note that permission is 7.14 + * not granted to redistribute this program under the terms of any 7.15 + * other version of the General Public License. 7.16 + * 7.17 + * This program is distributed in the hope that it will be useful, 7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.20 + * GNU General Public License for more details. 7.21 + * 7.22 + * You should have received a copy of the GNU General Public License 7.23 + * along with this program; if not, write to the Free Software 7.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 7.25 + */ 7.26 + 7.27 + 7.28 +typedef struct 7.29 +{ 7.30 + bool color; 7.31 + uint32_t width_samples, height_samples; 7.32 + double width_points, height_points; 7.33 + double x_resolution, y_resolution; 7.34 +} image_info_t; 7.35 + 7.36 + 7.37 +typedef struct 7.38 +{ 7.39 + bool (*open_input_file) (FILE *f, char *name); 7.40 + bool (*close_input_file) (void); 7.41 + bool (*last_input_page) (void); 7.42 + bool (*get_image_info) (int image, 7.43 + input_attributes_t input_attributes, 7.44 + image_info_t *image_info); 7.45 + bool (*process_image) (int image, 7.46 + input_attributes_t input_attributes, 7.47 + image_info_t *image_info, 7.48 + pdf_page_handle page); 7.49 +} input_handler_t; 7.50 + 7.51 + 7.52 +void install_input_handler (input_handler_t *handler); 7.53 + 7.54 + 7.55 +bool open_input_file (char *name); 7.56 +bool close_input_file (void); 7.57 +bool last_input_page (void); 7.58 +bool get_image_info (int image, 7.59 + input_attributes_t input_attributes, 7.60 + image_info_t *image_info); 7.61 +bool process_image (int image, 7.62 + input_attributes_t input_attributes, 7.63 + image_info_t *image_info, 7.64 + pdf_page_handle page); 7.65 + 7.66 + 7.67 +void init_tiff_handler (void); 7.68 +void init_jpeg_handler (void);
8.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble_jpeg.c 8.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 +++ b/tumble_jpeg.c Thu Mar 20 06:54:08 2003 +0000 8.4 @@ -0,0 +1,176 @@ 8.5 +/* 8.6 + * tumble: build a PDF file from image files 8.7 + * 8.8 + * $Id: tumble_jpeg.c,v 1.1 2003/03/19 22:54:08 eric Exp $ 8.9 + * Copyright 2003 Eric Smith <eric@brouhaha.com> 8.10 + * 8.11 + * This program is free software; you can redistribute it and/or modify 8.12 + * it under the terms of the GNU General Public License version 2 as 8.13 + * published by the Free Software Foundation. Note that permission is 8.14 + * not granted to redistribute this program under the terms of any 8.15 + * other version of the General Public License. 8.16 + * 8.17 + * This program is distributed in the hope that it will be useful, 8.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.20 + * GNU General Public License for more details. 8.21 + * 8.22 + * You should have received a copy of the GNU General Public License 8.23 + * along with this program; if not, write to the Free Software 8.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 8.25 + */ 8.26 + 8.27 + 8.28 +#include <stdbool.h> 8.29 +#include <stdint.h> 8.30 +#include <stdio.h> 8.31 +#include <jpeglib.h> 8.32 + 8.33 + 8.34 +#include "semantics.h" 8.35 +#include "tumble.h" 8.36 +#include "bitblt.h" 8.37 +#include "pdf.h" 8.38 +#include "tumble_input.h" 8.39 + 8.40 + 8.41 +static FILE *jpeg_f; 8.42 + 8.43 +static struct jpeg_decompress_struct cinfo; 8.44 +static struct jpeg_error_mgr jerr; 8.45 + 8.46 + 8.47 +bool close_jpeg_input_file (void) 8.48 +{ 8.49 + return (1); 8.50 +} 8.51 + 8.52 + 8.53 +bool open_jpeg_input_file (FILE *f, char *name) 8.54 +{ 8.55 + uint8_t buf [2]; 8.56 + size_t l; 8.57 + 8.58 + l = fread (& buf [0], 1, sizeof (buf), f); 8.59 + if (l != sizeof (buf)) 8.60 + return (0); 8.61 + 8.62 + rewind (f); 8.63 + 8.64 + if ((buf [0] != 0xff) || (buf [1] != 0xd8)) 8.65 + return (0); 8.66 + 8.67 + cinfo.err = jpeg_std_error (& jerr); 8.68 + jpeg_create_decompress (& cinfo); 8.69 + 8.70 + jpeg_stdio_src (& cinfo, f); 8.71 + 8.72 + jpeg_read_header (& cinfo, TRUE); 8.73 + 8.74 + rewind (f); 8.75 + 8.76 + jpeg_f = f; 8.77 + 8.78 + return (1); 8.79 +} 8.80 + 8.81 + 8.82 +bool last_jpeg_input_page (void) 8.83 +{ 8.84 + return (1); 8.85 +} 8.86 + 8.87 + 8.88 +bool get_jpeg_image_info (int image, 8.89 + input_attributes_t input_attributes, 8.90 + image_info_t *image_info) 8.91 +{ 8.92 + double unit; 8.93 + 8.94 + switch (cinfo.jpeg_color_space) 8.95 + { 8.96 + case JCS_GRAYSCALE: 8.97 + if (cinfo.num_components != 1) 8.98 + { 8.99 + fprintf (stderr, "JPEG grayscale image has %d components, should have 1\n", 8.100 + cinfo.num_components); 8.101 + return (0); 8.102 + } 8.103 + image_info->color = 0; 8.104 + break; 8.105 + case JCS_RGB: 8.106 + case JCS_YCbCr: 8.107 + if (cinfo.num_components != 3) 8.108 + { 8.109 + fprintf (stderr, "JPEG RGB or YCbCr image has %d components, should have 3\n", 8.110 + cinfo.num_components); 8.111 + return (0); 8.112 + } 8.113 + image_info->color = 1; 8.114 + break; 8.115 + default: 8.116 + fprintf (stderr, "JPEG color space %d not supported\n", cinfo.jpeg_color_space); 8.117 + return (0); 8.118 + } 8.119 + image_info->width_samples = cinfo.image_width; 8.120 + image_info->height_samples = cinfo.image_height; 8.121 + 8.122 + if (cinfo.saw_JFIF_marker & cinfo.density_unit) 8.123 + { 8.124 + switch (cinfo.density_unit) 8.125 + { 8.126 + case 1: /* samples per inch */ 8.127 + unit = 1.0; 8.128 + break; 8.129 + case 2: /* samples per cm */ 8.130 + unit = 2.54; 8.131 + break; 8.132 + default: 8.133 + fprintf (stderr, "JFIF density unit %d not supported\n", cinfo.density_unit); 8.134 + return (0); 8.135 + } 8.136 + image_info->width_points = ((image_info->width_samples * POINTS_PER_INCH) / 8.137 + (cinfo.X_density * unit)); 8.138 + image_info->height_points = ((image_info->height_samples * POINTS_PER_INCH) / 8.139 + (cinfo.Y_density * unit)); 8.140 + } 8.141 + else 8.142 + { 8.143 + /* assume 300 DPI - not great, but what else can we do? */ 8.144 + image_info->width_points = (image_info->width_samples * POINTS_PER_INCH) / 300.0; 8.145 + image_info->height_points = (image_info->height_samples * POINTS_PER_INCH) / 300.0; 8.146 + } 8.147 + 8.148 + return (1); 8.149 +} 8.150 + 8.151 + 8.152 +bool process_jpeg_image (int image, /* range 1 .. n */ 8.153 + input_attributes_t input_attributes, 8.154 + image_info_t *image_info, 8.155 + pdf_page_handle page) 8.156 +{ 8.157 + pdf_write_jpeg_image (page, 8.158 + 0, 0, /* x, y */ 8.159 + image_info->width_points, 8.160 + image_info->height_points, 8.161 + jpeg_f); 8.162 + 8.163 + return (page); 8.164 +} 8.165 + 8.166 + 8.167 +input_handler_t jpeg_handler = 8.168 + { 8.169 + open_jpeg_input_file, 8.170 + close_jpeg_input_file, 8.171 + last_jpeg_input_page, 8.172 + get_jpeg_image_info, 8.173 + process_jpeg_image 8.174 + }; 8.175 + 8.176 + 8.177 +void init_jpeg_handler (void) 8.178 +{ 8.179 + install_input_handler (& jpeg_handler); 8.180 +}
9.1 diff -r 3fe049d83e22 -r 752599b50ff3 tumble_tiff.c 9.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 +++ b/tumble_tiff.c Thu Mar 20 06:54:08 2003 +0000 9.4 @@ -0,0 +1,351 @@ 9.5 +/* 9.6 + * tumble: build a PDF file from image files 9.7 + * 9.8 + * $Id: tumble_tiff.c,v 1.1 2003/03/19 22:54:08 eric Exp $ 9.9 + * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 9.10 + * 9.11 + * This program is free software; you can redistribute it and/or modify 9.12 + * it under the terms of the GNU General Public License version 2 as 9.13 + * published by the Free Software Foundation. Note that permission is 9.14 + * not granted to redistribute this program under the terms of any 9.15 + * other version of the General Public License. 9.16 + * 9.17 + * This program is distributed in the hope that it will be useful, 9.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.20 + * GNU General Public License for more details. 9.21 + * 9.22 + * You should have received a copy of the GNU General Public License 9.23 + * along with this program; if not, write to the Free Software 9.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 9.25 + */ 9.26 + 9.27 + 9.28 +#include <stdbool.h> 9.29 +#include <stdint.h> 9.30 +#include <stdio.h> 9.31 +#include <stdlib.h> 9.32 +#include <string.h> 9.33 + 9.34 +#include <tiffio.h> 9.35 +#define TIFF_REVERSE_BITS 9.36 + 9.37 + 9.38 +#include "semantics.h" 9.39 +#include "tumble.h" 9.40 +#include "bitblt.h" 9.41 +#include "pdf.h" 9.42 +#include "tumble_input.h" 9.43 + 9.44 + 9.45 +TIFF *tiff_in; 9.46 + 9.47 + 9.48 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 9.49 + 9.50 + 9.51 +bool close_tiff_input_file (void) 9.52 +{ 9.53 + TIFFClose (tiff_in); 9.54 + return (1); 9.55 +} 9.56 + 9.57 + 9.58 +bool open_tiff_input_file (FILE *f, char *name) 9.59 +{ 9.60 + uint8_t buf [2]; 9.61 + size_t l; 9.62 + 9.63 + l = fread (& buf [0], 1, sizeof (buf), f); 9.64 + if (l != sizeof (buf)) 9.65 + return (0); 9.66 + 9.67 + rewind (f); 9.68 + 9.69 + if ((buf [0] != 0x49) || (buf [1] != 0x49)) 9.70 + return (0); 9.71 + 9.72 + /* $$$ should we dup the file descriptor here, so that later closing f 9.73 + won't cause problems? */ 9.74 + tiff_in = TIFFFdOpen (fileno (f), name, "r"); 9.75 + if (! tiff_in) 9.76 + { 9.77 + fprintf (stderr, "can't open input file '%s'\n", name); 9.78 + return (0); 9.79 + } 9.80 + return (1); 9.81 +} 9.82 + 9.83 + 9.84 +bool last_tiff_input_page (void) 9.85 +{ 9.86 + return (TIFFLastDirectory (tiff_in)); 9.87 +} 9.88 + 9.89 + 9.90 +bool get_tiff_image_info (int image, 9.91 + input_attributes_t input_attributes, 9.92 + image_info_t *image_info) 9.93 +{ 9.94 + uint32_t image_height, image_width; 9.95 + uint16_t samples_per_pixel; 9.96 + uint16_t bits_per_sample; 9.97 + uint16_t planar_config; 9.98 + 9.99 + uint16_t resolution_unit; 9.100 + float x_resolution, y_resolution; 9.101 + 9.102 + double dest_x_resolution, dest_y_resolution; 9.103 + 9.104 +#ifdef CHECK_DEPTH 9.105 + uint32_t image_depth; 9.106 +#endif 9.107 + 9.108 + if (! TIFFSetDirectory (tiff_in, image - 1)) 9.109 + { 9.110 + fprintf (stderr, "can't find page %d of input file\n", image); 9.111 + return (0); 9.112 + } 9.113 + if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_height)) 9.114 + { 9.115 + fprintf (stderr, "can't get image height\n"); 9.116 + return (0); 9.117 + } 9.118 + if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width)) 9.119 + { 9.120 + fprintf (stderr, "can't get image width\n"); 9.121 + return (0); 9.122 + } 9.123 + 9.124 + if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel)) 9.125 + { 9.126 + fprintf (stderr, "can't get samples per pixel\n"); 9.127 + return (0); 9.128 + } 9.129 + 9.130 +#ifdef CHECK_DEPTH 9.131 + if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth)) 9.132 + { 9.133 + fprintf (stderr, "can't get image depth\n"); 9.134 + return (0); 9.135 + } 9.136 +#endif 9.137 + 9.138 + if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample)) 9.139 + { 9.140 + fprintf (stderr, "can't get bits per sample\n"); 9.141 + return (0); 9.142 + } 9.143 + 9.144 + if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config)) 9.145 + planar_config = 1; 9.146 + 9.147 + if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit)) 9.148 + resolution_unit = 2; 9.149 + if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution)) 9.150 + x_resolution = 300; 9.151 + if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution)) 9.152 + y_resolution = 300; 9.153 + 9.154 + if (samples_per_pixel != 1) 9.155 + { 9.156 + fprintf (stderr, "samples per pixel %u, must be 1\n", samples_per_pixel); 9.157 + return (0); 9.158 + } 9.159 + 9.160 +#ifdef CHECK_DEPTH 9.161 + if (image_depth != 1) 9.162 + { 9.163 + fprintf (stderr, "image depth %u, must be 1\n", image_depth); 9.164 + return (0); 9.165 + } 9.166 +#endif 9.167 + 9.168 + if (bits_per_sample != 1) 9.169 + { 9.170 + fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample); 9.171 + return (0); 9.172 + } 9.173 + 9.174 + if (planar_config != 1) 9.175 + { 9.176 + fprintf (stderr, "planar config %u, must be 1\n", planar_config); 9.177 + return (0); 9.178 + } 9.179 + 9.180 + if (input_attributes.has_resolution) 9.181 + { 9.182 + x_resolution = input_attributes.x_resolution; 9.183 + y_resolution = input_attributes.y_resolution; 9.184 + } 9.185 + 9.186 + if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270)) 9.187 + { 9.188 + image_info->width_samples = image_height; 9.189 + image_info->height_samples = image_width; 9.190 + dest_x_resolution = y_resolution; 9.191 + dest_y_resolution = x_resolution; 9.192 + SWAP (double, image_info->width_points, image_info->height_points); 9.193 + } 9.194 + else 9.195 + { 9.196 + image_info->width_samples = image_width; 9.197 + image_info->height_samples = image_height; 9.198 + dest_x_resolution = x_resolution; 9.199 + dest_y_resolution = y_resolution; 9.200 + } 9.201 + 9.202 + image_info->width_points = (image_info->width_samples / dest_x_resolution) * POINTS_PER_INCH; 9.203 + image_info->height_points = (image_info->height_samples / dest_y_resolution) * POINTS_PER_INCH; 9.204 + 9.205 + if ((image_info->height_points > PAGE_MAX_POINTS) || 9.206 + (image_info->width_points > PAGE_MAX_POINTS)) 9.207 + { 9.208 + fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES); 9.209 + return (0); 9.210 + } 9.211 + 9.212 + return (1); 9.213 +} 9.214 + 9.215 + 9.216 +/* frees original! */ 9.217 +static Bitmap *resize_bitmap (Bitmap *src, 9.218 + double x_resolution, 9.219 + double y_resolution, 9.220 + input_attributes_t input_attributes) 9.221 +{ 9.222 + Rect src_rect; 9.223 + Point dest_min; 9.224 + Bitmap *dest; 9.225 + 9.226 + int width_pixels = input_attributes.page_size.width * x_resolution; 9.227 + int height_pixels = input_attributes.page_size.height * y_resolution; 9.228 + 9.229 + src_rect.min.x = (rect_width (& src->rect) - width_pixels) / 2; 9.230 + src_rect.min.y = (rect_height (& src->rect) - height_pixels) / 2; 9.231 + src_rect.max.x = src_rect.min.x + width_pixels; 9.232 + src_rect.max.y = src_rect.min.y + height_pixels; 9.233 + 9.234 + dest_min.x = 0; 9.235 + dest_min.y = 0; 9.236 + 9.237 + dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0); 9.238 + free_bitmap (src); 9.239 + return (dest); 9.240 +} 9.241 + 9.242 + 9.243 +/* "in place" rotation */ 9.244 +static void rotate_bitmap (Bitmap *src, 9.245 + input_attributes_t input_attributes) 9.246 +{ 9.247 + switch (input_attributes.rotation) 9.248 + { 9.249 + case 0: break; 9.250 + case 90: rot_90 (src); break; 9.251 + case 180: rot_180 (src); break; 9.252 + case 270: rot_270 (src); break; 9.253 + default: 9.254 + fprintf (stderr, "rotation must be 0, 90, 180, or 270\n"); 9.255 + } 9.256 +} 9.257 + 9.258 + 9.259 +bool process_tiff_image (int image, /* range 1 .. n */ 9.260 + input_attributes_t input_attributes, 9.261 + image_info_t *image_info, 9.262 + pdf_page_handle page) 9.263 +{ 9.264 + Rect rect; 9.265 + Bitmap *bitmap = NULL; 9.266 + 9.267 + int row; 9.268 + 9.269 + rect.min.x = 0; 9.270 + rect.min.y = 0; 9.271 + 9.272 + if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270)) 9.273 + { 9.274 + rect.max.x = image_info->height_samples; 9.275 + rect.max.y = image_info->width_samples; 9.276 + } 9.277 + else 9.278 + { 9.279 + rect.max.x = image_info->width_samples; 9.280 + rect.max.y = image_info->height_samples; 9.281 + } 9.282 + 9.283 + bitmap = create_bitmap (& rect); 9.284 + 9.285 + if (! bitmap) 9.286 + { 9.287 + fprintf (stderr, "can't allocate bitmap\n"); 9.288 + fprintf (stderr, "width %d height %d\n", image_info->width_samples, image_info->height_samples); 9.289 + goto fail; 9.290 + } 9.291 + 9.292 + for (row = 0; row < rect.max.y; row++) 9.293 + if (1 != TIFFReadScanline (tiff_in, 9.294 + bitmap->bits + row * bitmap->row_words, 9.295 + row, 9.296 + 0)) 9.297 + { 9.298 + fprintf (stderr, "can't read TIFF scanline\n"); 9.299 + goto fail; 9.300 + } 9.301 + 9.302 +#ifdef TIFF_REVERSE_BITS 9.303 + reverse_bits ((uint8_t *) bitmap->bits, 9.304 + rect.max.y * bitmap->row_words * sizeof (word_t)); 9.305 +#endif /* TIFF_REVERSE_BITS */ 9.306 + 9.307 +#if 0 9.308 + if (input_attributes.has_page_size) 9.309 + bitmap = resize_bitmap (bitmap, 9.310 + x_resolution, 9.311 + y_resolution, 9.312 + input_attributes); 9.313 +#endif 9.314 + 9.315 + rotate_bitmap (bitmap, 9.316 + input_attributes); 9.317 + 9.318 +#if 0 9.319 + pdf_write_text (page); 9.320 +#else 9.321 + pdf_write_g4_fax_image (page, 9.322 + 0, 0, /* x, y */ 9.323 + image_info->width_points, image_info->height_points, 9.324 + bitmap, 9.325 + 0, /* ImageMask */ 9.326 + 0, 0, 0, /* r, g, b */ 9.327 + 0); /* BlackIs1 */ 9.328 +#endif 9.329 + 9.330 + if (bitmap) 9.331 + free_bitmap (bitmap); 9.332 + return (page); 9.333 + 9.334 + fail: 9.335 + if (bitmap) 9.336 + free_bitmap (bitmap); 9.337 + 9.338 + return (NULL); 9.339 +} 9.340 + 9.341 + 9.342 +input_handler_t tiff_handler = 9.343 + { 9.344 + open_tiff_input_file, 9.345 + close_tiff_input_file, 9.346 + last_tiff_input_page, 9.347 + get_tiff_image_info, 9.348 + process_tiff_image 9.349 + }; 9.350 + 9.351 + 9.352 +void init_tiff_handler (void) 9.353 +{ 9.354 + install_input_handler (& tiff_handler); 9.355 +}