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