1.1 diff -r 2cec996b38bc -r 3aac131058da tumble.c 1.2 --- a/tumble.c Tue Jan 01 06:17:39 2002 +0000 1.3 +++ b/tumble.c Tue Jan 01 10:16:50 2002 +0000 1.4 @@ -5,7 +5,7 @@ 1.5 * encoding. 1.6 * 1.7 * Main program 1.8 - * $Id: tumble.c,v 1.11 2001/12/31 22:11:43 eric Exp $ 1.9 + * $Id: tumble.c,v 1.12 2002/01/01 02:16:50 eric Exp $ 1.10 * Copyright 2001 Eric Smith <eric@brouhaha.com> 1.11 * 1.12 * This program is free software; you can redistribute it and/or modify 1.13 @@ -179,6 +179,42 @@ 1.14 } 1.15 1.16 1.17 +static Bitmap *rotate_bitmap (Bitmap *src, int rotation) 1.18 +{ 1.19 + Rect src_rect; 1.20 + Point dest_upper_left; 1.21 + int scan; 1.22 + 1.23 + src_rect.upper_left.x = 0; 1.24 + src_rect.upper_left.y = 0; 1.25 + src_rect.lower_right.x = src->width; 1.26 + src_rect.lower_right.y = src->height; 1.27 + 1.28 + dest_upper_left.x = 0; 1.29 + dest_upper_left.y = 0; 1.30 + 1.31 + switch (rotation) 1.32 + { 1.33 + case 0: scan = ROT_0; break; 1.34 + case 90: scan = ROT_90; break; 1.35 + case 180: scan = ROT_180; break; 1.36 + case 270: scan = ROT_270; break; 1.37 + default: 1.38 + fprintf (stderr, "rotation must be 0, 90, 180, or 270\n"); 1.39 + return (NULL); 1.40 + } 1.41 + 1.42 + return (bitblt (src, 1.43 + src_rect, 1.44 + NULL, /* dest_bitmap */ 1.45 + dest_upper_left, 1.46 + scan, 1.47 + TF_SRC)); 1.48 +} 1.49 + 1.50 + 1.51 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 1.52 + 1.53 boolean process_page (int image, /* range 1 .. n */ 1.54 input_attributes_t input_attributes, 1.55 bookmark_t *bookmarks) 1.56 @@ -186,6 +222,7 @@ 1.57 int result = 0; 1.58 1.59 u32 image_length, image_width; 1.60 + u32 dest_image_length, dest_image_width; 1.61 #ifdef CHECK_DEPTH 1.62 u32 image_depth; 1.63 #endif 1.64 @@ -193,14 +230,19 @@ 1.65 u16 samples_per_pixel; 1.66 u16 bits_per_sample; 1.67 u16 planar_config; 1.68 + 1.69 u16 resolution_unit; 1.70 float x_resolution, y_resolution; 1.71 + float dest_x_resolution, dest_y_resolution; 1.72 + 1.73 + int scanline_size; 1.74 + 1.75 int width_points, height_points; /* really 1/72 inch units rather than 1.76 points */ 1.77 1.78 - 1.79 - char *buffer; 1.80 - u32 row; 1.81 + Bitmap *src_bitmap; 1.82 + Bitmap *dest_bitmap; 1.83 + int row; 1.84 1.85 panda_page *page; 1.86 1.87 @@ -298,6 +340,17 @@ 1.88 goto fail; 1.89 } 1.90 1.91 + width_points = (image_width / x_resolution) * POINTS_PER_INCH; 1.92 + height_points = (image_length / y_resolution) * POINTS_PER_INCH; 1.93 + 1.94 + if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS)) 1.95 + { 1.96 + fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES); 1.97 + goto fail; 1.98 + } 1.99 + 1.100 + printf ("height_points %d, width_points %d\n", height_points, width_points); 1.101 + 1.102 tiff_temp_fd = mkstemp (tiff_temp_fn); 1.103 if (tiff_temp_fd < 0) 1.104 { 1.105 @@ -312,47 +365,92 @@ 1.106 goto fail; 1.107 } 1.108 1.109 - TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, image_length); 1.110 - TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, image_width); 1.111 + printf ("rotation %d\n", input_attributes.rotation); 1.112 + 1.113 + if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270)) 1.114 + { 1.115 + dest_image_width = image_length; 1.116 + dest_image_length = image_width; 1.117 + dest_x_resolution = y_resolution; 1.118 + dest_y_resolution = x_resolution; 1.119 + SWAP (int, width_points, height_points); 1.120 + } 1.121 + else 1.122 + { 1.123 + dest_image_width = image_width; 1.124 + dest_image_length = image_length; 1.125 + dest_x_resolution = x_resolution; 1.126 + dest_y_resolution = y_resolution; 1.127 + } 1.128 + 1.129 + TIFFSetField (tiff_temp, TIFFTAG_IMAGELENGTH, dest_image_length); 1.130 + TIFFSetField (tiff_temp, TIFFTAG_IMAGEWIDTH, dest_image_width); 1.131 TIFFSetField (tiff_temp, TIFFTAG_PLANARCONFIG, planar_config); 1.132 1.133 - TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, image_length); 1.134 + TIFFSetField (tiff_temp, TIFFTAG_ROWSPERSTRIP, dest_image_length); 1.135 1.136 TIFFSetField (tiff_temp, TIFFTAG_RESOLUTIONUNIT, resolution_unit); 1.137 - TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, x_resolution); 1.138 - TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, y_resolution); 1.139 + TIFFSetField (tiff_temp, TIFFTAG_XRESOLUTION, dest_x_resolution); 1.140 + TIFFSetField (tiff_temp, TIFFTAG_YRESOLUTION, dest_y_resolution); 1.141 1.142 TIFFSetField (tiff_temp, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel); 1.143 TIFFSetField (tiff_temp, TIFFTAG_BITSPERSAMPLE, bits_per_sample); 1.144 TIFFSetField (tiff_temp, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); 1.145 TIFFSetField (tiff_temp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); 1.146 1.147 - buffer = _TIFFmalloc (TIFFScanlineSize (in)); 1.148 - if (! buffer) 1.149 + scanline_size = TIFFScanlineSize (in); 1.150 + 1.151 + src_bitmap = create_bitmap (image_width, image_length); 1.152 + if (! src_bitmap) 1.153 { 1.154 - fprintf (stderr, "failed to allocate buffer\n"); 1.155 + fprintf (stderr, "can't allocate bitmap\n"); 1.156 goto fail; 1.157 } 1.158 1.159 + if (src_bitmap->rowbytes != scanline_size) 1.160 + { 1.161 + printf ("image_width %d\n", image_width); 1.162 + printf ("rowbytes %d\n", src_bitmap->rowbytes); 1.163 + printf ("TIFFScanlineSize %d\n", scanline_size); 1.164 + } 1.165 + 1.166 for (row = 0; row < image_length; row++) 1.167 - { 1.168 - TIFFReadScanline (in, buffer, row, 0); 1.169 - TIFFWriteScanline (tiff_temp, buffer, row, 0); 1.170 - } 1.171 + TIFFReadScanline (in, 1.172 + src_bitmap->bits + row * src_bitmap->rowbytes, 1.173 + row, 1.174 + 0); 1.175 1.176 - _TIFFfree (buffer); 1.177 - TIFFClose (tiff_temp); 1.178 + for (row = 0; row < dest_image_length; row++) 1.179 + if (1 != TIFFReadScanline (in, 1.180 + src_bitmap->bits + row * src_bitmap->rowbytes, 1.181 + row, 1.182 + 0)) 1.183 + { 1.184 + fprintf (stderr, "can't read TIFF scanline\n"); 1.185 + goto fail; 1.186 + } 1.187 1.188 - width_points = (image_width / x_resolution) * POINTS_PER_INCH; 1.189 - height_points = (image_length / y_resolution) * POINTS_PER_INCH; 1.190 - 1.191 - if ((height_points > PAGE_MAX_POINTS) || (width_points > PAGE_MAX_POINTS)) 1.192 + dest_bitmap = rotate_bitmap (src_bitmap, input_attributes.rotation); 1.193 + if (! dest_bitmap) 1.194 { 1.195 - fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES); 1.196 + fprintf (stderr, "can't allocate bitmap\n"); 1.197 goto fail; 1.198 } 1.199 1.200 - printf ("height_points %d, width_points %d\n", height_points, width_points); 1.201 + for (row = 0; row < dest_bitmap->height; row++) 1.202 + if (1 != TIFFWriteScanline (tiff_temp, 1.203 + dest_bitmap->bits + row * dest_bitmap->rowbytes, 1.204 + row, 1.205 + 0)) 1.206 + { 1.207 + fprintf (stderr, "can't write TIFF scanline\n"); 1.208 + goto fail; 1.209 + } 1.210 + 1.211 + TIFFClose (tiff_temp); 1.212 + 1.213 + free_bitmap (dest_bitmap); 1.214 + free_bitmap (src_bitmap); 1.215 1.216 sprintf (pagesize, "[0 0 %d %d]", width_points, height_points); 1.217