tumble_tiff.c

Thu, 20 Mar 2003 08:20:52 +0000

author
eric
date
Thu, 20 Mar 2003 08:20:52 +0000
changeset 148
d4a6e303703a
parent 142
cfa664f3129c
child 151
83a99cc69861
permissions
-rw-r--r--

fix return values in process_tiff_image().

     1 /*
     2  * tumble: build a PDF file from image files
     3  *
     4  * $Id: tumble_tiff.c,v 1.3 2003/03/20 00:20:52 eric Exp $
     5  * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
     6  *
     7  * This program is free software; you can redistribute it and/or modify
     8  * it under the terms of the GNU General Public License version 2 as
     9  * published by the Free Software Foundation.  Note that permission is
    10  * not granted to redistribute this program under the terms of any
    11  * other version of the General Public License.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
    21  */
    24 #include <stdbool.h>
    25 #include <stdint.h>
    26 #include <stdio.h>
    27 #include <stdlib.h>
    28 #include <string.h>
    30 #include <tiffio.h>
    31 #define TIFF_REVERSE_BITS
    34 #include "semantics.h"
    35 #include "tumble.h"
    36 #include "bitblt.h"
    37 #include "pdf.h"
    38 #include "tumble_input.h"
    41 TIFF *tiff_in;
    44 #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    47 bool close_tiff_input_file (void)
    48 {
    49   TIFFClose (tiff_in);
    50   return (1);
    51 }
    54 bool open_tiff_input_file (FILE *f, char *name)
    55 {
    56   uint8_t buf [2];
    57   size_t l;
    59   l = fread (& buf [0], 1, sizeof (buf), f);
    60   if (l != sizeof (buf))
    61     return (0);
    63   rewind (f);
    65   if ((buf [0] != 0x49) || (buf [1] != 0x49))
    66     return (0);
    68   tiff_in = TIFFFdOpen (fileno (f), name, "r");
    69   if (! tiff_in)
    70     {
    71       fprintf (stderr, "can't open input file '%s'\n", name);
    72       return (0);
    73     }
    74   return (1);
    75 }
    78 bool last_tiff_input_page (void)
    79 {
    80   return (TIFFLastDirectory (tiff_in));
    81 }
    84 bool get_tiff_image_info (int image,
    85 			  input_attributes_t input_attributes,
    86 			  image_info_t *image_info)
    87 {
    88   uint32_t image_height, image_width;
    89   uint16_t samples_per_pixel;
    90   uint16_t bits_per_sample;
    91   uint16_t planar_config;
    93   uint16_t resolution_unit;
    94   float x_resolution, y_resolution;
    96   double dest_x_resolution, dest_y_resolution;
    98 #ifdef CHECK_DEPTH
    99   uint32_t image_depth;
   100 #endif
   102   if (! TIFFSetDirectory (tiff_in, image - 1))
   103     {
   104       fprintf (stderr, "can't find page %d of input file\n", image);
   105       return (0);
   106     }
   107   if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGELENGTH, & image_height))
   108     {
   109       fprintf (stderr, "can't get image height\n");
   110       return (0);
   111     }
   112   if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEWIDTH, & image_width))
   113     {
   114       fprintf (stderr, "can't get image width\n");
   115       return (0);
   116     }
   118   if (1 != TIFFGetField (tiff_in, TIFFTAG_SAMPLESPERPIXEL, & samples_per_pixel))
   119     {
   120       fprintf (stderr, "can't get samples per pixel\n");
   121       return (0);
   122     }
   124 #ifdef CHECK_DEPTH
   125   if (1 != TIFFGetField (tiff_in, TIFFTAG_IMAGEDEPTH, & image_depth))
   126     {
   127       fprintf (stderr, "can't get image depth\n");
   128       return (0);
   129     }
   130 #endif
   132   if (1 != TIFFGetField (tiff_in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   133     {
   134       fprintf (stderr, "can't get bits per sample\n");
   135       return (0);
   136     }
   138   if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config))
   139     planar_config = 1;
   141   if (1 != TIFFGetField (tiff_in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   142     resolution_unit = 2;
   143   if (1 != TIFFGetField (tiff_in, TIFFTAG_XRESOLUTION, & x_resolution))
   144     x_resolution = 300;
   145   if (1 != TIFFGetField (tiff_in, TIFFTAG_YRESOLUTION, & y_resolution))
   146     y_resolution = 300;
   148   if (samples_per_pixel != 1)
   149     {
   150       fprintf (stderr, "samples per pixel %u, must be 1\n", samples_per_pixel);
   151       return (0);
   152     }
   154 #ifdef CHECK_DEPTH
   155   if (image_depth != 1)
   156     {
   157       fprintf (stderr, "image depth %u, must be 1\n", image_depth);
   158       return (0);
   159     }
   160 #endif
   162   if (bits_per_sample != 1)
   163     {
   164       fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample);
   165       return (0);
   166     }
   168   if (planar_config != 1)
   169     {
   170       fprintf (stderr, "planar config %u, must be 1\n", planar_config);
   171       return (0);
   172     }
   174   if (input_attributes.has_resolution)
   175     {
   176       x_resolution = input_attributes.x_resolution;
   177       y_resolution = input_attributes.y_resolution;
   178     }
   180   if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   181     {
   182       image_info->width_samples  = image_height;
   183       image_info->height_samples = image_width;
   184       dest_x_resolution = y_resolution;
   185       dest_y_resolution = x_resolution;
   186       SWAP (double, image_info->width_points, image_info->height_points);
   187     }
   188   else
   189     {
   190       image_info->width_samples = image_width;
   191       image_info->height_samples = image_height;
   192       dest_x_resolution = x_resolution;
   193       dest_y_resolution = y_resolution;
   194     }
   196   image_info->width_points = (image_info->width_samples / dest_x_resolution) * POINTS_PER_INCH;
   197   image_info->height_points = (image_info->height_samples / dest_y_resolution) * POINTS_PER_INCH;
   199   if ((image_info->height_points > PAGE_MAX_POINTS) || 
   200       (image_info->width_points > PAGE_MAX_POINTS))
   201     {
   202       fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   203       return (0);
   204     }
   206   return (1);
   207 }
   210 /* frees original! */
   211 static Bitmap *resize_bitmap (Bitmap *src,
   212 			      double x_resolution,
   213 			      double y_resolution,
   214 			      input_attributes_t input_attributes)
   215 {
   216   Rect src_rect;
   217   Point dest_min;
   218   Bitmap *dest;
   220   int width_pixels = input_attributes.page_size.width * x_resolution;
   221   int height_pixels = input_attributes.page_size.height * y_resolution;
   223   src_rect.min.x = (rect_width (& src->rect) - width_pixels) / 2;
   224   src_rect.min.y = (rect_height (& src->rect) - height_pixels) / 2;
   225   src_rect.max.x = src_rect.min.x + width_pixels;
   226   src_rect.max.y = src_rect.min.y + height_pixels;
   228   dest_min.x = 0;
   229   dest_min.y = 0;
   231   dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0);
   232   free_bitmap (src);
   233   return (dest);
   234 }
   237 /* "in place" rotation */
   238 static void rotate_bitmap (Bitmap *src,
   239 			   input_attributes_t input_attributes)
   240 {
   241   switch (input_attributes.rotation)
   242     {
   243     case 0: break;
   244     case 90: rot_90 (src); break;
   245     case 180: rot_180 (src); break;
   246     case 270: rot_270 (src); break;
   247     default:
   248       fprintf (stderr, "rotation must be 0, 90, 180, or 270\n");
   249     }
   250 }
   253 bool process_tiff_image (int image,  /* range 1 .. n */
   254 			 input_attributes_t input_attributes,
   255 			 image_info_t *image_info,
   256 			 pdf_page_handle page)
   257 {
   258   bool result = 0;
   259   Rect rect;
   260   Bitmap *bitmap = NULL;
   262   int row;
   264   rect.min.x = 0;
   265   rect.min.y = 0;
   267   if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   268     {
   269       rect.max.x = image_info->height_samples;
   270       rect.max.y = image_info->width_samples;
   271     }
   272   else
   273     {
   274       rect.max.x = image_info->width_samples;
   275       rect.max.y = image_info->height_samples;
   276     }
   278   bitmap = create_bitmap (& rect);
   280   if (! bitmap)
   281     {
   282       fprintf (stderr, "can't allocate bitmap\n");
   283       fprintf (stderr, "width %d height %d\n", image_info->width_samples, image_info->height_samples);
   284       goto fail;
   285     }
   287   for (row = 0; row < rect.max.y; row++)
   288     if (1 != TIFFReadScanline (tiff_in,
   289 			       bitmap->bits + row * bitmap->row_words,
   290 			       row,
   291 			       0))
   292       {
   293 	fprintf (stderr, "can't read TIFF scanline\n");
   294 	goto fail;
   295       }
   297 #ifdef TIFF_REVERSE_BITS
   298   reverse_bits ((uint8_t *) bitmap->bits,
   299 		rect.max.y * bitmap->row_words * sizeof (word_t));
   300 #endif /* TIFF_REVERSE_BITS */
   302 #if 0
   303   if (input_attributes.has_page_size)
   304     bitmap = resize_bitmap (bitmap,
   305 			    x_resolution,
   306 			    y_resolution,
   307 			    input_attributes);
   308 #endif
   310   rotate_bitmap (bitmap,
   311 		 input_attributes);
   313 #if 0
   314   pdf_write_text (page);
   315 #else
   316   pdf_write_g4_fax_image (page,
   317 			  0, 0,  /* x, y */
   318 			  image_info->width_points, image_info->height_points,
   319 			  bitmap,
   320 			  0, /* ImageMask */
   321 			  0, 0, 0,  /* r, g, b */
   322 			  0); /* BlackIs1 */
   323 #endif
   325   result = 1;
   327  fail:
   328   if (bitmap)
   329     free_bitmap (bitmap);
   330   return (result);
   331 }
   334 input_handler_t tiff_handler =
   335   {
   336     open_tiff_input_file,
   337     close_tiff_input_file,
   338     last_tiff_input_page,
   339     get_tiff_image_info,
   340     process_tiff_image
   341   };
   344 void init_tiff_handler (void)
   345 {
   346   install_input_handler (& tiff_handler);
   347 }