tumble.c

Tue, 01 Jan 2002 05:02:44 +0000

author
eric
date
Tue, 01 Jan 2002 05:02:44 +0000
changeset 28
ba8313d18bd3
parent 26
4368c5fd9242
child 29
c904ffd6a1cf
permissions
-rw-r--r--

create temporary TIFF file.

     1 /*
     2  * tiffg4: reencode a bilevel TIFF file as a single-strip TIFF Class F Group 4
     3  * Main program
     4  * $Id: tumble.c,v 1.9 2001/12/31 21:02:44 eric Exp $
     5  * Copyright 2001 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 <stdio.h>
    25 #include <stdlib.h>
    26 #include <unistd.h>
    27 #include <tiffio.h>
    28 #include <panda/functions.h>
    29 #include <panda/constants.h>
    31 #include "type.h"
    32 #include "bitblt.h"
    33 #include "semantics.h"
    34 #include "parser.tab.h"
    35 #include "tiff2pdf.h"
    38 #define POINTS_PER_INCH 72
    40 /* page size limited by Acrobat Reader to 45 inches on a side */
    41 #define PAGE_MAX_INCHES 45
    42 #define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH)
    45 typedef struct output_file_t
    46 {
    47   struct output_file_t *next;
    48   char *name;
    49   panda_pdf *pdf;
    50 } output_file_t;
    53 char *in_filename;
    54 TIFF *in;
    55 output_file_t *output_files;
    56 output_file_t *out;
    57 /* panda_pdf *out; */
    60 boolean close_tiff_input_file (void)
    61 {
    62   if (in)
    63     {
    64       free (in_filename);
    65       TIFFClose (in);
    66     }
    67   in = NULL;
    68   in_filename = NULL;
    69   return (1);
    70 }
    72 boolean open_tiff_input_file (char *name)
    73 {
    74   if (in)
    75     {
    76       if (strcmp (name, in_filename) == 0)
    77 	return (1);
    78       close_tiff_input_file ();
    79     }
    80   in_filename = strdup (name);
    81   if (! in_filename)
    82     {
    83       fprintf (stderr, "can't strdup input filename '%s'\n", name);
    84       return (0);
    85     }
    86   in = TIFFOpen (name, "r");
    87   if (! in)
    88     {
    89       fprintf (stderr, "can't open input file '%s'\n", name);
    90       free (in_filename);
    91       return (0);
    92     }
    93   return (1);
    94 }
    97 boolean close_pdf_output_files (void)
    98 {
    99   output_file_t *o, *n;
   101   for (o = output_files; o; o = n)
   102     {
   103       n = o->next;
   104       panda_close (o->pdf);
   105       free (o->name);
   106       free (o);
   107     }
   108   out = NULL;
   109   output_files = NULL;
   110   return (1);
   111 }
   113 boolean open_pdf_output_file (char *name)
   114 {
   115   output_file_t *o;
   117   if (out && (strcmp (name, out->name) == 0))
   118     return (1);
   119   for (o = output_files; o; o = o->next)
   120     if (strcmp (name, o->name) == 0)
   121       {
   122 	out = o;
   123 	return (1);
   124       }
   125   o = calloc (1, sizeof (output_file_t));
   126   if (! 0)
   127     {
   128       fprintf (stderr, "can't calloc output file struct for '%s'\n", name);
   129       return (0);
   130    }
   132   o->name = strdup (name);
   133   if (! o->name)
   134     {
   135       fprintf (stderr, "can't strdup output filename '%s'\n", name);
   136       free (o);
   137       return (0);
   138     }
   140   o->pdf = panda_open (name, "w");
   141   if (! o->pdf)
   142     {
   143       fprintf (stderr, "can't open output file '%s'\n", name);
   144       free (o->name);
   145       free (o);
   146       return (0);
   147     }
   149   /* prepend new output file onto list */
   150   o->next = output_files;
   151   output_files = o;
   153   out = o;
   154   return (1);
   155 }
   158 void process_page_numbers (int page_index,
   159 			   int count,
   160 			   int base,
   161 			   page_label_t *page_label)
   162 {
   163 }
   166 boolean process_page (int image,  /* range 1 .. n */
   167 		      input_attributes_t input_attributes,
   168 		      bookmark_t *bookmarks)
   169 {
   170   u32 image_length, image_width;
   171 #ifdef CHECK_DEPTH
   172   u32 image_depth;
   173 #endif
   174   u16 bits_per_sample;
   175   u16 planar_config;
   176   u16 resolution_unit;
   177   float x_resolution, y_resolution;
   178   int width_points, height_points;  /* really 1/72 inch units rather than
   179 				       points */
   182   char *buffer;
   183   u32 row;
   185   panda_page *page;
   187   int tiff_temp_fd;
   188   char tiff_temp_fn [] = "/var/tmp/tiff2pdf-XXXXXX\0";
   189   TIFF *tiff_temp;
   191   char pagesize [26];  /* Needs to hold two ints of four characters (0..3420),
   192 			  two zeros, three spaces, two brackets, and a NULL.
   193                           Added an extra ten characters just in case. */
   195   if (! TIFFSetDirectory (in, image - 1))
   196     {
   197       fprintf (stderr, "can't find page %d of input file\n", image);
   198       goto fail;
   199     }
   200   if (1 != TIFFGetField (in, TIFFTAG_IMAGELENGTH, & image_length))
   201     {
   202       fprintf (stderr, "can't get image length\n");
   203       goto fail;
   204     }
   205   if (1 != TIFFGetField (in, TIFFTAG_IMAGEWIDTH, & image_width))
   206     {
   207       fprintf (stderr, "can't get image width\n");
   208       goto fail;
   209     }
   210 #ifdef CHECK_DEPTH
   211   if (1 != TIFFGetField (in, TIFFTAG_IMAGEDEPTH, & image_depth))
   212     {
   213       fprintf (stderr, "can't get image depth\n");
   214       goto fail;
   215     }
   216 #endif
   218   if (1 != TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, & bits_per_sample))
   219     {
   220       fprintf (stderr, "can't get bits per sample\n");
   221       goto fail;
   222     }
   224   if (1 != TIFFGetField (in, TIFFTAG_PLANARCONFIG, & planar_config))
   225     planar_config = 1;
   227   printf ("image length %u width %u, "
   228 #ifdef CHECK_DEPTH
   229           "depth %u, "
   230 #endif
   231           "planar config %u\n",
   232 	  image_length, image_width,
   233 #ifdef CHECK_DEPTH
   234 	  image_depth,
   235 #endif
   236 	  planar_config);
   238   if (1 != TIFFGetField (in, TIFFTAG_RESOLUTIONUNIT, & resolution_unit))
   239     resolution_unit = 2;
   240   if (1 != TIFFGetField (in, TIFFTAG_XRESOLUTION, & x_resolution))
   241     x_resolution = 300;
   242   if (1 != TIFFGetField (in, TIFFTAG_YRESOLUTION, & y_resolution))
   243     y_resolution = 300;
   245   printf ("resolution unit %u, x resolution %f, y resolution %f\n",
   246 	  resolution_unit, x_resolution, y_resolution);
   248 #ifdef CHECK_DEPTH
   249   if (image_depth != 1)
   250     {
   251       fprintf (stderr, "image depth %u, must be 1\n", image_depth);
   252       goto fail;
   253     }
   254 #endif
   256   if (bits_per_sample != 1)
   257     {
   258       fprintf (stderr, "bits per sample %u, must be 1\n", bits_per_sample);
   259       goto fail;
   260     }
   262   if (planar_config != 1)
   263     {
   264       fprintf (stderr, "planar config %u, must be 1\n", planar_config);
   265       goto fail;
   266     }
   268   tiff_temp_fd = mkstemp (tiff_temp_fn);
   269   if (tiff_temp_fd < 0)
   270     {
   271       fprintf (stderr, "can't create temporary TIFF file\n");
   272       goto fail;
   273     }
   275   tiff_temp = TIFFFdOpen (tiff_temp_fd, tiff_temp_fn, "w");
   276   if (! out)
   277     {
   278       fprintf (stderr, "can't open temporary TIFF file '%s'\n", tiff_temp_fn);
   279       goto fail;
   280     }
   282   TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, image_length);
   283   TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, image_width);
   284   TIFFSetField (tiff_temp, TIFFTAG_PLANARCONFIG, planar_config);
   286   TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, image_length);
   288   TIFFSetField (tiff_temp, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
   289   TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, x_resolution);
   290   TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, y_resolution);
   292   TIFFSetField (tiff_temp, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
   293   TIFFSetField (tiff_temp, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
   294   TIFFSetField (tiff_temp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
   296   buffer = _TIFFmalloc (TIFFScanlineSize (in));
   297   if (! buffer)
   298     {
   299       fprintf (stderr, "failed to allocate buffer\n");
   300       goto fail;
   301     }
   303   for (row = 0; row < image_length; row++)
   304     {
   305       TIFFReadScanline (in, buffer, row, 0);
   306       TIFFWriteScanline (tiff_temp, buffer, row, 0);
   307     }
   309   _TIFFfree (buffer);
   310   TIFFClose (tiff_temp);
   312   height_points = (image_width / x_resolution) * POINTS_PER_INCH;
   313   width_points = (image_length / y_resolution) * POINTS_PER_INCH;
   315   if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
   316     {
   317       fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   318       goto fail;
   319     }
   321   printf ("height_points %d, width_points %d\n", height_points, width_points);
   323   sprintf (pagesize, "[0 0 %d %d]", width_points, height_points);
   325   page = panda_newpage (out->pdf, pagesize);
   326   panda_imagebox (out->pdf,
   327 		  page,
   328 		  0, /* top */
   329 		  0, /* left */
   330 		  height_points, /* bottom */
   331 		  width_points, /* right */
   332 		  tiff_temp_fn,
   333 		  panda_image_tiff);
   335   unlink (tiff_temp_fn);
   337   return (1);
   339  fail:
   340   return (0);
   341 }
   344 int main (int argc, char *argv[])
   345 {
   346   int result = 0;
   348   panda_init ();
   350   if (argc != 2)
   351     {
   352       fprintf (stderr, "usage: %s spec\n", argv [0]);
   353       result = 1;
   354       goto fail;
   355     }
   357   if (! parse_spec_file (argv [1]))
   358     {
   359       result = 2;
   360       goto fail;
   361     }
   363   if (! process_specs ())
   364     {
   365       result = 3;
   366       goto fail;
   367     }
   369  fail:
   370   close_tiff_input_file ();
   371   close_pdf_output_files ();
   372   return (result);
   373 }