added start of page size support.

Tue, 01 Jan 2002 10:16:50 +0000

author
eric
date
Tue, 01 Jan 2002 10:16:50 +0000
changeset 32
3aac131058da
parent 31
2cec996b38bc
child 33
44d823824a46

added start of page size support.

parser.y file | annotate | diff | revisions
scanner.l file | annotate | diff | revisions
semantics.c file | annotate | diff | revisions
semantics.h file | annotate | diff | revisions
t2p.c file | annotate | diff | revisions
t2p.h file | annotate | diff | revisions
tumble.c file | annotate | diff | revisions
tumble.h file | annotate | diff | revisions
     1.1 --- a/parser.y	Tue Jan 01 06:17:39 2002 +0000
     1.2 +++ b/parser.y	Tue Jan 01 10:16:50 2002 +0000
     1.3 @@ -59,9 +59,11 @@
     1.4  
     1.5  %type <fp> unit
     1.6  
     1.7 -
     1.8 +%type <fp> length
     1.9  
    1.10 -%type <fp> length
    1.11 +%type <integer> orientation
    1.12 +
    1.13 +%type <size> page_size
    1.14  
    1.15  %%
    1.16  
    1.17 @@ -96,9 +98,9 @@
    1.18  	ROTATE INTEGER ';' { input_set_rotation ($2) } ;
    1.19  
    1.20  unit:
    1.21 -	/* empty */  /* default to INCH */ { $$ = 25.4; }
    1.22 -	| CM { $$ = 1.0; }
    1.23 -	| INCH { $$ = 25.4; } ;
    1.24 +	/* empty */  /* default to INCH */ { $$ = 1.0; }
    1.25 +	| CM { $$ = (1.0 / 25.4); }
    1.26 +	| INCH { $$ = 1.0; } ;
    1.27  
    1.28  length:
    1.29  	FLOAT unit { $$ = $1 * $2; } ;
    1.30 @@ -110,13 +112,23 @@
    1.31  	| CROP length ',' length ',' length ',' length ';' ;
    1.32  
    1.33  orientation:
    1.34 -	PORTRAIT
    1.35 -	| LANDSCAPE ;
    1.36 +	PORTRAIT { $$ = 0; }
    1.37 +	| LANDSCAPE { $$ = 1; } ;
    1.38 +
    1.39 +page_size:
    1.40 +	PAGE_SIZE { $$ = $1; }
    1.41 +	| PAGE_SIZE orientation { if ($2)
    1.42 +                                    {
    1.43 +                                      $$.width = $1.height;
    1.44 +				      $$.height = $1.width;
    1.45 +                                    }
    1.46 +                                  else
    1.47 +                                    $$ = $1;
    1.48 +                                }
    1.49 +	| length ',' length { $$.width = $1; $$.height = $3; } ;
    1.50  
    1.51  size_clause:
    1.52 -	SIZE PAGE_SIZE ';'
    1.53 -	| SIZE PAGE_SIZE orientation ';'
    1.54 -	| SIZE length ',' length ';' ;
    1.55 +	SIZE page_size ';' { input_set_page_size ($2); } ;
    1.56  
    1.57  resolution_clause:
    1.58  	RESOLUTION FLOAT unit ;
     2.1 --- a/scanner.l	Tue Jan 01 06:17:39 2002 +0000
     2.2 +++ b/scanner.l	Tue Jan 01 10:16:50 2002 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 -$Id: scanner.l,v 1.13 2001/12/31 22:11:43 eric Exp $
     2.6 +$Id: scanner.l,v 1.14 2002/01/01 02:16:50 eric Exp $
     2.7  */
     2.8  
     2.9  %option case-insensitive
    2.10 @@ -32,20 +32,20 @@
    2.11  {digit}+	{ yylval.integer = atoi (yytext); LDBG(("integer %d\n", yylval.integer)); return (INTEGER); }
    2.12  {digit}+\.{digit}+ { yylval.fp = atof (yytext); return (FLOAT); }
    2.13  
    2.14 -a		{ yylval.size.width = 8.5 * 25.4;
    2.15 -		  yylval.size.height = 11.0 * 25.4;
    2.16 +a		{ yylval.size.width = 8.5;
    2.17 +		  yylval.size.height = 11.0;
    2.18                    return (PAGE_SIZE); }
    2.19 -b		{ yylval.size.width = 11.0 * 25.4;
    2.20 -                  yylval.size.height = 17.0 * 25.4;
    2.21 +b		{ yylval.size.width = 11.0;
    2.22 +                  yylval.size.height = 17.0;
    2.23                    return (PAGE_SIZE); }
    2.24 -c		{ yylval.size.width = 17.0 * 25.4;
    2.25 -                  yylval.size.height = 22.0 * 25.4;
    2.26 +c		{ yylval.size.width = 17.0;
    2.27 +                  yylval.size.height = 22.0;
    2.28                    return (PAGE_SIZE); }
    2.29 -d		{ yylval.size.width = 22.0 * 25.4;
    2.30 -                  yylval.size.height = 34.0 * 25.4;
    2.31 +d		{ yylval.size.width = 22.0;
    2.32 +                  yylval.size.height = 34.0;
    2.33                    return (PAGE_SIZE); }
    2.34 -e		{ yylval.size.width = 34.0 * 25.4;
    2.35 -                   yylval.size.height = 44.0 * 25.4;
    2.36 +e		{ yylval.size.width = 34.0;
    2.37 +                   yylval.size.height = 44.0;
    2.38                    return (PAGE_SIZE); }
    2.39  
    2.40  all		{ return (ALL); }
     3.1 --- a/semantics.c	Tue Jan 01 06:17:39 2002 +0000
     3.2 +++ b/semantics.c	Tue Jan 01 10:16:50 2002 +0000
     3.3 @@ -10,8 +10,8 @@
     3.4  
     3.5  typedef struct
     3.6  {
     3.7 -  boolean has_size;
     3.8 -  page_size_t size;
     3.9 +  boolean has_page_size;
    3.10 +  page_size_t page_size;
    3.11  
    3.12    boolean has_rotation;
    3.13    int rotation;
    3.14 @@ -184,6 +184,14 @@
    3.15    SDBG(("rotation %d\n", rotation));
    3.16  }
    3.17  
    3.18 +void input_set_page_size (page_size_t size)
    3.19 +{
    3.20 +  last_input_context->modifiers [current_modifier_context].has_page_size = 1;
    3.21 +  last_input_context->modifiers [current_modifier_context].page_size = size;
    3.22 +  printf ("page size %f, %f\n", size.width, size.height);
    3.23 +  SDBG(("page size %f, %f\n", size.width, size.height));
    3.24 +}
    3.25 +
    3.26  static void increment_input_image_count (int count)
    3.27  {
    3.28    input_context_t *context;
    3.29 @@ -423,14 +431,42 @@
    3.30    exit (2);
    3.31  }
    3.32  
    3.33 -static int get_input_rotation (input_context_t *context, input_modifier_type_t type)
    3.34 +static boolean get_input_rotation (input_context_t *context,
    3.35 +				   input_modifier_type_t type,
    3.36 +				   int *rotation)
    3.37  {
    3.38    for (; context; context = context->parent)
    3.39      {
    3.40        if (context->modifiers [type].has_rotation)
    3.41 -	return (context->modifiers [type].rotation);
    3.42 +	{
    3.43 +	  * rotation = context->modifiers [type].rotation;
    3.44 +	  return (1);
    3.45 +	}
    3.46        if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
    3.47 -	return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
    3.48 +	{
    3.49 +	  * rotation = context->modifiers [INPUT_MODIFIER_ALL].rotation;
    3.50 +	  return (1);
    3.51 +	}
    3.52 +    }
    3.53 +  return (0);  /* default */
    3.54 +}
    3.55 +
    3.56 +static boolean get_input_page_size (input_context_t *context,
    3.57 +				    input_modifier_type_t type,
    3.58 +				    page_size_t *page_size)
    3.59 +{
    3.60 +  for (; context; context = context->parent)
    3.61 +    {
    3.62 +      if (context->modifiers [type].has_page_size)
    3.63 +	{
    3.64 +	  * page_size = context->modifiers [type].page_size;
    3.65 +	  return (1);
    3.66 +	}
    3.67 +      if (context->modifiers [INPUT_MODIFIER_ALL].has_page_size)
    3.68 +	{
    3.69 +	  * page_size = context->modifiers [INPUT_MODIFIER_ALL].page_size;
    3.70 +	  return (1);
    3.71 +	}
    3.72      }
    3.73    return (0);  /* default */
    3.74  }
    3.75 @@ -473,10 +509,24 @@
    3.76      for (i = image->range.first; i <= image->range.last; i++)
    3.77        {
    3.78  	input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
    3.79 -	printf ("file '%s' image %d, rotation %d\n",
    3.80 +	boolean has_rotation, has_page_size;
    3.81 +	int rotation;
    3.82 +	page_size_t page_size;
    3.83 +
    3.84 +	has_rotation = get_input_rotation (image->input_context,
    3.85 +					   parity,
    3.86 +					   & rotation);
    3.87 +	has_page_size = get_input_page_size (image->input_context,
    3.88 +					     parity,
    3.89 +					     & page_size);
    3.90 +	printf ("file '%s' image %d",
    3.91  	        get_input_file (image->input_context),
    3.92 -		i, 
    3.93 -		get_input_rotation (image->input_context, parity));
    3.94 +		i);
    3.95 +	if (has_rotation)
    3.96 +	  printf (" rotation %d", rotation);
    3.97 +	if (has_page_size)
    3.98 +	  printf (" size %f, %f", page_size.width, page_size.height);
    3.99 +	printf ("\n");
   3.100        }
   3.101  }
   3.102  
   3.103 @@ -611,8 +661,15 @@
   3.104        parity = ((image->range.first + i) % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
   3.105  
   3.106        memset (& input_attributes, 0, sizeof (input_attributes));
   3.107 -      input_attributes.rotation = get_input_rotation (image->input_context,
   3.108 -						      parity);;
   3.109 +
   3.110 +      input_attributes.rotation = 0;
   3.111 +      input_attributes.has_rotation = get_input_rotation (image->input_context,
   3.112 +							  parity,
   3.113 +							  & input_attributes.rotation);
   3.114 +
   3.115 +      input_attributes.has_page_size = get_input_page_size (image->input_context,
   3.116 +							    parity,
   3.117 +							    & input_attributes.page_size);
   3.118  
   3.119        process_page (image->range.first + i,
   3.120  		    input_attributes,
     4.1 --- a/semantics.h	Tue Jan 01 06:17:39 2002 +0000
     4.2 +++ b/semantics.h	Tue Jan 01 10:16:50 2002 +0000
     4.3 @@ -52,6 +52,7 @@
     4.4  void input_set_modifier_context (input_modifier_type_t type);
     4.5  void input_set_file (char *name);
     4.6  void input_set_rotation (int rotation);
     4.7 +void input_set_page_size (page_size_t size);
     4.8  void input_images (range_t range);
     4.9  
    4.10  /* semantic routines for output statements */
     5.1 --- a/t2p.c	Tue Jan 01 06:17:39 2002 +0000
     5.2 +++ b/t2p.c	Tue Jan 01 10:16:50 2002 +0000
     5.3 @@ -5,7 +5,7 @@
     5.4   *           encoding.
     5.5   *
     5.6   * Main program
     5.7 - * $Id: t2p.c,v 1.11 2001/12/31 22:11:43 eric Exp $
     5.8 + * $Id: t2p.c,v 1.12 2002/01/01 02:16:50 eric Exp $
     5.9   * Copyright 2001 Eric Smith <eric@brouhaha.com>
    5.10   *
    5.11   * This program is free software; you can redistribute it and/or modify
    5.12 @@ -179,6 +179,42 @@
    5.13  }
    5.14  
    5.15  
    5.16 +static Bitmap *rotate_bitmap (Bitmap *src, int rotation)
    5.17 +{
    5.18 +  Rect src_rect;
    5.19 +  Point dest_upper_left;
    5.20 +  int scan;
    5.21 +
    5.22 +  src_rect.upper_left.x = 0;
    5.23 +  src_rect.upper_left.y = 0;
    5.24 +  src_rect.lower_right.x = src->width;
    5.25 +  src_rect.lower_right.y = src->height;
    5.26 +
    5.27 +  dest_upper_left.x = 0;
    5.28 +  dest_upper_left.y = 0;
    5.29 +
    5.30 +  switch (rotation)
    5.31 +    {
    5.32 +    case 0: scan = ROT_0; break;
    5.33 +    case 90: scan = ROT_90; break;
    5.34 +    case 180: scan = ROT_180; break;
    5.35 +    case 270: scan = ROT_270; break;
    5.36 +    default:
    5.37 +      fprintf (stderr, "rotation must be 0, 90, 180, or 270\n");
    5.38 +      return (NULL);
    5.39 +    }
    5.40 +
    5.41 +  return (bitblt (src,
    5.42 +		  src_rect,
    5.43 +		  NULL,  /* dest_bitmap */
    5.44 +		  dest_upper_left,
    5.45 +		  scan,
    5.46 +		  TF_SRC));
    5.47 +}
    5.48 +
    5.49 +
    5.50 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    5.51 +
    5.52  boolean process_page (int image,  /* range 1 .. n */
    5.53  		      input_attributes_t input_attributes,
    5.54  		      bookmark_t *bookmarks)
    5.55 @@ -186,6 +222,7 @@
    5.56    int result = 0;
    5.57  
    5.58    u32 image_length, image_width;
    5.59 +  u32 dest_image_length, dest_image_width;
    5.60  #ifdef CHECK_DEPTH
    5.61    u32 image_depth;
    5.62  #endif
    5.63 @@ -193,14 +230,19 @@
    5.64    u16 samples_per_pixel;
    5.65    u16 bits_per_sample;
    5.66    u16 planar_config;
    5.67 +
    5.68    u16 resolution_unit;
    5.69    float x_resolution, y_resolution;
    5.70 +  float dest_x_resolution, dest_y_resolution;
    5.71 +
    5.72 +  int scanline_size;
    5.73 +
    5.74    int width_points, height_points;  /* really 1/72 inch units rather than
    5.75  				       points */
    5.76  
    5.77 -
    5.78 -  char *buffer;
    5.79 -  u32 row;
    5.80 +  Bitmap *src_bitmap;
    5.81 +  Bitmap *dest_bitmap;
    5.82 +  int row;
    5.83  
    5.84    panda_page *page;
    5.85  
    5.86 @@ -298,6 +340,17 @@
    5.87        goto fail;
    5.88      }
    5.89  
    5.90 +  width_points = (image_width / x_resolution) * POINTS_PER_INCH;
    5.91 +  height_points = (image_length / y_resolution) * POINTS_PER_INCH;
    5.92 +
    5.93 +  if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
    5.94 +    {
    5.95 +      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
    5.96 +      goto fail;
    5.97 +    }
    5.98 +
    5.99 +  printf ("height_points %d, width_points %d\n", height_points, width_points);
   5.100 +
   5.101    tiff_temp_fd = mkstemp (tiff_temp_fn);
   5.102    if (tiff_temp_fd < 0)
   5.103      {
   5.104 @@ -312,47 +365,92 @@
   5.105        goto fail;
   5.106      }
   5.107  
   5.108 -  TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, image_length);
   5.109 -  TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, image_width);
   5.110 +  printf ("rotation %d\n", input_attributes.rotation);
   5.111 +
   5.112 +  if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   5.113 +    {
   5.114 +      dest_image_width  = image_length;
   5.115 +      dest_image_length = image_width;
   5.116 +      dest_x_resolution = y_resolution;
   5.117 +      dest_y_resolution = x_resolution;
   5.118 +      SWAP (int, width_points, height_points);
   5.119 +    }
   5.120 +  else
   5.121 +    {
   5.122 +      dest_image_width = image_width;
   5.123 +      dest_image_length = image_length;
   5.124 +      dest_x_resolution = x_resolution;
   5.125 +      dest_y_resolution = y_resolution;
   5.126 +    }
   5.127 +
   5.128 +  TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, dest_image_length);
   5.129 +  TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, dest_image_width);
   5.130    TIFFSetField (tiff_temp, TIFFTAG_PLANARCONFIG, planar_config);
   5.131  
   5.132 -  TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, image_length);
   5.133 +  TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, dest_image_length);
   5.134  
   5.135    TIFFSetField (tiff_temp, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
   5.136 -  TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, x_resolution);
   5.137 -  TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, y_resolution);
   5.138 +  TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, dest_x_resolution);
   5.139 +  TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, dest_y_resolution);
   5.140  
   5.141    TIFFSetField (tiff_temp, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel);
   5.142    TIFFSetField (tiff_temp, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
   5.143    TIFFSetField (tiff_temp, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
   5.144    TIFFSetField (tiff_temp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
   5.145  
   5.146 -  buffer = _TIFFmalloc (TIFFScanlineSize (in));
   5.147 -  if (! buffer)
   5.148 +  scanline_size = TIFFScanlineSize (in);
   5.149 +
   5.150 +  src_bitmap = create_bitmap (image_width, image_length);
   5.151 +  if (! src_bitmap)
   5.152      {
   5.153 -      fprintf (stderr, "failed to allocate buffer\n");
   5.154 +      fprintf (stderr, "can't allocate bitmap\n");
   5.155        goto fail;
   5.156      }
   5.157  
   5.158 +  if (src_bitmap->rowbytes != scanline_size)
   5.159 +    {
   5.160 +      printf ("image_width %d\n", image_width);
   5.161 +      printf ("rowbytes %d\n", src_bitmap->rowbytes);
   5.162 +      printf ("TIFFScanlineSize %d\n", scanline_size);
   5.163 +    }
   5.164 +
   5.165    for (row = 0; row < image_length; row++)
   5.166 -    {
   5.167 -      TIFFReadScanline (in, buffer, row, 0);
   5.168 -      TIFFWriteScanline (tiff_temp, buffer, row, 0);
   5.169 -    }
   5.170 +    TIFFReadScanline (in,
   5.171 +		      src_bitmap->bits + row * src_bitmap->rowbytes,
   5.172 +		      row,
   5.173 +		      0);
   5.174  
   5.175 -  _TIFFfree (buffer);
   5.176 -  TIFFClose (tiff_temp);
   5.177 +  for (row = 0; row < dest_image_length; row++)
   5.178 +    if (1 != TIFFReadScanline (in,
   5.179 +			       src_bitmap->bits + row * src_bitmap->rowbytes,
   5.180 +			       row,
   5.181 +			       0))
   5.182 +      {
   5.183 +	fprintf (stderr, "can't read TIFF scanline\n");
   5.184 +	goto fail;
   5.185 +      }
   5.186  
   5.187 -  width_points = (image_width / x_resolution) * POINTS_PER_INCH;
   5.188 -  height_points = (image_length / y_resolution) * POINTS_PER_INCH;
   5.189 -
   5.190 -  if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
   5.191 +  dest_bitmap = rotate_bitmap (src_bitmap, input_attributes.rotation);
   5.192 +  if (! dest_bitmap)
   5.193      {
   5.194 -      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   5.195 +      fprintf (stderr, "can't allocate bitmap\n");
   5.196        goto fail;
   5.197      }
   5.198  
   5.199 -  printf ("height_points %d, width_points %d\n", height_points, width_points);
   5.200 +  for (row = 0; row < dest_bitmap->height; row++)
   5.201 +    if (1 != TIFFWriteScanline (tiff_temp,
   5.202 +				dest_bitmap->bits + row * dest_bitmap->rowbytes,
   5.203 +				row,
   5.204 +				0))
   5.205 +      {
   5.206 +	fprintf (stderr, "can't write TIFF scanline\n");
   5.207 +	goto fail;
   5.208 +      }
   5.209 +
   5.210 +  TIFFClose (tiff_temp);
   5.211 +
   5.212 +  free_bitmap (dest_bitmap);
   5.213 +  free_bitmap (src_bitmap);
   5.214  
   5.215    sprintf (pagesize, "[0 0 %d %d]", width_points, height_points);
   5.216  
     6.1 --- a/t2p.h	Tue Jan 01 06:17:39 2002 +0000
     6.2 +++ b/t2p.h	Tue Jan 01 10:16:50 2002 +0000
     6.3 @@ -1,7 +1,12 @@
     6.4  typedef struct
     6.5  {
     6.6 -  page_size_t size;
     6.7 +  boolean has_page_size;
     6.8 +  page_size_t page_size;
     6.9 +
    6.10 +  boolean has_rotation;
    6.11    int rotation;
    6.12 +
    6.13 +  boolean has_crop;
    6.14    crop_t crop;
    6.15  } input_attributes_t;
    6.16  
     7.1 --- a/tumble.c	Tue Jan 01 06:17:39 2002 +0000
     7.2 +++ b/tumble.c	Tue Jan 01 10:16:50 2002 +0000
     7.3 @@ -5,7 +5,7 @@
     7.4   *           encoding.
     7.5   *
     7.6   * Main program
     7.7 - * $Id: tumble.c,v 1.11 2001/12/31 22:11:43 eric Exp $
     7.8 + * $Id: tumble.c,v 1.12 2002/01/01 02:16:50 eric Exp $
     7.9   * Copyright 2001 Eric Smith <eric@brouhaha.com>
    7.10   *
    7.11   * This program is free software; you can redistribute it and/or modify
    7.12 @@ -179,6 +179,42 @@
    7.13  }
    7.14  
    7.15  
    7.16 +static Bitmap *rotate_bitmap (Bitmap *src, int rotation)
    7.17 +{
    7.18 +  Rect src_rect;
    7.19 +  Point dest_upper_left;
    7.20 +  int scan;
    7.21 +
    7.22 +  src_rect.upper_left.x = 0;
    7.23 +  src_rect.upper_left.y = 0;
    7.24 +  src_rect.lower_right.x = src->width;
    7.25 +  src_rect.lower_right.y = src->height;
    7.26 +
    7.27 +  dest_upper_left.x = 0;
    7.28 +  dest_upper_left.y = 0;
    7.29 +
    7.30 +  switch (rotation)
    7.31 +    {
    7.32 +    case 0: scan = ROT_0; break;
    7.33 +    case 90: scan = ROT_90; break;
    7.34 +    case 180: scan = ROT_180; break;
    7.35 +    case 270: scan = ROT_270; break;
    7.36 +    default:
    7.37 +      fprintf (stderr, "rotation must be 0, 90, 180, or 270\n");
    7.38 +      return (NULL);
    7.39 +    }
    7.40 +
    7.41 +  return (bitblt (src,
    7.42 +		  src_rect,
    7.43 +		  NULL,  /* dest_bitmap */
    7.44 +		  dest_upper_left,
    7.45 +		  scan,
    7.46 +		  TF_SRC));
    7.47 +}
    7.48 +
    7.49 +
    7.50 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    7.51 +
    7.52  boolean process_page (int image,  /* range 1 .. n */
    7.53  		      input_attributes_t input_attributes,
    7.54  		      bookmark_t *bookmarks)
    7.55 @@ -186,6 +222,7 @@
    7.56    int result = 0;
    7.57  
    7.58    u32 image_length, image_width;
    7.59 +  u32 dest_image_length, dest_image_width;
    7.60  #ifdef CHECK_DEPTH
    7.61    u32 image_depth;
    7.62  #endif
    7.63 @@ -193,14 +230,19 @@
    7.64    u16 samples_per_pixel;
    7.65    u16 bits_per_sample;
    7.66    u16 planar_config;
    7.67 +
    7.68    u16 resolution_unit;
    7.69    float x_resolution, y_resolution;
    7.70 +  float dest_x_resolution, dest_y_resolution;
    7.71 +
    7.72 +  int scanline_size;
    7.73 +
    7.74    int width_points, height_points;  /* really 1/72 inch units rather than
    7.75  				       points */
    7.76  
    7.77 -
    7.78 -  char *buffer;
    7.79 -  u32 row;
    7.80 +  Bitmap *src_bitmap;
    7.81 +  Bitmap *dest_bitmap;
    7.82 +  int row;
    7.83  
    7.84    panda_page *page;
    7.85  
    7.86 @@ -298,6 +340,17 @@
    7.87        goto fail;
    7.88      }
    7.89  
    7.90 +  width_points = (image_width / x_resolution) * POINTS_PER_INCH;
    7.91 +  height_points = (image_length / y_resolution) * POINTS_PER_INCH;
    7.92 +
    7.93 +  if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
    7.94 +    {
    7.95 +      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
    7.96 +      goto fail;
    7.97 +    }
    7.98 +
    7.99 +  printf ("height_points %d, width_points %d\n", height_points, width_points);
   7.100 +
   7.101    tiff_temp_fd = mkstemp (tiff_temp_fn);
   7.102    if (tiff_temp_fd < 0)
   7.103      {
   7.104 @@ -312,47 +365,92 @@
   7.105        goto fail;
   7.106      }
   7.107  
   7.108 -  TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, image_length);
   7.109 -  TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, image_width);
   7.110 +  printf ("rotation %d\n", input_attributes.rotation);
   7.111 +
   7.112 +  if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   7.113 +    {
   7.114 +      dest_image_width  = image_length;
   7.115 +      dest_image_length = image_width;
   7.116 +      dest_x_resolution = y_resolution;
   7.117 +      dest_y_resolution = x_resolution;
   7.118 +      SWAP (int, width_points, height_points);
   7.119 +    }
   7.120 +  else
   7.121 +    {
   7.122 +      dest_image_width = image_width;
   7.123 +      dest_image_length = image_length;
   7.124 +      dest_x_resolution = x_resolution;
   7.125 +      dest_y_resolution = y_resolution;
   7.126 +    }
   7.127 +
   7.128 +  TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, dest_image_length);
   7.129 +  TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, dest_image_width);
   7.130    TIFFSetField (tiff_temp, TIFFTAG_PLANARCONFIG, planar_config);
   7.131  
   7.132 -  TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, image_length);
   7.133 +  TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, dest_image_length);
   7.134  
   7.135    TIFFSetField (tiff_temp, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
   7.136 -  TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, x_resolution);
   7.137 -  TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, y_resolution);
   7.138 +  TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, dest_x_resolution);
   7.139 +  TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, dest_y_resolution);
   7.140  
   7.141    TIFFSetField (tiff_temp, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel);
   7.142    TIFFSetField (tiff_temp, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
   7.143    TIFFSetField (tiff_temp, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
   7.144    TIFFSetField (tiff_temp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
   7.145  
   7.146 -  buffer = _TIFFmalloc (TIFFScanlineSize (in));
   7.147 -  if (! buffer)
   7.148 +  scanline_size = TIFFScanlineSize (in);
   7.149 +
   7.150 +  src_bitmap = create_bitmap (image_width, image_length);
   7.151 +  if (! src_bitmap)
   7.152      {
   7.153 -      fprintf (stderr, "failed to allocate buffer\n");
   7.154 +      fprintf (stderr, "can't allocate bitmap\n");
   7.155        goto fail;
   7.156      }
   7.157  
   7.158 +  if (src_bitmap->rowbytes != scanline_size)
   7.159 +    {
   7.160 +      printf ("image_width %d\n", image_width);
   7.161 +      printf ("rowbytes %d\n", src_bitmap->rowbytes);
   7.162 +      printf ("TIFFScanlineSize %d\n", scanline_size);
   7.163 +    }
   7.164 +
   7.165    for (row = 0; row < image_length; row++)
   7.166 -    {
   7.167 -      TIFFReadScanline (in, buffer, row, 0);
   7.168 -      TIFFWriteScanline (tiff_temp, buffer, row, 0);
   7.169 -    }
   7.170 +    TIFFReadScanline (in,
   7.171 +		      src_bitmap->bits + row * src_bitmap->rowbytes,
   7.172 +		      row,
   7.173 +		      0);
   7.174  
   7.175 -  _TIFFfree (buffer);
   7.176 -  TIFFClose (tiff_temp);
   7.177 +  for (row = 0; row < dest_image_length; row++)
   7.178 +    if (1 != TIFFReadScanline (in,
   7.179 +			       src_bitmap->bits + row * src_bitmap->rowbytes,
   7.180 +			       row,
   7.181 +			       0))
   7.182 +      {
   7.183 +	fprintf (stderr, "can't read TIFF scanline\n");
   7.184 +	goto fail;
   7.185 +      }
   7.186  
   7.187 -  width_points = (image_width / x_resolution) * POINTS_PER_INCH;
   7.188 -  height_points = (image_length / y_resolution) * POINTS_PER_INCH;
   7.189 -
   7.190 -  if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS))
   7.191 +  dest_bitmap = rotate_bitmap (src_bitmap, input_attributes.rotation);
   7.192 +  if (! dest_bitmap)
   7.193      {
   7.194 -      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   7.195 +      fprintf (stderr, "can't allocate bitmap\n");
   7.196        goto fail;
   7.197      }
   7.198  
   7.199 -  printf ("height_points %d, width_points %d\n", height_points, width_points);
   7.200 +  for (row = 0; row < dest_bitmap->height; row++)
   7.201 +    if (1 != TIFFWriteScanline (tiff_temp,
   7.202 +				dest_bitmap->bits + row * dest_bitmap->rowbytes,
   7.203 +				row,
   7.204 +				0))
   7.205 +      {
   7.206 +	fprintf (stderr, "can't write TIFF scanline\n");
   7.207 +	goto fail;
   7.208 +      }
   7.209 +
   7.210 +  TIFFClose (tiff_temp);
   7.211 +
   7.212 +  free_bitmap (dest_bitmap);
   7.213 +  free_bitmap (src_bitmap);
   7.214  
   7.215    sprintf (pagesize, "[0 0 %d %d]", width_points, height_points);
   7.216  
     8.1 --- a/tumble.h	Tue Jan 01 06:17:39 2002 +0000
     8.2 +++ b/tumble.h	Tue Jan 01 10:16:50 2002 +0000
     8.3 @@ -1,7 +1,12 @@
     8.4  typedef struct
     8.5  {
     8.6 -  page_size_t size;
     8.7 +  boolean has_page_size;
     8.8 +  page_size_t page_size;
     8.9 +
    8.10 +  boolean has_rotation;
    8.11    int rotation;
    8.12 +
    8.13 +  boolean has_crop;
    8.14    crop_t crop;
    8.15  } input_attributes_t;
    8.16