New comit of SDL2
[supertux.git] / src / SDL2 / external / tiff-4.0.3 / tools / tiffcrop.c
1 /* $Id: tiffcrop.c,v 1.20 2010-12-14 02:03:24 faxguy Exp $ */
2
3 /* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
4  * the image data through additional options listed below
5  *
6  * Original code:
7  * Copyright (c) 1988-1997 Sam Leffler
8  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
9  * Additions (c) Richard Nolde 2006-2010 
10  *
11  * Permission to use, copy, modify, distribute, and sell this software and 
12  * its documentation for any purpose is hereby granted without fee, provided
13  * that (i) the above copyright notices and this permission notice appear in
14  * all copies of the software and related documentation, and (ii) the names of
15  * Sam Leffler and Silicon Graphics may not be used in any advertising or
16  * publicity relating to the software without the specific, prior written
17  * permission of Sam Leffler and Silicon Graphics.
18  * 
19  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
20  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
21  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
22  * 
23  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS OR ANY OTHER COPYRIGHT  
24  * HOLDERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL 
25  * DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
26  * DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND 
27  * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
28  * OR PERFORMANCE OF THIS SOFTWARE.
29  *
30  * Some portions of the current code are derived from tiffcp, primarly in 
31  * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though
32  * some of the original functions have been extended to support arbitrary bit
33  * depths. These functions are presented at the top of this file.
34  *
35  * Add support for the options below to extract sections of image(s) 
36  * and to modify the whole image or selected portions of each image by
37  * rotations, mirroring, and colorscale/colormap inversion of selected
38  * types of TIFF images when appropriate. Some color model dependent 
39  * functions are restricted to bilevel or 8 bit per sample data.
40  * See the man page for the full explanations.
41  *
42  * New Options: 
43  * -h             Display the syntax guide.
44  * -v             Report the version and last build date for tiffcrop and libtiff.
45  * -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1 
46  *                Specify a series of coordinates to define rectangular
47  *                regions by the top left and lower right corners.
48  * -e c|d|i|m|s   export mode for images and selections from input images
49  *   combined     All images and selections are written to a single file (default)
50  *                with multiple selections from one image combined into a single image
51  *   divided      All images and selections are written to a single file
52  *                with each selection from one image written to a new image
53  *   image        Each input image is written to a new file (numeric filename sequence)
54  *                with multiple selections from the image combined into one image
55  *   multiple     Each input image is written to a new file (numeric filename sequence)
56  *                with each selection from the image written to a new image
57  *   separated    Individual selections from each image are written to separate files
58  * -U units       [in, cm, px ] inches, centimeters or pixels
59  * -H #           Set horizontal resolution of output images to #
60  * -V #           Set vertical resolution of output images to #
61  * -J #           Horizontal margin of output page to # expressed in current
62  *                units when sectioning image into columns x rows 
63  *                using the -S cols:rows option.
64  * -K #           Vertical margin of output page to # expressed in current
65  *                units when sectioning image into columns x rows
66  *                using the -S cols:rows option.
67  * -X #           Horizontal dimension of region to extract expressed in current
68  *                units
69  * -Y #           Vertical dimension of region to extract expressed in current
70  *                units
71  * -O orient      Orientation for output image, portrait, landscape, auto
72  * -P page        Page size for output image segments, eg letter, legal, tabloid,
73  *                etc.
74  * -S cols:rows   Divide the image into equal sized segments using cols across
75  *                and rows down
76  * -E t|l|r|b     Edge to use as origin
77  * -m #,#,#,#     Margins from edges for selection: top, left, bottom, right
78  *                (commas separated)
79  * -Z #:#,#:#     Zones of the image designated as zone X of Y, 
80  *                eg 1:3 would be first of three equal portions measured
81  *                from reference edge
82  * -N odd|even|#,#-#,#|last 
83  *                Select sequences and/or ranges of images within file
84  *                to process. The words odd or even may be used to specify
85  *                all odd or even numbered images the word last may be used
86  *                in place of a number in the sequence to indicate the final
87  *                image in the file without knowing how many images there are.
88  * -R #           Rotate image or crop selection by 90,180,or 270 degrees
89  *                clockwise  
90  * -F h|v         Flip (mirror) image or crop selection horizontally
91  *                or vertically 
92  * -I [black|white|data|both]
93  *                Invert color space, eg dark to light for bilevel and grayscale images
94  *                If argument is white or black, set the PHOTOMETRIC_INTERPRETATION 
95  *                tag to MinIsBlack or MinIsWhite without altering the image data
96  *                If the argument is data or both, the image data are modified:
97  *                both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
98  *                data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
99  * -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
100  *                Dump raw data for input and/or output images to individual files
101  *                in raw (binary) format or text (ASCII) representing binary data
102  *                as strings of 1s and 0s. The filename arguments are used as stems
103  *                from which individual files are created for each image. Text format
104  *                includes annotations for image parameters and scanline info. Level
105  *                selects which functions dump data, with higher numbers selecting
106  *                lower level, scanline level routines. Debug reports a limited set
107  *                of messages to monitor progess without enabling dump logs.
108  */
109
110 static   char tiffcrop_version_id[] = "2.4";
111 static   char tiffcrop_rev_date[] = "12-13-2010";
112
113 #include "tif_config.h"
114 #include "tiffiop.h"
115
116 #include <stdio.h>
117 #include <stdlib.h>
118 #include <string.h>
119 #include <math.h>
120 #include <ctype.h>
121 #include <limits.h>
122 #include <sys/stat.h>
123 #include <assert.h>
124
125 #ifdef HAVE_UNISTD_H
126 # include <unistd.h>
127 #endif
128
129 #ifdef HAVE_STDINT_H
130 # include <stdint.h>
131 #endif
132
133 #ifndef HAVE_GETOPT
134 extern int getopt(int, char**, char*);
135 #endif
136
137 #ifdef NEED_LIBPORT
138 # include "libport.h"
139 #endif
140
141 #include "tiffio.h"
142
143 #if defined(VMS)
144 # define unlink delete
145 #endif
146
147 #ifndef PATH_MAX
148 #define PATH_MAX 1024
149 #endif
150
151 #ifndef streq
152 #define streq(a,b)      (strcmp((a),(b)) == 0)
153 #endif
154 #define strneq(a,b,n)   (strncmp((a),(b),(n)) == 0)
155
156 #define TRUE    1
157 #define FALSE   0
158
159 #ifndef TIFFhowmany
160 #define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
161 #define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
162 #endif
163
164 /*
165  * Definitions and data structures required to support cropping and image
166  * manipulations.
167  */
168
169 #define EDGE_TOP      1
170 #define EDGE_LEFT     2
171 #define EDGE_BOTTOM   3
172 #define EDGE_RIGHT    4
173 #define EDGE_CENTER   5
174
175 #define MIRROR_HORIZ  1
176 #define MIRROR_VERT   2
177 #define MIRROR_BOTH   3
178 #define ROTATECW_90   8
179 #define ROTATECW_180 16
180 #define ROTATECW_270 32
181 #define ROTATE_ANY ROTATECW_90 || ROTATECW_180 || ROTATECW_270 
182
183 #define CROP_NONE     0
184 #define CROP_MARGINS  1
185 #define CROP_WIDTH    2
186 #define CROP_LENGTH   4
187 #define CROP_ZONES    8
188 #define CROP_REGIONS 16
189 #define CROP_ROTATE  32
190 #define CROP_MIRROR  64
191 #define CROP_INVERT 128
192
193 /* Modes for writing out images and selections */
194 #define ONE_FILE_COMPOSITE       0 /* One file, sections combined sections */
195 #define ONE_FILE_SEPARATED       1 /* One file, sections to new IFDs */
196 #define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
197 #define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
198 #define FILE_PER_SELECTION       4 /* One file per selection */
199
200 #define COMPOSITE_IMAGES         0 /* Selections combined into one image */  
201 #define SEPARATED_IMAGES         1 /* Selections saved to separate images */
202
203 #define STRIP    1
204 #define TILE     2
205
206 #define MAX_REGIONS   8  /* number of regions to extract from a single page */
207 #define MAX_OUTBUFFS  8  /* must match larger of zones or regions */
208 #define MAX_SECTIONS 32  /* number of sections per page to write to output */
209 #define MAX_IMAGES 2048  /* number of images in descrete list, not in the file */
210 #define MAX_SAMPLES   8  /* maximum number of samples per pixel supported */
211 #define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
212 #define MAX_EXPORT_PAGES 999999  /* maximum number of export pages per file */
213
214 #define DUMP_NONE   0
215 #define DUMP_TEXT   1
216 #define DUMP_RAW    2
217
218 /* Offsets into buffer for margins and fixed width and length segments */
219 struct offset {
220   uint32  tmargin;
221   uint32  lmargin;
222   uint32  bmargin;
223   uint32  rmargin;
224   uint32  crop_width;
225   uint32  crop_length;
226   uint32  startx;
227   uint32  endx;
228   uint32  starty;
229   uint32  endy;
230 };
231
232 /* Description of a zone within the image. Position 1 of 3 zones would be 
233  * the first third of the image. These are computed after margins and 
234  * width/length requests are applied so that you can extract multiple 
235  * zones from within a larger region for OCR or barcode recognition.
236  */
237
238 struct  buffinfo {
239   uint32 size;           /* size of this buffer */
240   unsigned char *buffer; /* address of the allocated buffer */
241 };
242
243 struct  zone {
244   int   position;  /* ordinal of segment to be extracted */
245   int   total;     /* total equal sized divisions of crop area */
246   };
247
248 struct  pageseg {
249   uint32 x1;        /* index of left edge */
250   uint32 x2;        /* index of right edge */
251   uint32 y1;        /* index of top edge */
252   uint32 y2;        /* index of bottom edge */
253   int    position;  /* ordinal of segment to be extracted */
254   int    total;     /* total equal sized divisions of crop area */
255   uint32 buffsize;  /* size of buffer needed to hold the cropped zone */
256 };
257
258 struct  coordpairs {
259   double X1;        /* index of left edge in current units */
260   double X2;        /* index of right edge in current units */
261   double Y1;        /* index of top edge in current units */
262   double Y2;        /* index of bottom edge in current units */
263 };
264
265 struct  region {
266   uint32 x1;        /* pixel offset of left edge */
267   uint32 x2;        /* pixel offset of right edge */
268   uint32 y1;        /* pixel offset of top edge */
269   uint32 y2;        /* picel offset of bottom edge */
270   uint32 width;     /* width in pixels */
271   uint32 length;    /* length in pixels */
272   uint32 buffsize;  /* size of buffer needed to hold the cropped region */
273   unsigned char *buffptr; /* address of start of the region */
274 };
275
276 /* Cropping parameters from command line and image data 
277  * Note: This should be renamed to proc_opts and expanded to include all current globals
278  * if possible, but each function that accesses global variables will have to be redone.
279  */
280 struct crop_mask {
281   double width;           /* Selection width for master crop region in requested units */
282   double length;          /* Selection length for master crop region in requesed units */
283   double margins[4];      /* Top, left, bottom, right margins */
284   float  xres;            /* Horizontal resolution read from image*/
285   float  yres;            /* Vertical resolution read from image */
286   uint32 combined_width;  /* Width of combined cropped zones */
287   uint32 combined_length; /* Length of combined cropped zones */
288   uint32 bufftotal;       /* Size of buffer needed to hold all the cropped region */
289   uint16 img_mode;        /* Composite or separate images created from zones or regions */
290   uint16 exp_mode;        /* Export input images or selections to one or more files */
291   uint16 crop_mode;       /* Crop options to be applied */
292   uint16 res_unit;        /* Resolution unit for margins and selections */
293   uint16 edge_ref;        /* Reference edge for sections extraction and combination */
294   uint16 rotation;        /* Clockwise rotation of the extracted region or image */
295   uint16 mirror;          /* Mirror extracted region or image horizontally or vertically */
296   uint16 invert;          /* Invert the color map of image or region */
297   uint16 photometric;     /* Status of photometric interpretation for inverted image */
298   uint16 selections;      /* Number of regions or zones selected */
299   uint16 regions;         /* Number of regions delimited by corner coordinates */
300   struct region regionlist[MAX_REGIONS]; /* Regions within page or master crop region */
301   uint16 zones;           /* Number of zones delimited by Ordinal:Total requested */
302   struct zone zonelist[MAX_REGIONS]; /* Zones indices to define a region */
303   struct coordpairs corners[MAX_REGIONS]; /* Coordinates of upper left and lower right corner */
304 };
305
306 #define MAX_PAPERNAMES 49
307 #define MAX_PAPERNAME_LENGTH 15
308 #define DEFAULT_RESUNIT      RESUNIT_INCH
309 #define DEFAULT_PAGE_HEIGHT   14.0
310 #define DEFAULT_PAGE_WIDTH     8.5
311 #define DEFAULT_RESOLUTION   300
312 #define DEFAULT_PAPER_SIZE  "legal"
313
314 #define ORIENTATION_NONE       0
315 #define ORIENTATION_PORTRAIT   1
316 #define ORIENTATION_LANDSCAPE  2
317 #define ORIENTATION_SEASCAPE   4
318 #define ORIENTATION_AUTO      16
319
320 #define PAGE_MODE_NONE         0
321 #define PAGE_MODE_RESOLUTION   1
322 #define PAGE_MODE_PAPERSIZE    2
323 #define PAGE_MODE_MARGINS      4
324 #define PAGE_MODE_ROWSCOLS     8
325
326 #define INVERT_DATA_ONLY      10
327 #define INVERT_DATA_AND_TAG   11
328
329 struct paperdef {
330   char   name[MAX_PAPERNAME_LENGTH];
331   double width;
332   double length;
333   double asratio;
334   };
335
336 /* European page sizes corrected from update sent by 
337  * thomas . jarosch @ intra2net . com on 5/7/2010
338  * Paper Size       Width   Length  Aspect Ratio */
339 struct paperdef PaperTable[MAX_PAPERNAMES] = {
340   {"default",         8.500,  14.000,  0.607},
341   {"pa4",             8.264,  11.000,  0.751},
342   {"letter",          8.500,  11.000,  0.773},
343   {"legal",           8.500,  14.000,  0.607},
344   {"half-letter",     8.500,   5.514,  1.542},
345   {"executive",       7.264,  10.528,  0.690},
346   {"tabloid",        11.000,  17.000,  0.647},
347   {"11x17",          11.000,  17.000,  0.647},
348   {"ledger",         17.000,  11.000,  1.545},
349   {"archa",           9.000,  12.000,  0.750},
350   {"archb",          12.000,  18.000,  0.667},
351   {"archc",          18.000,  24.000,  0.750},
352   {"archd",          24.000,  36.000,  0.667},
353   {"arche",          36.000,  48.000,  0.750},
354   {"csheet",         17.000,  22.000,  0.773},
355   {"dsheet",         22.000,  34.000,  0.647},
356   {"esheet",         34.000,  44.000,  0.773},
357   {"superb",         11.708,  17.042,  0.687},
358   {"commercial",      4.139,   9.528,  0.434},
359   {"monarch",         3.889,   7.528,  0.517},
360   {"envelope-dl",     4.333,   8.681,  0.499},
361   {"envelope-c5",     6.389,   9.028,  0.708},
362   {"europostcard",    4.139,   5.833,  0.710},
363   {"a0",             33.110,  46.811,  0.707},
364   {"a1",             23.386,  33.110,  0.706},
365   {"a2",             16.535,  23.386,  0.707},
366   {"a3",             11.693,  16.535,  0.707},
367   {"a4",              8.268,  11.693,  0.707},
368   {"a5",              5.827,   8.268,  0.705},
369   {"a6",              4.134,   5.827,  0.709},
370   {"a7",              2.913,   4.134,  0.705},
371   {"a8",              2.047,   2.913,  0.703},
372   {"a9",              1.457,   2.047,  0.712},
373   {"a10",             1.024,   1.457,  0.703},
374   {"b0",             39.370,  55.669,  0.707},
375   {"b1",             27.835,  39.370,  0.707},
376   {"b2",             19.685,  27.835,  0.707},
377   {"b3",             13.898,  19.685,  0.706},
378   {"b4",              9.843,  13.898,  0.708},
379   {"b5",              6.929,   9.843,  0.704},
380   {"b6",              4.921,   6.929,  0.710},
381   {"c0",             36.102,  51.063,  0.707},
382   {"c1",             25.512,  36.102,  0.707},
383   {"c2",             18.031,  25.512,  0.707},
384   {"c3",             12.756,  18.031,  0.707},
385   {"c4",              9.016,  12.756,  0.707},
386   {"c5",              6.378,   9.016,  0.707},
387   {"c6",              4.488,   6.378,  0.704},
388   {"",                0.000,   0.000,  1.000}
389 };
390
391 /* Structure to define input image parameters */
392 struct image_data {
393   float  xres;
394   float  yres;
395   uint32 width;
396   uint32 length;
397   uint16 res_unit;
398   uint16 bps;
399   uint16 spp;
400   uint16 planar;
401   uint16 photometric;
402   uint16 orientation;
403   uint16 compression;
404   uint16 adjustments;
405 };
406
407 /* Structure to define the output image modifiers */
408 struct pagedef {
409   char          name[16];
410   double        width;    /* width in pixels */
411   double        length;   /* length in pixels */
412   double        hmargin;  /* margins to subtract from width of sections */
413   double        vmargin;  /* margins to subtract from height of sections */
414   double        hres;     /* horizontal resolution for output */
415   double        vres;     /* vertical resolution for output */
416   uint32        mode;     /* bitmask of modifiers to page format */
417   uint16        res_unit; /* resolution unit for output image */
418   unsigned int  rows;     /* number of section rows */
419   unsigned int  cols;     /* number of section cols */
420   unsigned int  orient;   /* portrait, landscape, seascape, auto */
421 };
422
423 struct dump_opts {
424   int  debug;
425   int  format;
426   int  level;
427   char mode[4];
428   char infilename[PATH_MAX + 1];
429   char outfilename[PATH_MAX + 1];
430   FILE *infile;
431   FILE *outfile;
432   };
433
434 /* globals */
435 static int    outtiled = -1;
436 static uint32 tilewidth = 0;
437 static uint32 tilelength = 0;
438
439 static uint16 config = 0;
440 static uint16 compression = 0;
441 static uint16 predictor = 0;
442 static uint16 fillorder = 0;
443 static uint32 rowsperstrip = 0;
444 static uint32 g3opts = 0;
445 static int    ignore = FALSE;           /* if true, ignore read errors */
446 static uint32 defg3opts = (uint32) -1;
447 static int    quality = 100;            /* JPEG quality */
448 /* static int    jpegcolormode = -1;        was JPEGCOLORMODE_RGB;  */
449 static int    jpegcolormode = JPEGCOLORMODE_RGB;
450 static uint16 defcompression = (uint16) -1;
451 static uint16 defpredictor = (uint16) -1;
452 static int    pageNum = 0;
453 static int    little_endian = 1;
454
455 /* Functions adapted from tiffcp with additions or significant modifications */
456 static int  readContigStripsIntoBuffer   (TIFF*, uint8*);
457 static int  readSeparateStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
458 static int  readContigTilesIntoBuffer    (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
459 static int  readSeparateTilesIntoBuffer  (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
460 static int  writeBufferToContigStrips    (TIFF*, uint8*, uint32);
461 static int  writeBufferToContigTiles     (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
462 static int  writeBufferToSeparateStrips  (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
463 static int  writeBufferToSeparateTiles   (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
464 static int  extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, tsample_t, 
465                                          uint16, uint16, struct dump_opts *);
466 static int processCompressOptions(char*);
467 static void usage(void);
468
469 /* All other functions by Richard Nolde,  not found in tiffcp */
470 static void initImageData (struct image_data *);
471 static void initCropMasks (struct crop_mask *);
472 static void initPageSetup (struct pagedef *, struct pageseg *, struct buffinfo []);
473 static void initDumpOptions(struct dump_opts *);
474
475 /* Command line and file naming functions */
476 void  process_command_opts (int, char *[], char *, char *, uint32 *,
477                             uint16 *, uint16 *, uint32 *, uint32 *, uint32 *,
478                             struct crop_mask *, struct pagedef *, 
479                             struct dump_opts *, 
480                             unsigned int *, unsigned int *);
481 static  int update_output_file (TIFF **, char *, int, char *, unsigned int *);
482
483
484 /*  * High level functions for whole image manipulation */
485 static int  get_page_geometry (char *, struct pagedef*);
486 static int  computeInputPixelOffsets(struct crop_mask *, struct image_data *, 
487                                      struct offset *);
488 static int  computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
489                                        struct pagedef *, struct pageseg *,
490                                        struct dump_opts *);
491 static int  loadImage(TIFF *, struct image_data *, struct dump_opts *, unsigned char **);
492 static int  correct_orientation(struct image_data *, unsigned char **);
493 static int  getCropOffsets(struct image_data *, struct crop_mask *, struct dump_opts *);
494 static int  processCropSelections(struct image_data *, struct crop_mask *, 
495                                   unsigned char **, struct buffinfo []);
496 static int  writeSelections(TIFF *, TIFF **, struct crop_mask *, struct image_data *,
497                             struct dump_opts *, struct buffinfo [],
498                             char *, char *, unsigned int*, unsigned int);
499
500 /* Section functions */
501 static int  createImageSection(uint32, unsigned char **);
502 static int  extractImageSection(struct image_data *, struct pageseg *, 
503                                 unsigned char *, unsigned char *);
504 static int  writeSingleSection(TIFF *, TIFF *, struct image_data *,
505                                struct dump_opts *, uint32, uint32,
506                                double, double, unsigned char *);
507 static int  writeImageSections(TIFF *, TIFF *, struct image_data *,
508                                struct pagedef *, struct pageseg *, 
509                                struct dump_opts *, unsigned char *, 
510                                unsigned char **);
511 /* Whole image functions */
512 static int  createCroppedImage(struct image_data *, struct crop_mask *, 
513                                unsigned char **, unsigned char **);
514 static int  writeCroppedImage(TIFF *, TIFF *, struct image_data *image,
515                               struct dump_opts * dump,
516                               uint32, uint32, unsigned char *, int, int);
517
518 /* Image manipulation functions */
519 static int rotateContigSamples8bits(uint16, uint16, uint16, uint32, 
520                                     uint32,   uint32, uint8 *, uint8 *);
521 static int rotateContigSamples16bits(uint16, uint16, uint16, uint32, 
522                                      uint32,   uint32, uint8 *, uint8 *);
523 static int rotateContigSamples24bits(uint16, uint16, uint16, uint32, 
524                                      uint32,   uint32, uint8 *, uint8 *);
525 static int rotateContigSamples32bits(uint16, uint16, uint16, uint32, 
526                                      uint32,   uint32, uint8 *, uint8 *);
527 static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
528                        unsigned char **);
529 static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
530                        unsigned char *);
531 static int invertImage(uint16, uint16, uint16, uint32, uint32,
532                        unsigned char *);
533
534 /* Functions to reverse the sequence of samples in a scanline */
535 static int reverseSamples8bits  (uint16, uint16, uint32, uint8 *, uint8 *);
536 static int reverseSamples16bits (uint16, uint16, uint32, uint8 *, uint8 *);
537 static int reverseSamples24bits (uint16, uint16, uint32, uint8 *, uint8 *);
538 static int reverseSamples32bits (uint16, uint16, uint32, uint8 *, uint8 *);
539 static int reverseSamplesBytes  (uint16, uint16, uint32, uint8 *, uint8 *);
540
541 /* Functions for manipulating individual samples in an image */
542 static int extractSeparateRegion(struct image_data *, struct crop_mask *,
543                                  unsigned char *, unsigned char *, int);
544 static int extractCompositeRegions(struct image_data *,  struct crop_mask *,
545                                    unsigned char *, unsigned char *);
546 static int extractContigSamples8bits (uint8 *, uint8 *, uint32,
547                                      tsample_t, uint16, uint16, 
548                                      tsample_t, uint32, uint32);
549 static int extractContigSamples16bits (uint8 *, uint8 *, uint32,
550                                       tsample_t, uint16, uint16, 
551                                       tsample_t, uint32, uint32);
552 static int extractContigSamples24bits (uint8 *, uint8 *, uint32,
553                                       tsample_t, uint16, uint16, 
554                                       tsample_t, uint32, uint32);
555 static int extractContigSamples32bits (uint8 *, uint8 *, uint32,
556                                       tsample_t, uint16, uint16, 
557                                       tsample_t, uint32, uint32);
558 static int extractContigSamplesBytes (uint8 *, uint8 *, uint32, 
559                                       tsample_t, uint16, uint16, 
560                                       tsample_t, uint32, uint32);
561 static int extractContigSamplesShifted8bits (uint8 *, uint8 *, uint32,
562                                              tsample_t, uint16, uint16,
563                                              tsample_t, uint32, uint32,
564                                              int);
565 static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
566                                               tsample_t, uint16, uint16, 
567                                               tsample_t, uint32, uint32,
568                                               int);
569 static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
570                                               tsample_t, uint16, uint16, 
571                                               tsample_t, uint32, uint32,
572                                               int);
573 static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
574                                               tsample_t, uint16, uint16, 
575                                               tsample_t, uint32, uint32,
576                                               int);
577 static int extractContigSamplesToTileBuffer(uint8 *, uint8 *, uint32, uint32,
578                                             uint32, uint32, tsample_t, uint16,
579                                             uint16, uint16, struct dump_opts *);
580
581 /* Functions to combine separate planes into interleaved planes */
582 static int combineSeparateSamples8bits (uint8 *[], uint8 *, uint32, uint32,
583                                         uint16, uint16, FILE *, int, int);
584 static int combineSeparateSamples16bits (uint8 *[], uint8 *, uint32, uint32,
585                                          uint16, uint16, FILE *, int, int);
586 static int combineSeparateSamples24bits (uint8 *[], uint8 *, uint32, uint32,
587                                          uint16, uint16, FILE *, int, int);
588 static int combineSeparateSamples32bits (uint8 *[], uint8 *, uint32, uint32,
589                                          uint16, uint16, FILE *, int, int);
590 static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
591                                         uint32, uint32, tsample_t, uint16,
592                                         FILE *, int, int);
593
594 static int combineSeparateTileSamples8bits (uint8 *[], uint8 *, uint32, uint32,
595                                             uint32, uint32, uint16, uint16, 
596                                             FILE *, int, int);
597 static int combineSeparateTileSamples16bits (uint8 *[], uint8 *, uint32, uint32,
598                                              uint32, uint32, uint16, uint16,
599                                              FILE *, int, int);
600 static int combineSeparateTileSamples24bits (uint8 *[], uint8 *, uint32, uint32,
601                                              uint32, uint32, uint16, uint16,
602                                              FILE *, int, int);
603 static int combineSeparateTileSamples32bits (uint8 *[], uint8 *, uint32, uint32,
604                                              uint32, uint32, uint16, uint16,
605                                              FILE *, int, int);
606 static int combineSeparateTileSamplesBytes (unsigned char *[], unsigned char *,
607                                             uint32, uint32, uint32, uint32, 
608                                             tsample_t, uint16, FILE *, int, int);
609
610 /* Dump functions for debugging */
611 static void dump_info  (FILE *, int, char *, char *, ...);
612 static int  dump_data  (FILE *, int, char *, unsigned char *, uint32);
613 static int  dump_byte  (FILE *, int, char *, unsigned char);
614 static int  dump_short (FILE *, int, char *, uint16);
615 static int  dump_long  (FILE *, int, char *, uint32);
616 static int  dump_wide  (FILE *, int, char *, uint64);
617 static int  dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *);
618
619 /* End function declarations */
620 /* Functions derived in whole or in part from tiffcp */
621 /* The following functions are taken largely intact from tiffcp */
622
623 static   char* usage_info[] = {
624 "usage: tiffcrop [options] source1 ... sourceN  destination",
625 "where options are:",
626 " -h            Print this syntax listing",
627 " -v            Print tiffcrop version identifier and last revision date",
628 " ",
629 " -a            Append to output instead of overwriting",
630 " -d offset     Set initial directory offset, counting first image as one, not zero",
631 " -p contig     Pack samples contiguously (e.g. RGBRGB...)",
632 " -p separate   Store samples separately (e.g. RRR...GGG...BBB...)",
633 " -s            Write output in strips",
634 " -t            Write output in tiles",
635 " -i            Ignore read errors",
636 " ",
637 " -r #          Make each strip have no more than # rows",
638 " -w #          Set output tile width (pixels)",
639 " -l #          Set output tile length (pixels)",
640 " ",
641 " -f lsb2msb    Force lsb-to-msb FillOrder for output",
642 " -f msb2lsb    Force msb-to-lsb FillOrder for output",
643 "",
644 " -c lzw[:opts]  Compress output with Lempel-Ziv & Welch encoding",
645 " -c zip[:opts]  Compress output with deflate encoding",
646 " -c jpeg[:opts] Compress output with JPEG encoding",
647 " -c packbits    Compress output with packbits encoding",
648 " -c g3[:opts]   Compress output with CCITT Group 3 encoding",
649 " -c g4          Compress output with CCITT Group 4 encoding",
650 " -c none        Use no compression algorithm on output",
651 " ",
652 "Group 3 options:",
653 " 1d            Use default CCITT Group 3 1D-encoding",
654 " 2d            Use optional CCITT Group 3 2D-encoding",
655 " fill          Byte-align EOL codes",
656 "For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
657 " ",
658 "JPEG options:",
659 " #             Set compression quality level (0-100, default 100)",
660 " raw           Output color image as raw YCbCr",
661 " rgb           Output color image as RGB",
662 "For example, -c jpeg:rgb:50 to get JPEG-encoded RGB data with 50% comp. quality",
663 " ",
664 "LZW and deflate options:",
665 " #             Set predictor value",
666 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
667 " ",
668 "Page and selection options:",
669 " -N odd|even|#,#-#,#|last         sequences and ranges of images within file to process",
670 "             The words odd or even may be used to specify all odd or even numbered images.",
671 "             The word last may be used in place of a number in the sequence to indicate.",
672 "             The final image in the file without knowing how many images there are.",
673 "             Numbers are counted from one even though TIFF IFDs are counted from zero.",
674 " ",
675 " -E t|l|r|b  edge to use as origin for width and length of crop region",
676 " -U units    [in, cm, px ] inches, centimeters or pixels",
677 " ",
678 " -m #,#,#,#  margins from edges for selection: top, left, bottom, right separated by commas",
679 " -X #        horizontal dimension of region to extract expressed in current units",
680 " -Y #        vertical dimension of region to extract expressed in current units",
681 " -Z #:#,#:#  zones of the image designated as position X of Y,",
682 "             eg 1:3 would be first of three equal portions measured from reference edge",
683 " -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
684 "             regions of the image designated by upper left and lower right coordinates",
685 "",
686 "Export grouping options:",
687 " -e c|d|i|m|s    export mode for images and selections from input images.",
688 "                 When exporting a composite image from multiple zones or regions",
689 "                 (combined and image modes), the selections must have equal sizes",
690 "                 for the axis perpendicular to the edge specified with -E.",
691 "    c|combined   All images and selections are written to a single file (default).",
692 "                 with multiple selections from one image combined into a single image.",
693 "    d|divided    All images and selections are written to a single file",
694 "                 with each selection from one image written to a new image.",
695 "    i|image      Each input image is written to a new file (numeric filename sequence)",
696 "                 with multiple selections from the image combined into one image.",
697 "    m|multiple   Each input image is written to a new file (numeric filename sequence)",
698 "                 with each selection from the image written to a new image.",
699 "    s|separated  Individual selections from each image are written to separate files.",
700 "",
701 "Output options:",
702 " -H #        Set horizontal resolution of output images to #",
703 " -V #        Set vertical resolution of output images to #",
704 " -J #        Set horizontal margin of output page to # expressed in current units",
705 "             when sectioning image into columns x rows using the -S cols:rows option",
706 " -K #        Set verticalal margin of output page to # expressed in current units",
707 "             when sectioning image into columns x rows using the -S cols:rows option",
708 " ",
709 " -O orient    orientation for output image, portrait, landscape, auto",
710 " -P page      page size for output image segments, eg letter, legal, tabloid, etc",
711 "              use #.#x#.# to specify a custom page size in the currently defined units",
712 "              where #.# represents the width and length",        
713 " -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
714 " ",
715 " -F hor|vert|both",
716 "             flip (mirror) image or region horizontally, vertically, or both",
717 " -R #        [90,180,or 270] degrees clockwise rotation of image or extracted region",
718 " -I [black|white|data|both]",
719 "             invert color space, eg dark to light for bilevel and grayscale images",
720 "             If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
721 "             tag to MinIsBlack or MinIsWhite without altering the image data",
722 "             If the argument is data or both, the image data are modified:",
723 "             both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
724 "             data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
725 " ",
726 "-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
727 "             Debug/dump program progress and/or data to non-TIFF files.",
728 "             Options include the following and must be joined as a comma",
729 "             separate list. The use of this option is generally limited to",
730 "             program debugging and development of future options.",
731 " ",
732 "   debug:N   Display limited program progress indicators where larger N",
733 "             increase the level of detail. Note: Tiffcrop may be compiled with",
734 "             -DDEVELMODE to enable additional very low level debug reporting.",
735 "",
736 "   Format:txt|raw  Format any logged data as ASCII text or raw binary ",
737 "             values. ASCII text dumps include strings of ones and zeroes",
738 "             representing the binary values in the image data plus identifying headers.",
739 " ",
740 "   level:N   Specify the level of detail presented in the dump files.",
741 "             This can vary from dumps of the entire input or output image data to dumps",
742 "             of data processed by specific functions. Current range of levels is 1 to 3.",
743 " ",
744 "   input:full-path-to-directory/input-dumpname",
745 " ",
746 "   output:full-path-to-directory/output-dumpnaem",
747 " ",
748 "             When dump files are being written, each image will be written to a separate",
749 "             file with the name built by adding a numeric sequence value to the dumpname",
750 "             and an extension of .txt for ASCII dumps or .bin for binary dumps.",
751 " ",
752 "             The four debug/dump options are independent, though it makes little sense to",
753 "             specify a dump file without specifying a detail level.",
754 " ",
755 NULL
756 };
757
758 /* This function could be modified to pass starting sample offset 
759  * and number of samples as args to select fewer than spp
760  * from input image. These would then be passed to individual 
761  * extractContigSampleXX routines.
762  */
763 static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, 
764                                       uint32 imagelength, 
765                                       uint32 imagewidth, 
766                                       uint32 tw, uint32 tl,
767                                       tsample_t spp, uint16 bps)
768   {
769   int status = 1;
770   tsample_t sample = 0;
771   tsample_t count = spp; 
772   uint32 row, col, trow;
773   uint32 nrow, ncol;
774   uint32 dst_rowsize, shift_width;
775   uint32 bytes_per_sample, bytes_per_pixel;
776   uint32 trailing_bits, prev_trailing_bits;
777   uint32 tile_rowsize  = TIFFTileRowSize(in);
778   uint32 src_offset, dst_offset;
779   uint32 row_offset, col_offset;
780   uint8 *bufp = (uint8*) buf;
781   unsigned char *src = NULL;
782   unsigned char *dst = NULL;
783   tsize_t tbytes = 0, tile_buffsize = 0;
784   tsize_t tilesize = TIFFTileSize(in);
785   unsigned char *tilebuf = NULL;
786
787   bytes_per_sample = (bps + 7) / 8; 
788   bytes_per_pixel  = ((bps * spp) + 7) / 8;
789
790   if ((bps % 8) == 0)
791     shift_width = 0;
792   else
793     {
794     if (bytes_per_pixel < (bytes_per_sample + 1))
795       shift_width = bytes_per_pixel;
796     else
797       shift_width = bytes_per_sample + 1;
798     }
799
800   tile_buffsize = tilesize;
801
802   if (tilesize < (tsize_t)(tl * tile_rowsize))
803     {
804 #ifdef DEBUG2
805     TIFFError("readContigTilesIntoBuffer",
806               "Tilesize %lu is too small, using alternate calculation %u",
807               tilesize, tl * tile_rowsize);
808 #endif
809     tile_buffsize = tl * tile_rowsize;
810     } 
811
812   tilebuf = _TIFFmalloc(tile_buffsize);
813   if (tilebuf == 0)
814     return 0;
815
816   dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;  
817   for (row = 0; row < imagelength; row += tl)
818     {
819     nrow = (row + tl > imagelength) ? imagelength - row : tl;
820     for (col = 0; col < imagewidth; col += tw)
821       {
822       tbytes = TIFFReadTile(in, tilebuf, col, row, 0, 0);
823       if (tbytes < tilesize  && !ignore)
824         {
825         TIFFError(TIFFFileName(in),
826                   "Error, can't read tile at row %lu col %lu, Read %lu bytes of %lu",
827                   (unsigned long) col, (unsigned long) row, (unsigned long)tbytes,
828                   (unsigned long)tilesize);
829                   status = 0;
830                   _TIFFfree(tilebuf);
831                   return status;
832         }
833       
834       row_offset = row * dst_rowsize;
835       col_offset = ((col * bps * spp) + 7)/ 8;
836       bufp = buf + row_offset + col_offset;
837
838       if (col + tw > imagewidth)
839         ncol = imagewidth - col;
840       else
841         ncol = tw;
842
843       /* Each tile scanline will start on a byte boundary but it
844        * has to be merged into the scanline for the entire
845        * image buffer and the previous segment may not have
846        * ended on a byte boundary
847        */
848       /* Optimization for common bit depths, all samples */
849       if (((bps % 8) == 0) && (count == spp))
850         {
851         for (trow = 0; trow < nrow; trow++)
852           {
853           src_offset = trow * tile_rowsize;
854           _TIFFmemcpy (bufp, tilebuf + src_offset, (ncol * spp * bps) / 8);
855           bufp += (imagewidth * bps * spp) / 8;
856           }
857         }
858       else
859         {
860         /* Bit depths not a multiple of 8 and/or extract fewer than spp samples */
861         prev_trailing_bits = trailing_bits = 0;
862         trailing_bits = (ncol * bps * spp) % 8;
863
864         /*      for (trow = 0; tl < nrow; trow++) */
865         for (trow = 0; trow < nrow; trow++)
866           {
867           src_offset = trow * tile_rowsize;
868           src = tilebuf + src_offset;
869           dst_offset = (row + trow) * dst_rowsize;
870           dst = buf + dst_offset + col_offset;
871           switch (shift_width)
872             {
873             case 0: if (extractContigSamplesBytes (src, dst, ncol, sample,
874                                                    spp, bps, count, 0, ncol))
875                       {
876                       TIFFError("readContigTilesIntoBuffer",
877                                 "Unable to extract row %d from tile %lu", 
878                                 row, (unsigned long)TIFFCurrentTile(in));
879                       return 1;
880                       }
881                     break;
882             case 1: if (bps == 1)
883                       { 
884                       if (extractContigSamplesShifted8bits (src, dst, ncol,
885                                                             sample, spp,
886                                                             bps, count,
887                                                             0, ncol,
888                                                             prev_trailing_bits))
889                         {
890                         TIFFError("readContigTilesIntoBuffer",
891                                   "Unable to extract row %d from tile %lu", 
892                                   row, (unsigned long)TIFFCurrentTile(in));
893                         return 1;
894                         }
895                       break;
896                       }
897                     else
898                       if (extractContigSamplesShifted16bits (src, dst, ncol,
899                                                              sample, spp,
900                                                              bps, count,
901                                                              0, ncol,
902                                                              prev_trailing_bits))
903                         {
904                         TIFFError("readContigTilesIntoBuffer",
905                                   "Unable to extract row %d from tile %lu", 
906                                   row, (unsigned long)TIFFCurrentTile(in));
907                         return 1;
908                         }
909                     break;
910             case 2: if (extractContigSamplesShifted24bits (src, dst, ncol,
911                                                            sample, spp,
912                                                            bps, count,
913                                                            0, ncol,
914                                                            prev_trailing_bits))
915                       {
916                       TIFFError("readContigTilesIntoBuffer",
917                                 "Unable to extract row %d from tile %lu", 
918                                 row, (unsigned long)TIFFCurrentTile(in));
919                       return 1;
920                       }
921                     break;
922             case 3:
923             case 4:
924             case 5: if (extractContigSamplesShifted32bits (src, dst, ncol,
925                                                            sample, spp,
926                                                            bps, count,
927                                                            0, ncol,
928                                                            prev_trailing_bits))
929                       {
930                       TIFFError("readContigTilesIntoBuffer",
931                                 "Unable to extract row %d from tile %lu", 
932                                 row, (unsigned long)TIFFCurrentTile(in));
933                       return 1;
934                       }
935                     break;
936             default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %d", bps);
937                      return 1;
938             }
939           }
940         prev_trailing_bits += trailing_bits;
941         if (prev_trailing_bits > 7)
942           prev_trailing_bits-= 8;
943         }
944       }
945     }
946
947   _TIFFfree(tilebuf);
948   return status;
949   }
950
951 static int  readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf, 
952                                          uint32 imagelength, uint32 imagewidth, 
953                                          uint32 tw, uint32 tl,
954                                          uint16 spp, uint16 bps)
955   {
956   int     i, status = 1, sample;
957   int     shift_width, bytes_per_pixel;
958   uint16  bytes_per_sample;
959   uint32  row, col;     /* Current row and col of image */
960   uint32  nrow, ncol;   /* Number of rows and cols in current tile */
961   uint32  row_offset, col_offset; /* Output buffer offsets */
962   tsize_t tbytes = 0, tilesize = TIFFTileSize(in);
963   tsample_t s;
964   uint8*  bufp = (uint8*)obuf;
965   unsigned char *srcbuffs[MAX_SAMPLES];
966   unsigned char *tbuff = NULL;
967
968   bytes_per_sample = (bps + 7) / 8;
969
970   for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
971     {
972     srcbuffs[sample] = NULL;
973     tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
974     if (!tbuff)
975       {
976       TIFFError ("readSeparateTilesIntoBuffer", 
977                  "Unable to allocate tile read buffer for sample %d", sample);
978       for (i = 0; i < sample; i++)
979         _TIFFfree (srcbuffs[i]);
980       return 0;
981       }
982     srcbuffs[sample] = tbuff;
983     } 
984   /* Each tile contains only the data for a single plane
985    * arranged in scanlines of tw * bytes_per_sample bytes.
986    */
987   for (row = 0; row < imagelength; row += tl)
988     {
989     nrow = (row + tl > imagelength) ? imagelength - row : tl;
990     for (col = 0; col < imagewidth; col += tw)
991       {
992       for (s = 0; s < spp; s++)
993         {  /* Read each plane of a tile set into srcbuffs[s] */
994         tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
995         if (tbytes < 0  && !ignore)
996           {
997           TIFFError(TIFFFileName(in),
998                  "Error, can't read tile for row %lu col %lu, "
999                  "sample %lu",
1000                  (unsigned long) col, (unsigned long) row,
1001                  (unsigned long) s);
1002                  status = 0;
1003           for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1004             {
1005             tbuff = srcbuffs[sample];
1006             if (tbuff != NULL)
1007               _TIFFfree(tbuff);
1008             }
1009           return status;
1010           }
1011         }
1012      /* Tiles on the right edge may be padded out to tw 
1013       * which must be a multiple of 16.
1014       * Ncol represents the visible (non padding) portion.  
1015       */
1016       if (col + tw > imagewidth)
1017         ncol = imagewidth - col;
1018       else
1019         ncol = tw;
1020
1021       row_offset = row * (((imagewidth * spp * bps) + 7) / 8);
1022       col_offset = ((col * spp * bps) + 7) / 8;
1023       bufp = obuf + row_offset + col_offset;
1024
1025       if ((bps % 8) == 0)
1026         {
1027         if (combineSeparateTileSamplesBytes(srcbuffs, bufp, ncol, nrow, imagewidth,
1028                                             tw, spp, bps, NULL, 0, 0))
1029           {
1030           status = 0;
1031           break;
1032           }
1033         }
1034       else
1035         {
1036         bytes_per_pixel  = ((bps * spp) + 7) / 8;
1037         if (bytes_per_pixel < (bytes_per_sample + 1))
1038           shift_width = bytes_per_pixel;
1039         else
1040           shift_width = bytes_per_sample + 1;
1041
1042         switch (shift_width)
1043           {
1044           case 1: if (combineSeparateTileSamples8bits (srcbuffs, bufp, ncol, nrow,
1045                                                        imagewidth, tw, spp, bps, 
1046                                                        NULL, 0, 0))
1047                     {
1048                     status = 0;
1049                     break;
1050                     }
1051                   break;
1052           case 2: if (combineSeparateTileSamples16bits (srcbuffs, bufp, ncol, nrow,
1053                                                        imagewidth, tw, spp, bps, 
1054                                                        NULL, 0, 0))
1055                     {
1056                     status = 0;
1057                     break;
1058                     }
1059                   break;
1060           case 3: if (combineSeparateTileSamples24bits (srcbuffs, bufp, ncol, nrow,
1061                                                        imagewidth, tw, spp, bps, 
1062                                                        NULL, 0, 0))
1063                     {
1064                     status = 0;
1065                     break;
1066                     }
1067                   break;
1068           case 4: 
1069           case 5:
1070           case 6:
1071           case 7:
1072           case 8: if (combineSeparateTileSamples32bits (srcbuffs, bufp, ncol, nrow,
1073                                                        imagewidth, tw, spp, bps, 
1074                                                        NULL, 0, 0))
1075                     {
1076                     status = 0;
1077                     break;
1078                     }
1079                   break;
1080           default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps);
1081                   status = 0;
1082                   break;
1083           }
1084         }
1085       }
1086     }
1087
1088   for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1089     {
1090     tbuff = srcbuffs[sample];
1091     if (tbuff != NULL)
1092       _TIFFfree(tbuff);
1093     }
1094  
1095   return status;
1096   }
1097
1098 static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength)
1099   {
1100   uint32 row, nrows, rowsperstrip;
1101   tstrip_t strip = 0;
1102   tsize_t stripsize;
1103
1104   TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1105   for (row = 0; row < imagelength; row += rowsperstrip)
1106     {
1107     nrows = (row + rowsperstrip > imagelength) ?
1108              imagelength - row : rowsperstrip;
1109     stripsize = TIFFVStripSize(out, nrows);
1110     if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
1111       {
1112       TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1113       return 1;
1114       }
1115     buf += stripsize;
1116     }
1117
1118   return 0;
1119   }
1120
1121 /* Abandon plans to modify code so that plannar orientation separate images
1122  * do not have all samples for each channel written before all samples
1123  * for the next channel have been abandoned.
1124  * Libtiff internals seem to depend on all data for a given sample
1125  * being contiguous within a strip or tile when PLANAR_CONFIG is 
1126  * separate. All strips or tiles of a given plane are written
1127  * before any strips or tiles of a different plane are stored.
1128  */
1129 static int 
1130 writeBufferToSeparateStrips (TIFF* out, uint8* buf, 
1131                              uint32 length, uint32 width, uint16 spp,
1132                              struct dump_opts *dump)
1133   {
1134   uint8   *src;
1135   uint16   bps;
1136   uint32   row, nrows, rowsize, rowsperstrip;
1137   uint32   bytes_per_sample;
1138   tsample_t s;
1139   tstrip_t strip = 0;
1140   tsize_t  stripsize = TIFFStripSize(out);
1141   tsize_t  rowstripsize,  scanlinesize = TIFFScanlineSize(out);
1142   tsize_t  total_bytes = 0;
1143   tdata_t  obuf;
1144
1145   (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1146   (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1147   bytes_per_sample = (bps + 7) / 8;
1148   rowsize = ((bps * spp * width) + 7) / 8; /* source has interleaved samples */
1149   rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); 
1150
1151   obuf = _TIFFmalloc (rowstripsize);
1152   if (obuf == NULL)
1153     return 1;
1154   
1155   for (s = 0; s < spp; s++)
1156     {
1157     for (row = 0; row < length; row += rowsperstrip)
1158       {
1159       nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
1160
1161       stripsize = TIFFVStripSize(out, nrows);
1162       src = buf + (row * rowsize);
1163       total_bytes += stripsize;
1164       memset (obuf, '\0', rowstripsize);
1165       if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
1166         {
1167         _TIFFfree(obuf);
1168         return 1;
1169         }
1170       if ((dump->outfile != NULL) && (dump->level == 1))
1171         {
1172         dump_info(dump->outfile, dump->format,"", 
1173                   "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d", 
1174                   s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
1175         dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
1176         }
1177
1178       if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
1179         {
1180         TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1181         _TIFFfree(obuf);
1182         return 1;
1183         }
1184       }
1185     }      
1186
1187   _TIFFfree(obuf);
1188   return 0;
1189 }
1190
1191 /* Extract all planes from contiguous buffer into a single tile buffer 
1192  * to be written out as a tile.
1193  */
1194 static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
1195                                        uint32 imagewidth, tsample_t spp, 
1196                                        struct dump_opts* dump)
1197   {
1198   uint16 bps;
1199   uint32 tl, tw;
1200   uint32 row, col, nrow, ncol;
1201   uint32 src_rowsize, col_offset;
1202   uint32 tile_rowsize  = TIFFTileRowSize(out);
1203   uint8* bufp = (uint8*) buf;
1204   tsize_t tile_buffsize = 0;
1205   tsize_t tilesize = TIFFTileSize(out);
1206   unsigned char *tilebuf = NULL;
1207
1208   TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1209   TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1210   TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1211
1212   tile_buffsize = tilesize;
1213   if (tilesize < (tsize_t)(tl * tile_rowsize))
1214     {
1215 #ifdef DEBUG2
1216     TIFFError("writeBufferToContigTiles",
1217               "Tilesize %lu is too small, using alternate calculation %u",
1218               tilesize, tl * tile_rowsize);
1219 #endif
1220     tile_buffsize = tl * tile_rowsize;
1221     }
1222
1223   tilebuf = _TIFFmalloc(tile_buffsize);
1224   if (tilebuf == 0)
1225     return 1;
1226
1227   src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
1228   for (row = 0; row < imagelength; row += tl)
1229     {
1230     nrow = (row + tl > imagelength) ? imagelength - row : tl;
1231     for (col = 0; col < imagewidth; col += tw)
1232       {
1233       /* Calculate visible portion of tile. */
1234       if (col + tw > imagewidth)
1235         ncol = imagewidth - col;
1236       else
1237         ncol = tw;
1238
1239       col_offset = (((col * bps * spp) + 7) / 8);
1240       bufp = buf + (row * src_rowsize) + col_offset;
1241       if (extractContigSamplesToTileBuffer(tilebuf, bufp, nrow, ncol, imagewidth,
1242                                            tw, 0, spp, spp, bps, dump) > 0)
1243         {
1244         TIFFError("writeBufferToContigTiles", 
1245                   "Unable to extract data to tile for row %lu, col %lu",
1246                   (unsigned long) row, (unsigned long)col);
1247         _TIFFfree(tilebuf);
1248         return 1;
1249         }
1250
1251       if (TIFFWriteTile(out, tilebuf, col, row, 0, 0) < 0)
1252         {
1253         TIFFError("writeBufferToContigTiles",
1254                   "Cannot write tile at %lu %lu",
1255                   (unsigned long) col, (unsigned long) row);
1256          _TIFFfree(tilebuf);
1257         return 1;
1258         }
1259       }
1260     }
1261   _TIFFfree(tilebuf);
1262
1263   return 0;
1264   } /* end writeBufferToContigTiles */
1265
1266 /* Extract each plane from contiguous buffer into a single tile buffer 
1267  * to be written out as a tile.
1268  */
1269 static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
1270                                        uint32 imagewidth, tsample_t spp, 
1271                                        struct dump_opts * dump)
1272   {
1273   tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1274   uint32 tl, tw;
1275   uint32 row, col, nrow, ncol;
1276   uint32 src_rowsize, col_offset;
1277   uint16 bps;
1278   tsample_t s;
1279   uint8* bufp = (uint8*) buf;
1280
1281   if (obuf == NULL)
1282     return 1;
1283
1284   TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1285   TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1286   TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1287   src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
1288          
1289   for (row = 0; row < imagelength; row += tl)
1290     {
1291     nrow = (row + tl > imagelength) ? imagelength - row : tl;
1292     for (col = 0; col < imagewidth; col += tw)
1293       {
1294       /* Calculate visible portion of tile. */
1295       if (col + tw > imagewidth)
1296         ncol = imagewidth - col;
1297       else
1298         ncol = tw;
1299
1300       col_offset = (((col * bps * spp) + 7) / 8);
1301       bufp = buf + (row * src_rowsize) + col_offset;
1302
1303       for (s = 0; s < spp; s++)
1304         {
1305         if (extractContigSamplesToTileBuffer(obuf, bufp, nrow, ncol, imagewidth,
1306                                              tw, s, 1, spp, bps, dump) > 0)
1307           {
1308           TIFFError("writeBufferToSeparateTiles", 
1309                     "Unable to extract data to tile for row %lu, col %lu sample %d",
1310                     (unsigned long) row, (unsigned long)col, (int)s);
1311           _TIFFfree(obuf);
1312           return 1;
1313           }
1314
1315         if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0)
1316           {
1317            TIFFError("writeBufferToseparateTiles",
1318                      "Cannot write tile at %lu %lu sample %lu",
1319                      (unsigned long) col, (unsigned long) row,
1320                      (unsigned long) s);
1321            _TIFFfree(obuf);
1322            return 1;
1323           }
1324         }
1325       }
1326     }
1327   _TIFFfree(obuf);
1328
1329   return 0;
1330   } /* end writeBufferToSeparateTiles */
1331
1332 static void
1333 processG3Options(char* cp)
1334 {
1335         if( (cp = strchr(cp, ':')) ) {
1336                 if (defg3opts == (uint32) -1)
1337                         defg3opts = 0;
1338                 do {
1339                         cp++;
1340                         if (strneq(cp, "1d", 2))
1341                                 defg3opts &= ~GROUP3OPT_2DENCODING;
1342                         else if (strneq(cp, "2d", 2))
1343                                 defg3opts |= GROUP3OPT_2DENCODING;
1344                         else if (strneq(cp, "fill", 4))
1345                                 defg3opts |= GROUP3OPT_FILLBITS;
1346                         else
1347                                 usage();
1348                 } while( (cp = strchr(cp, ':')) );
1349         }
1350 }
1351
1352 static int
1353 processCompressOptions(char* opt)
1354   {
1355   char* cp = NULL;
1356
1357   if (strneq(opt, "none",4))
1358     {
1359     defcompression = COMPRESSION_NONE;
1360     }
1361   else if (streq(opt, "packbits"))
1362     {
1363     defcompression = COMPRESSION_PACKBITS;
1364     }
1365   else if (strneq(opt, "jpeg", 4))
1366     {
1367     cp = strchr(opt, ':');
1368     defcompression = COMPRESSION_JPEG;
1369
1370     while (cp)
1371       {
1372       if (isdigit((int)cp[1]))
1373         quality = atoi(cp + 1);
1374       else if (strneq(cp + 1, "raw", 3 ))
1375         jpegcolormode = JPEGCOLORMODE_RAW;
1376       else if (strneq(cp + 1, "rgb", 3 ))
1377         jpegcolormode = JPEGCOLORMODE_RGB;
1378       else
1379         usage();
1380       cp = strchr(cp + 1, ':');
1381       }
1382     }
1383   else if (strneq(opt, "g3", 2))
1384     {
1385     processG3Options(opt);
1386     defcompression = COMPRESSION_CCITTFAX3;
1387     }
1388   else if (streq(opt, "g4"))
1389     {
1390     defcompression = COMPRESSION_CCITTFAX4;
1391     }
1392   else if (strneq(opt, "lzw", 3))
1393     {
1394     cp = strchr(opt, ':');
1395     if (cp)
1396       defpredictor = atoi(cp+1);
1397     defcompression = COMPRESSION_LZW;
1398     }
1399   else if (strneq(opt, "zip", 3))
1400     {
1401     cp = strchr(opt, ':');
1402     if (cp)
1403       defpredictor = atoi(cp+1);
1404     defcompression = COMPRESSION_ADOBE_DEFLATE;
1405    }
1406   else
1407     return (0);
1408
1409   return (1);
1410   }
1411
1412 static void
1413 usage(void)
1414   {
1415   int i;
1416
1417   fprintf(stderr, "\n%s\n", TIFFGetVersion());
1418   for (i = 0; usage_info[i] != NULL; i++)
1419     fprintf(stderr, "%s\n", usage_info[i]);
1420   exit(-1);
1421   }
1422
1423 #define CopyField(tag, v) \
1424     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
1425 #define CopyField2(tag, v1, v2) \
1426     if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
1427 #define CopyField3(tag, v1, v2, v3) \
1428     if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
1429 #define CopyField4(tag, v1, v2, v3, v4) \
1430     if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
1431
1432 static void
1433 cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
1434 {
1435         switch (type) {
1436         case TIFF_SHORT:
1437                 if (count == 1) {
1438                         uint16 shortv;
1439                         CopyField(tag, shortv);
1440                 } else if (count == 2) {
1441                         uint16 shortv1, shortv2;
1442                         CopyField2(tag, shortv1, shortv2);
1443                 } else if (count == 4) {
1444                         uint16 *tr, *tg, *tb, *ta;
1445                         CopyField4(tag, tr, tg, tb, ta);
1446                 } else if (count == (uint16) -1) {
1447                         uint16 shortv1;
1448                         uint16* shortav;
1449                         CopyField2(tag, shortv1, shortav);
1450                 }
1451                 break;
1452         case TIFF_LONG:
1453                 { uint32 longv;
1454                   CopyField(tag, longv);
1455                 }
1456                 break;
1457         case TIFF_RATIONAL:
1458                 if (count == 1) {
1459                         float floatv;
1460                         CopyField(tag, floatv);
1461                 } else if (count == (uint16) -1) {
1462                         float* floatav;
1463                         CopyField(tag, floatav);
1464                 }
1465                 break;
1466         case TIFF_ASCII:
1467                 { char* stringv;
1468                   CopyField(tag, stringv);
1469                 }
1470                 break;
1471         case TIFF_DOUBLE:
1472                 if (count == 1) {
1473                         double doublev;
1474                         CopyField(tag, doublev);
1475                 } else if (count == (uint16) -1) {
1476                         double* doubleav;
1477                         CopyField(tag, doubleav);
1478                 }
1479                 break;
1480           default:
1481                 TIFFError(TIFFFileName(in),
1482                           "Data type %d is not supported, tag %d skipped",
1483                           tag, type);
1484         }
1485 }
1486
1487 static struct cpTag {
1488         uint16  tag;
1489         uint16  count;
1490         TIFFDataType type;
1491 } tags[] = {
1492         { TIFFTAG_SUBFILETYPE,          1, TIFF_LONG },
1493         { TIFFTAG_THRESHHOLDING,        1, TIFF_SHORT },
1494         { TIFFTAG_DOCUMENTNAME,         1, TIFF_ASCII },
1495         { TIFFTAG_IMAGEDESCRIPTION,     1, TIFF_ASCII },
1496         { TIFFTAG_MAKE,                 1, TIFF_ASCII },
1497         { TIFFTAG_MODEL,                1, TIFF_ASCII },
1498         { TIFFTAG_MINSAMPLEVALUE,       1, TIFF_SHORT },
1499         { TIFFTAG_MAXSAMPLEVALUE,       1, TIFF_SHORT },
1500         { TIFFTAG_XRESOLUTION,          1, TIFF_RATIONAL },
1501         { TIFFTAG_YRESOLUTION,          1, TIFF_RATIONAL },
1502         { TIFFTAG_PAGENAME,             1, TIFF_ASCII },
1503         { TIFFTAG_XPOSITION,            1, TIFF_RATIONAL },
1504         { TIFFTAG_YPOSITION,            1, TIFF_RATIONAL },
1505         { TIFFTAG_RESOLUTIONUNIT,       1, TIFF_SHORT },
1506         { TIFFTAG_SOFTWARE,             1, TIFF_ASCII },
1507         { TIFFTAG_DATETIME,             1, TIFF_ASCII },
1508         { TIFFTAG_ARTIST,               1, TIFF_ASCII },
1509         { TIFFTAG_HOSTCOMPUTER,         1, TIFF_ASCII },
1510         { TIFFTAG_WHITEPOINT,           (uint16) -1, TIFF_RATIONAL },
1511         { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
1512         { TIFFTAG_HALFTONEHINTS,        2, TIFF_SHORT },
1513         { TIFFTAG_INKSET,               1, TIFF_SHORT },
1514         { TIFFTAG_DOTRANGE,             2, TIFF_SHORT },
1515         { TIFFTAG_TARGETPRINTER,        1, TIFF_ASCII },
1516         { TIFFTAG_SAMPLEFORMAT,         1, TIFF_SHORT },
1517         { TIFFTAG_YCBCRCOEFFICIENTS,    (uint16) -1,TIFF_RATIONAL },
1518         { TIFFTAG_YCBCRSUBSAMPLING,     2, TIFF_SHORT },
1519         { TIFFTAG_YCBCRPOSITIONING,     1, TIFF_SHORT },
1520         { TIFFTAG_REFERENCEBLACKWHITE,  (uint16) -1,TIFF_RATIONAL },
1521         { TIFFTAG_EXTRASAMPLES,         (uint16) -1, TIFF_SHORT },
1522         { TIFFTAG_SMINSAMPLEVALUE,      1, TIFF_DOUBLE },
1523         { TIFFTAG_SMAXSAMPLEVALUE,      1, TIFF_DOUBLE },
1524         { TIFFTAG_STONITS,              1, TIFF_DOUBLE },
1525 };
1526 #define NTAGS   (sizeof (tags) / sizeof (tags[0]))
1527
1528 #define CopyTag(tag, count, type)       cpTag(in, out, tag, count, type)
1529
1530 /* Functions written by Richard Nolde, with exceptions noted. */
1531 void  process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
1532                             uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
1533                             uint32 *deftilelength, uint32 *defrowsperstrip,
1534                             struct crop_mask *crop_data, struct pagedef *page, 
1535                             struct dump_opts *dump,
1536                             unsigned int     *imagelist, unsigned int   *image_count )
1537     {
1538     int   c, good_args = 0;
1539     char *opt_offset   = NULL;    /* Position in string of value sought */
1540     char *opt_ptr      = NULL;    /* Pointer to next token in option set */
1541     char *sep          = NULL;    /* Pointer to a token separator */
1542     unsigned int  i, j, start, end;
1543     extern int   optind;
1544     extern char* optarg;
1545
1546     *mp++ = 'w';
1547     *mp = '\0';
1548     while ((c = getopt(argc, argv,
1549        "ac:d:e:f:hil:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1)
1550       {
1551     good_args++;
1552     switch (c) {
1553       case 'a': mode[0] = 'a';  /* append to output */
1554                 break;
1555       case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
1556                   {
1557                   TIFFError ("Unknown compression option", "%s", optarg);
1558                   TIFFError ("For valid options type", "tiffcrop -h");
1559                   exit (-1);
1560                   }
1561                 break;
1562       case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
1563                 if (start == 0)
1564                   {
1565                   TIFFError ("","Directory offset must be greater than zero");
1566                   TIFFError ("For valid options type", "tiffcrop -h");
1567                   exit (-1);
1568                   }
1569                 *dirnum = start - 1;
1570                 break;
1571       case 'e': switch (tolower(optarg[0])) /* image export modes*/
1572                   {
1573                   case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
1574                             crop_data->img_mode = COMPOSITE_IMAGES;
1575                             break; /* Composite */
1576                   case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
1577                             crop_data->img_mode = SEPARATED_IMAGES;
1578                             break; /* Divided */
1579                   case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
1580                             crop_data->img_mode = COMPOSITE_IMAGES;
1581                             break; /* Image */
1582                   case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
1583                             crop_data->img_mode = SEPARATED_IMAGES;
1584                             break; /* Multiple */
1585                   case 's': crop_data->exp_mode = FILE_PER_SELECTION;
1586                             crop_data->img_mode = SEPARATED_IMAGES;
1587                             break; /* Sections */
1588                   default:  TIFFError ("Unknown export mode","%s", optarg);
1589                             TIFFError ("For valid options type", "tiffcrop -h");
1590                             exit (-1);
1591                   }
1592                 break;
1593       case 'f': if (streq(optarg, "lsb2msb"))      /* fill order */
1594                   *deffillorder = FILLORDER_LSB2MSB;
1595                 else if (streq(optarg, "msb2lsb"))
1596                   *deffillorder = FILLORDER_MSB2LSB;
1597                 else
1598                   {
1599                   TIFFError ("Unknown fill order", "%s", optarg);
1600                   TIFFError ("For valid options type", "tiffcrop -h");
1601                   exit (-1);
1602                   }
1603                 break;
1604       case 'h': usage();
1605                 break;
1606       case 'i': ignore = TRUE;          /* ignore errors */
1607                 break;
1608       case 'l': outtiled = TRUE;         /* tile length */
1609                 *deftilelength = atoi(optarg);
1610                 break;
1611       case 'p': /* planar configuration */
1612                 if (streq(optarg, "separate"))
1613                   *defconfig = PLANARCONFIG_SEPARATE;
1614                 else if (streq(optarg, "contig"))
1615                   *defconfig = PLANARCONFIG_CONTIG;
1616                 else
1617                   {
1618                   TIFFError ("Unkown planar configuration", "%s", optarg);
1619                   TIFFError ("For valid options type", "tiffcrop -h");
1620                   exit (-1);
1621                   }
1622                 break;
1623       case 'r': /* rows/strip */
1624                 *defrowsperstrip = atol(optarg);
1625                 break;
1626       case 's': /* generate stripped output */
1627                 outtiled = FALSE;
1628                 break;
1629       case 't': /* generate tiled output */
1630                 outtiled = TRUE;
1631                 break;
1632       case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
1633                 TIFFError ("Tiffcrop version", "%s, last updated: %s", 
1634                            tiffcrop_version_id, tiffcrop_rev_date);
1635                 TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
1636                 TIFFError ("           ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
1637                 TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
1638                 exit (0);
1639                 break;
1640       case 'w': /* tile width */
1641                 outtiled = TRUE;
1642                 *deftilewidth = atoi(optarg);
1643                 break;
1644       case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
1645                 crop_data->crop_mode |= CROP_REGIONS;
1646                 for (i = 0, opt_ptr = strtok (optarg, ":");
1647                    ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
1648                     (opt_ptr = strtok (NULL, ":")), i++)
1649                     {
1650                     crop_data->regions++;
1651                     if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
1652                                &crop_data->corners[i].X1, &crop_data->corners[i].Y1,
1653                                &crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
1654                       {
1655                       TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
1656                       TIFFError ("For valid options type", "tiffcrop -h");
1657                       exit (-1);
1658                       }
1659                     }
1660                 /*  check for remaining elements over MAX_REGIONS */
1661                 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
1662                   {
1663                   TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
1664                   TIFFError ("For valid options type", "tiffcrop -h");
1665                   exit (-1);;
1666                   }
1667                 break;
1668       /* options for file open modes */
1669       case 'B': *mp++ = 'b'; *mp = '\0';
1670                 break;
1671       case 'L': *mp++ = 'l'; *mp = '\0';
1672                 break;
1673       case 'M': *mp++ = 'm'; *mp = '\0';
1674                 break;
1675       case 'C': *mp++ = 'c'; *mp = '\0';
1676                 break;
1677       /* options for Debugging / data dump */
1678       case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
1679                     (opt_ptr != NULL);
1680                     (opt_ptr = strtok (NULL, ",")), i++)
1681                     {
1682                     opt_offset = strpbrk(opt_ptr, ":=");
1683                     if (opt_offset == NULL)
1684                       {
1685                       TIFFError("Invalid dump option", "%s", optarg);
1686                       TIFFError ("For valid options type", "tiffcrop -h");
1687                       exit (-1);
1688                       }
1689                       
1690                     *opt_offset = '\0';
1691                     /* convert option to lowercase */
1692                     end = strlen (opt_ptr);
1693                     for (i = 0; i < end; i++)
1694                       *(opt_ptr + i) = tolower(*(opt_ptr + i));
1695                     /* Look for dump format specification */
1696                     if (strncmp(opt_ptr, "for", 3) == 0)
1697                       {
1698                       /* convert value to lowercase */
1699                       end = strlen (opt_offset + 1);
1700                       for (i = 1; i <= end; i++)
1701                         *(opt_offset + i) = tolower(*(opt_offset + i));
1702                       /* check dump format value */
1703                       if (strncmp (opt_offset + 1, "txt", 3) == 0)
1704                         {
1705                         dump->format = DUMP_TEXT;
1706                         strcpy (dump->mode, "w");
1707                         }
1708                       else
1709                         {
1710                         if (strncmp(opt_offset + 1, "raw", 3) == 0)
1711                           {
1712                           dump->format = DUMP_RAW;
1713                           strcpy (dump->mode, "wb");
1714                           }
1715                         else
1716                           {
1717                           TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
1718                           TIFFError ("For valid options type", "tiffcrop -h");
1719                           exit (-1);
1720                           }
1721                         }
1722                       }
1723                     else
1724                       { /* Look for dump level specification */
1725                       if (strncmp (opt_ptr, "lev", 3) == 0)
1726                         dump->level = atoi(opt_offset + 1);
1727                         /* Look for input data dump file name */
1728                       if (strncmp (opt_ptr, "in", 2) == 0)
1729                         {
1730                         strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
1731                         dump->infilename[PATH_MAX - 20] = '\0';
1732                         }
1733                         /* Look for output data dump file name */
1734                       if (strncmp (opt_ptr, "out", 3) == 0)
1735                         {
1736                         strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
1737                         dump->outfilename[PATH_MAX - 20] = '\0';
1738                         }
1739                       if (strncmp (opt_ptr, "deb", 3) == 0)
1740                         dump->debug = atoi(opt_offset + 1);
1741                       }
1742                     }
1743                 if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
1744                   {
1745                   if (dump->level == 1)
1746                     TIFFError("","Defaulting to dump level 1, no data.");
1747                   if (dump->format == DUMP_NONE)
1748                     {
1749                     TIFFError("", "You must specify a dump format for dump files");
1750                     TIFFError ("For valid options type", "tiffcrop -h");
1751                     exit (-1);
1752                     }
1753                   }
1754                 break;
1755
1756       /* image manipulation routine options */
1757       case 'm': /* margins to exclude from selection, uppercase M was already used */
1758                 /* order of values must be TOP, LEFT, BOTTOM, RIGHT */
1759                 crop_data->crop_mode |= CROP_MARGINS;
1760                 for (i = 0, opt_ptr = strtok (optarg, ",:");
1761                     ((opt_ptr != NULL) &&  (i < 4));
1762                      (opt_ptr = strtok (NULL, ",:")), i++)
1763                     {
1764                     crop_data->margins[i] = atof(opt_ptr);
1765                     }
1766                 break;
1767       case 'E': /* edge reference */
1768                 switch (tolower(optarg[0]))
1769                   {
1770                   case 't': crop_data->edge_ref = EDGE_TOP;
1771                             break;
1772                   case 'b': crop_data->edge_ref = EDGE_BOTTOM;
1773                              break;
1774                   case 'l': crop_data->edge_ref = EDGE_LEFT;
1775                             break;
1776                   case 'r': crop_data->edge_ref = EDGE_RIGHT;
1777                             break;
1778                   default:  TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
1779                             TIFFError ("For valid options type", "tiffcrop -h");
1780                             exit (-1);
1781                   }
1782                 break;
1783       case 'F': /* flip eg mirror image or cropped segment, M was already used */
1784                 crop_data->crop_mode |= CROP_MIRROR;
1785                 switch (tolower(optarg[0]))
1786                   {
1787                   case  'h': crop_data->mirror = MIRROR_HORIZ;
1788                              break;
1789                   case  'v': crop_data->mirror = MIRROR_VERT;
1790                              break;
1791                   case  'b': crop_data->mirror = MIRROR_BOTH;
1792                              break;
1793                   default:   TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
1794                              TIFFError ("For valid options type", "tiffcrop -h");
1795                              exit (-1);
1796                   }
1797                 break;
1798       case 'H': /* set horizontal resolution to new value */
1799                 page->hres = atof (optarg);
1800                 page->mode |= PAGE_MODE_RESOLUTION;
1801                 break;
1802       case 'I': /* invert the color space, eg black to white */
1803                 crop_data->crop_mode |= CROP_INVERT;
1804                 /* The PHOTOMETIC_INTERPRETATION tag may be updated */
1805                 if (streq(optarg, "black"))
1806                   {
1807                   crop_data->photometric = PHOTOMETRIC_MINISBLACK;
1808                   continue;
1809                   }
1810                 if (streq(optarg, "white"))
1811                   {
1812                   crop_data->photometric = PHOTOMETRIC_MINISWHITE;
1813                   continue;
1814                   }
1815                 if (streq(optarg, "data")) 
1816                   {
1817                   crop_data->photometric = INVERT_DATA_ONLY;
1818                   continue;
1819                   }
1820                 if (streq(optarg, "both"))
1821                   {
1822                   crop_data->photometric = INVERT_DATA_AND_TAG;
1823                   continue;
1824                   }
1825
1826                 TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
1827                 TIFFError ("For valid options type", "tiffcrop -h");
1828                 exit (-1);
1829                 break;
1830       case 'J': /* horizontal margin for sectioned ouput pages */ 
1831                 page->hmargin = atof(optarg);
1832                 page->mode |= PAGE_MODE_MARGINS;
1833                 break;
1834       case 'K': /* vertical margin for sectioned ouput pages*/ 
1835                 page->vmargin = atof(optarg);
1836                 page->mode |= PAGE_MODE_MARGINS;
1837                 break;
1838       case 'N': /* list of images to process */
1839                 for (i = 0, opt_ptr = strtok (optarg, ",");
1840                     ((opt_ptr != NULL) &&  (i < MAX_IMAGES));
1841                      (opt_ptr = strtok (NULL, ",")))
1842                      { /* We do not know how many images are in file yet 
1843                         * so we build a list to include the maximum allowed
1844                         * and follow it until we hit the end of the file.
1845                         * Image count is not accurate for odd, even, last
1846                         * so page numbers won't be valid either.
1847                         */
1848                      if (streq(opt_ptr, "odd"))
1849                        {
1850                        for (j = 1; j <= MAX_IMAGES; j += 2)
1851                          imagelist[i++] = j;
1852                        *image_count = (MAX_IMAGES - 1) / 2;
1853                        break;
1854                        }
1855                      else
1856                        {
1857                        if (streq(opt_ptr, "even"))
1858                          {
1859                          for (j = 2; j <= MAX_IMAGES; j += 2)
1860                            imagelist[i++] = j;
1861                          *image_count = MAX_IMAGES / 2;
1862                          break;
1863                          }
1864                        else
1865                          {
1866                          if (streq(opt_ptr, "last"))
1867                            imagelist[i++] = MAX_IMAGES;
1868                          else  /* single value between commas */
1869                            {
1870                            sep = strpbrk(opt_ptr, ":-");
1871                            if (!sep)
1872                              imagelist[i++] = atoi(opt_ptr);
1873                            else
1874                              {
1875                              *sep = '\0';
1876                              start = atoi (opt_ptr);
1877                              if (!strcmp((sep + 1), "last"))
1878                                end = MAX_IMAGES;
1879                              else
1880                                end = atoi (sep + 1);
1881                              for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
1882                                imagelist[i++] = j;
1883                              }
1884                            }
1885                          }
1886                       }
1887                     }
1888                 *image_count = i;
1889                 break;
1890       case 'O': /* page orientation */ 
1891                 switch (tolower(optarg[0]))
1892                   {
1893                   case  'a': page->orient = ORIENTATION_AUTO;
1894                              break;
1895                   case  'p': page->orient = ORIENTATION_PORTRAIT;
1896                              break;
1897                   case  'l': page->orient = ORIENTATION_LANDSCAPE;
1898                              break;
1899                   default:  TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
1900                             TIFFError ("For valid options type", "tiffcrop -h");
1901                             exit (-1);
1902                   }
1903                 break;
1904       case 'P': /* page size selection */ 
1905                 if (sscanf(optarg, "%lfx%lf", &page->width, &page->length) == 2)
1906                   {
1907                   strcpy (page->name, "Custom"); 
1908                   page->mode |= PAGE_MODE_PAPERSIZE;
1909                   break;
1910                   }
1911                 if (get_page_geometry (optarg, page))
1912                   {
1913                   if (!strcmp(optarg, "list"))
1914                     {
1915                     TIFFError("", "Name            Width   Length (in inches)");
1916                     for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1917                       TIFFError ("", "%-15.15s %5.2f   %5.2f", 
1918                                PaperTable[i].name, PaperTable[i].width, 
1919                                PaperTable[i].length);
1920                     exit (-1);                   
1921                     }
1922      
1923                   TIFFError ("Invalid paper size", "%s", optarg);
1924                   TIFFError ("", "Select one of:");
1925                   TIFFError("", "Name            Width   Length (in inches)");
1926                   for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1927                     TIFFError ("", "%-15.15s %5.2f   %5.2f", 
1928                                PaperTable[i].name, PaperTable[i].width, 
1929                                PaperTable[i].length);
1930                   exit (-1);
1931                   }
1932                 else
1933                   {
1934                   page->mode |= PAGE_MODE_PAPERSIZE;
1935                   }
1936                 break;
1937       case 'R': /* rotate image or cropped segment */
1938                 crop_data->crop_mode |= CROP_ROTATE;
1939                 switch (strtoul(optarg, NULL, 0))
1940                   {
1941                   case  90:  crop_data->rotation = (uint16)90;
1942                              break;
1943                   case  180: crop_data->rotation = (uint16)180;
1944                              break;
1945                   case  270: crop_data->rotation = (uint16)270;
1946                              break;
1947                   default:   TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
1948                              TIFFError ("For valid options type", "tiffcrop -h");
1949                              exit (-1);
1950                   }
1951                 break;
1952       case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
1953                 sep = strpbrk(optarg, ",:");
1954                 if (sep)
1955                   {
1956                   *sep = '\0';
1957                   page->cols = atoi(optarg);
1958                   page->rows = atoi(sep +1);
1959                   }
1960                 else
1961                   {
1962                   page->cols = atoi(optarg);
1963                   page->rows = atoi(optarg);
1964                   }
1965                 if ((page->cols * page->rows) > MAX_SECTIONS)
1966                   {
1967                   TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
1968                   exit (-1);
1969                   }
1970                 page->mode |= PAGE_MODE_ROWSCOLS;
1971                 break;
1972       case 'U': /* units for measurements and offsets */
1973                 if (streq(optarg, "in"))
1974                   {
1975                   crop_data->res_unit = RESUNIT_INCH;
1976                   page->res_unit = RESUNIT_INCH;
1977                   }
1978                 else if (streq(optarg, "cm"))
1979                   {
1980                   crop_data->res_unit = RESUNIT_CENTIMETER;
1981                   page->res_unit = RESUNIT_CENTIMETER;
1982                   }
1983                 else if (streq(optarg, "px"))
1984                   {
1985                   crop_data->res_unit = RESUNIT_NONE;
1986                   page->res_unit = RESUNIT_NONE;
1987                   }
1988                 else
1989                   {
1990                   TIFFError ("Illegal unit of measure","%s", optarg);
1991                   TIFFError ("For valid options type", "tiffcrop -h");
1992                   exit (-1);
1993                   }
1994                 break;
1995       case 'V': /* set vertical resolution to new value */
1996                 page->vres = atof (optarg);
1997                 page->mode |= PAGE_MODE_RESOLUTION;
1998                 break;
1999       case 'X': /* selection width */
2000                 crop_data->crop_mode |= CROP_WIDTH;
2001                 crop_data->width = atof(optarg);
2002                 break;
2003       case 'Y': /* selection length */
2004                 crop_data->crop_mode |= CROP_LENGTH;
2005                 crop_data->length = atof(optarg);
2006                 break;
2007       case 'Z': /* zones of an image X:Y read as zone X of Y */
2008                 crop_data->crop_mode |= CROP_ZONES;
2009                 for (i = 0, opt_ptr = strtok (optarg, ",");
2010                    ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
2011                     (opt_ptr = strtok (NULL, ",")), i++)
2012                     {
2013                     crop_data->zones++;
2014                     opt_offset = strchr(opt_ptr, ':');
2015                     *opt_offset = '\0';
2016                     crop_data->zonelist[i].position = atoi(opt_ptr);
2017                     crop_data->zonelist[i].total    = atoi(opt_offset + 1);
2018                     }
2019                 /*  check for remaining elements over MAX_REGIONS */
2020                 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
2021                   {
2022                   TIFFError("Zone list exceeds region limit", "%d",  MAX_REGIONS);
2023                   exit (-1);
2024                   }
2025                 break;
2026     case '?':   TIFFError ("For valid options type", "tiffcrop -h");
2027                 exit (-1);
2028                 /*NOTREACHED*/
2029       }
2030     }
2031   }  /* end process_command_opts */
2032
2033 /* Start a new output file if one has not been previously opened or
2034  * autoindex is set to non-zero. Update page and file counters
2035  * so TIFFTAG PAGENUM will be correct in image.
2036  */
2037 static int 
2038 update_output_file (TIFF **tiffout, char *mode, int autoindex,
2039                     char *outname, unsigned int *page)
2040   {
2041   static int findex = 0;    /* file sequence indicator */
2042   char  *sep;
2043   char   filenum[16];
2044   char   export_ext[16];
2045   char   exportname[PATH_MAX];
2046
2047   if (autoindex && (*tiffout != NULL))
2048     {   
2049     /* Close any export file that was previously opened */
2050     TIFFClose (*tiffout);
2051     *tiffout = NULL;
2052     }
2053
2054   strcpy (export_ext, ".tiff");
2055   memset (exportname, '\0', PATH_MAX);
2056
2057   /* Leave room for page number portion of the new filename */
2058   strncpy (exportname, outname, PATH_MAX - 16);
2059   if (*tiffout == NULL)   /* This is a new export file */
2060     {
2061     if (autoindex)
2062       { /* create a new filename for each export */
2063       findex++;
2064       if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
2065         {
2066         strncpy (export_ext, sep, 5);
2067         *sep = '\0';
2068         }
2069       else
2070         strncpy (export_ext, ".tiff", 5);
2071       export_ext[5] = '\0';
2072
2073       /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
2074       if (findex > MAX_EXPORT_PAGES)
2075         {
2076         TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES);
2077         return 1;
2078         }
2079
2080       sprintf (filenum, "-%03d%s", findex, export_ext);
2081       filenum[14] = '\0';
2082       strncat (exportname, filenum, 15);
2083       }
2084     exportname[PATH_MAX - 1] = '\0';
2085
2086     *tiffout = TIFFOpen(exportname, mode);
2087     if (*tiffout == NULL)
2088       {
2089       TIFFError("update_output_file", "Unable to open output file %s", exportname);
2090       return 1;
2091       }
2092     *page = 0; 
2093
2094     return 0;
2095     }
2096   else 
2097     (*page)++;
2098
2099   return 0;
2100   } /* end update_output_file */
2101
2102
2103 int
2104 main(int argc, char* argv[])
2105   {
2106   extern int optind;
2107   uint16 defconfig = (uint16) -1;
2108   uint16 deffillorder = 0;
2109   uint32 deftilewidth = (uint32) 0;
2110   uint32 deftilelength = (uint32) 0;
2111   uint32 defrowsperstrip = (uint32) 0;
2112   uint32 dirnum = 0;
2113
2114   TIFF *in = NULL;
2115   TIFF *out = NULL;
2116   char  mode[10];
2117   char *mp = mode;
2118
2119   /** RJN additions **/
2120   struct image_data image;     /* Image parameters for one image */
2121   struct crop_mask  crop;      /* Cropping parameters for all images */
2122   struct pagedef    page;      /* Page definition for output pages */
2123   struct pageseg    sections[MAX_SECTIONS];  /* Sections of one output page */
2124   struct buffinfo   seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
2125   struct dump_opts  dump;                  /* Data dump options */
2126   unsigned char *read_buff    = NULL;      /* Input image data buffer */
2127   unsigned char *crop_buff    = NULL;      /* Crop area buffer */
2128   unsigned char *sect_buff    = NULL;      /* Image section buffer */
2129   unsigned char *sect_src     = NULL;      /* Image section buffer pointer */
2130   unsigned int  imagelist[MAX_IMAGES + 1]; /* individually specified images */
2131   unsigned int  image_count  = 0;
2132   unsigned int  dump_images  = 0;
2133   unsigned int  next_image   = 0;
2134   unsigned int  next_page    = 0;
2135   unsigned int  total_pages  = 0;
2136   unsigned int  total_images = 0;
2137   unsigned int  end_of_input = FALSE;
2138   int    seg, length;
2139   char   temp_filename[PATH_MAX + 1];
2140
2141   little_endian = *((unsigned char *)&little_endian) & '1';
2142
2143   initImageData(&image);
2144   initCropMasks(&crop);
2145   initPageSetup(&page, sections, seg_buffs);
2146   initDumpOptions(&dump);
2147
2148   process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig, 
2149                         &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
2150                         &crop, &page, &dump, imagelist, &image_count);
2151
2152   if (argc - optind < 2)
2153     usage();
2154
2155   if ((argc - optind) == 2)
2156     pageNum = -1;
2157   else
2158     total_images = 0;
2159   /* read multiple input files and write to output file(s) */
2160   while (optind < argc - 1)
2161     {
2162     in = TIFFOpen (argv[optind], "r");
2163     if (in == NULL)
2164       return (-3);
2165
2166     /* If only one input file is specified, we can use directory count */
2167     total_images = TIFFNumberOfDirectories(in); 
2168     if (image_count == 0)
2169       {
2170       dirnum = 0;
2171       total_pages = total_images; /* Only valid with single input file */
2172       }
2173     else
2174       {
2175       dirnum = (tdir_t)(imagelist[next_image] - 1);
2176       next_image++;
2177
2178       /* Total pages only valid for enumerated list of pages not derived
2179        * using odd, even, or last keywords.
2180        */
2181       if (image_count >  total_images)
2182         image_count = total_images;
2183       
2184       total_pages = image_count;
2185       }
2186
2187     /* MAX_IMAGES is used for special case "last" in selection list */
2188     if (dirnum == (MAX_IMAGES - 1))
2189       dirnum = total_images - 1;
2190
2191     if (dirnum > (total_images))
2192       {
2193       TIFFError (TIFFFileName(in), 
2194       "Invalid image number %d, File contains only %d images", 
2195                  (int)dirnum + 1, total_images);
2196       if (out != NULL)
2197         (void) TIFFClose(out);
2198       return (1);
2199       }
2200
2201     if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
2202       {
2203       TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
2204       if (out != NULL)
2205         (void) TIFFClose(out);
2206       return (1);
2207       }
2208
2209     end_of_input = FALSE;
2210     while (end_of_input == FALSE)
2211       {
2212       config = defconfig;
2213       compression = defcompression;
2214       predictor = defpredictor;
2215       fillorder = deffillorder;
2216       rowsperstrip = defrowsperstrip;
2217       tilewidth = deftilewidth;
2218       tilelength = deftilelength;
2219       g3opts = defg3opts;
2220
2221       if (dump.format != DUMP_NONE)
2222         {
2223         /* manage input and/or output dump files here */
2224         dump_images++;
2225         length = strlen(dump.infilename);
2226         if (length > 0)
2227           {
2228           if (dump.infile != NULL)
2229             fclose (dump.infile);
2230
2231           /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes 
2232              fewer than PATH_MAX */ 
2233           memset (temp_filename, '\0', PATH_MAX + 1);              
2234           sprintf (temp_filename, "%s-read-%03d.%s", dump.infilename, dump_images,
2235                   (dump.format == DUMP_TEXT) ? "txt" : "raw");
2236           if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
2237             {
2238             TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2239             exit (-1);
2240             }
2241           dump_info(dump.infile, dump.format, "Reading image","%d from %s", 
2242                     dump_images, TIFFFileName(in));
2243           } 
2244         length = strlen(dump.outfilename);
2245         if (length > 0)
2246           {
2247           if (dump.outfile != NULL)
2248             fclose (dump.outfile);
2249
2250           /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes 
2251              fewer than PATH_MAX */ 
2252           memset (temp_filename, '\0', PATH_MAX + 1);              
2253           sprintf (temp_filename, "%s-write-%03d.%s", dump.outfilename, dump_images,
2254                   (dump.format == DUMP_TEXT) ? "txt" : "raw");
2255           if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
2256             {
2257               TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2258             exit (-1);
2259             }
2260           dump_info(dump.outfile, dump.format, "Writing image","%d from %s", 
2261                     dump_images, TIFFFileName(in));
2262           } 
2263         }
2264
2265       if (dump.debug)
2266          TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
2267
2268       if (loadImage(in, &image, &dump, &read_buff))
2269         {
2270         TIFFError("main", "Unable to load source image");
2271         exit (-1);
2272         }
2273
2274       /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
2275        */
2276       if (image.adjustments != 0)
2277         {
2278         if (correct_orientation(&image, &read_buff))
2279             TIFFError("main", "Unable to correct image orientation");
2280         }
2281
2282       if (getCropOffsets(&image, &crop, &dump))
2283         {
2284         TIFFError("main", "Unable to define crop regions");
2285         exit (-1);
2286         }
2287
2288       if (crop.selections > 0)
2289         {
2290         if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
2291           {
2292           TIFFError("main", "Unable to process image selections");
2293           exit (-1);
2294           }
2295         }
2296       else  /* Single image segment without zones or regions */
2297         {
2298         if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
2299           {
2300           TIFFError("main", "Unable to create output image");
2301           exit (-1);
2302           }
2303         }
2304       if (page.mode == PAGE_MODE_NONE)
2305         {  /* Whole image or sections not based on output page size */
2306         if (crop.selections > 0)
2307           {
2308           writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
2309                           mp, argv[argc - 1], &next_page, total_pages);
2310           }
2311         else  /* One file all images and sections */
2312           {
2313           if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
2314                                   &next_page))
2315              exit (1);
2316           if (writeCroppedImage(in, out, &image, &dump,crop.combined_width, 
2317                                 crop.combined_length, crop_buff, next_page, total_pages))
2318             {
2319              TIFFError("main", "Unable to write new image");
2320              exit (-1);
2321             }
2322           }
2323         }
2324       else
2325         {
2326         /* If we used a crop buffer, our data is there, otherwise it is
2327          * in the read_buffer
2328          */
2329         if (crop_buff != NULL)  
2330           sect_src = crop_buff;
2331         else
2332           sect_src = read_buff;
2333         /* Break input image into pages or rows and columns */
2334         if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
2335           {
2336           TIFFError("main", "Unable to compute output section data");
2337           exit (-1);
2338           }
2339         /* If there are multiple files on the command line, the final one is assumed 
2340          * to be the output filename into which the images are written.
2341          */
2342         if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
2343           exit (1);
2344
2345         if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, &sect_buff))
2346           {
2347           TIFFError("main", "Unable to write image sections");
2348           exit (-1);
2349           }
2350         }
2351
2352       /* No image list specified, just read the next image */
2353       if (image_count == 0)
2354         dirnum++;
2355       else
2356         {
2357         dirnum = (tdir_t)(imagelist[next_image] - 1);
2358         next_image++;
2359         }
2360
2361       if (dirnum == MAX_IMAGES - 1)
2362         dirnum = TIFFNumberOfDirectories(in) - 1;
2363
2364       if (!TIFFSetDirectory(in, (tdir_t)dirnum))
2365         end_of_input = TRUE;
2366       }
2367     TIFFClose(in);
2368     optind++;
2369     }
2370
2371   /* If we did not use the read buffer as the crop buffer */
2372   if (read_buff)
2373     _TIFFfree(read_buff);
2374
2375   if (crop_buff)
2376     _TIFFfree(crop_buff);
2377
2378   if (sect_buff)
2379     _TIFFfree(sect_buff);
2380
2381    /* Clean up any segment buffers used for zones or regions */
2382   for (seg = 0; seg < crop.selections; seg++)
2383     _TIFFfree (seg_buffs[seg].buffer);
2384
2385   if (dump.format != DUMP_NONE)
2386     {
2387     if (dump.infile != NULL)
2388      fclose (dump.infile);
2389
2390     if (dump.outfile != NULL)
2391       {
2392       dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
2393       fclose (dump.outfile);
2394       }
2395     }
2396
2397   TIFFClose(out);
2398
2399   return (0);
2400   } /* end main */
2401
2402
2403 /* Debugging functions */
2404 static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
2405   {
2406   int j, k;
2407   uint32 i;
2408   char  dump_array[10];
2409   unsigned char bitset;
2410
2411   if (dumpfile == NULL)
2412     {
2413     TIFFError ("", "Invalid FILE pointer for dump file");
2414     return (1);
2415     }
2416
2417   if (format == DUMP_TEXT)
2418     {
2419     fprintf (dumpfile," %s  ", dump_tag);
2420     for (i = 0; i < count; i++)
2421       {
2422       for (j = 0, k = 7; j < 8; j++, k--)
2423         {
2424         bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
2425         sprintf(&dump_array[j], (bitset) ? "1" : "0");
2426         }
2427       dump_array[8] = '\0';
2428       fprintf (dumpfile," %s", dump_array);
2429       }
2430     fprintf (dumpfile,"\n");
2431     }
2432   else
2433     {
2434     if ((fwrite (data, 1, count, dumpfile)) != count)
2435       {
2436       TIFFError ("", "Unable to write binary data to dump file");
2437       return (1);
2438       }
2439     }
2440
2441   return (0);
2442   }
2443
2444 static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
2445   {
2446   int j, k;
2447   char  dump_array[10];
2448   unsigned char bitset;
2449
2450   if (dumpfile == NULL)
2451     {
2452     TIFFError ("", "Invalid FILE pointer for dump file");
2453     return (1);
2454     }
2455
2456   if (format == DUMP_TEXT)
2457     {
2458     fprintf (dumpfile," %s  ", dump_tag);
2459     for (j = 0, k = 7; j < 8; j++, k--)
2460       {
2461       bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2462       sprintf(&dump_array[j], (bitset) ? "1" : "0");
2463       }
2464     dump_array[8] = '\0';
2465     fprintf (dumpfile," %s\n", dump_array);
2466     }
2467   else
2468     {
2469     if ((fwrite (&data, 1, 1, dumpfile)) != 1)
2470       {
2471       TIFFError ("", "Unable to write binary data to dump file");
2472       return (1);
2473       }
2474     }
2475
2476   return (0);
2477   }
2478
2479 static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
2480   {
2481   int j, k;
2482   char  dump_array[20];
2483   unsigned char bitset;
2484
2485   if (dumpfile == NULL)
2486     {
2487     TIFFError ("", "Invalid FILE pointer for dump file");
2488     return (1);
2489     }
2490
2491   if (format == DUMP_TEXT)
2492     {
2493     fprintf (dumpfile," %s  ", dump_tag);
2494     for (j = 0, k = 15; k >= 0; j++, k--)
2495       {
2496       bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2497       sprintf(&dump_array[j], (bitset) ? "1" : "0");
2498       if ((k % 8) == 0)
2499           sprintf(&dump_array[++j], " ");
2500       }
2501     dump_array[17] = '\0';
2502     fprintf (dumpfile," %s\n", dump_array);
2503     }
2504   else
2505     {
2506     if ((fwrite (&data, 2, 1, dumpfile)) != 2)
2507       {
2508       TIFFError ("", "Unable to write binary data to dump file");
2509       return (1);
2510       }
2511     }
2512
2513   return (0);
2514   }
2515
2516 static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
2517   {
2518   int j, k;
2519   char  dump_array[40];
2520   unsigned char bitset;
2521
2522   if (dumpfile == NULL)
2523     {
2524     TIFFError ("", "Invalid FILE pointer for dump file");
2525     return (1);
2526     }
2527
2528   if (format == DUMP_TEXT)
2529     {
2530     fprintf (dumpfile," %s  ", dump_tag);
2531     for (j = 0, k = 31; k >= 0; j++, k--)
2532       {
2533       bitset = data & (((uint32)1 << k)) ? 1 : 0;
2534       sprintf(&dump_array[j], (bitset) ? "1" : "0");
2535       if ((k % 8) == 0)
2536           sprintf(&dump_array[++j], " ");
2537       }
2538     dump_array[35] = '\0';
2539     fprintf (dumpfile," %s\n", dump_array);
2540     }
2541   else
2542     {
2543     if ((fwrite (&data, 4, 1, dumpfile)) != 4)
2544       {
2545       TIFFError ("", "Unable to write binary data to dump file");
2546       return (1);
2547       }
2548     }
2549   return (0);
2550   }
2551
2552 static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
2553   {
2554   int j, k;
2555   char  dump_array[80];
2556   unsigned char bitset;
2557
2558   if (dumpfile == NULL)
2559     {
2560     TIFFError ("", "Invalid FILE pointer for dump file");
2561     return (1);
2562     }
2563
2564   if (format == DUMP_TEXT)
2565     {
2566     fprintf (dumpfile," %s  ", dump_tag);
2567     for (j = 0, k = 63; k >= 0; j++, k--)
2568       {
2569       bitset = data & (((uint64)1 << k)) ? 1 : 0;
2570       sprintf(&dump_array[j], (bitset) ? "1" : "0");
2571       if ((k % 8) == 0)
2572           sprintf(&dump_array[++j], " ");
2573       }
2574     dump_array[71] = '\0';
2575     fprintf (dumpfile," %s\n", dump_array);
2576     }
2577   else
2578     {
2579     if ((fwrite (&data, 8, 1, dumpfile)) != 8)
2580       {
2581       TIFFError ("", "Unable to write binary data to dump file");
2582       return (1);
2583       }
2584     }
2585
2586   return (0);
2587   }
2588
2589 static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
2590   {
2591   if (format == DUMP_TEXT)
2592     {
2593     va_list ap;
2594     va_start(ap, msg);
2595     fprintf(dumpfile, "%s ", prefix);
2596     vfprintf(dumpfile, msg, ap);
2597     fprintf(dumpfile, "\n");
2598     }
2599   }
2600
2601 static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width, 
2602                  uint32 row, unsigned char *buff)
2603   {
2604   int j, k;
2605   uint32 i;
2606   unsigned char * dump_ptr;
2607
2608   if (dumpfile == NULL)
2609     {
2610     TIFFError ("", "Invalid FILE pointer for dump file");
2611     return (1);
2612     }
2613
2614   for (i = 0; i < rows; i++)
2615     {
2616     dump_ptr = buff + (i * width);
2617     if (format == DUMP_TEXT)
2618       dump_info (dumpfile, format, "", 
2619                  "Row %4d, %d bytes at offset %d",
2620                  row + i + 1, width, row * width);
2621      
2622     for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
2623       dump_data (dumpfile, format, "", dump_ptr, 10);
2624     if (k > 0)
2625       dump_data (dumpfile, format, "", dump_ptr, k);
2626     }
2627   return (0);
2628   }
2629
2630 /* Extract one or more samples from an interleaved buffer. If count == 1,
2631  * only the sample plane indicated by sample will be extracted.  If count > 1, 
2632  * count samples beginning at sample will be extracted. Portions of a 
2633  * scanline can be extracted by specifying a start and end value.
2634  */
2635
2636 static int 
2637 extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols, 
2638                            tsample_t sample, uint16 spp, uint16 bps, 
2639                            tsample_t count, uint32 start, uint32 end)
2640   {
2641   int i, bytes_per_sample, sindex;
2642   uint32 col, dst_rowsize, bit_offset;
2643   uint32 src_byte, src_bit;
2644   uint8 *src = in;
2645   uint8 *dst = out;
2646
2647   if ((src == NULL) || (dst == NULL))
2648     {
2649     TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
2650     return (1);
2651     }
2652
2653   if ((start > end) || (start > cols))
2654     {
2655     TIFFError ("extractContigSamplesBytes", 
2656                "Invalid start column value %d ignored", start);
2657     start = 0;
2658     }
2659   if ((end == 0) || (end > cols))
2660     {
2661     TIFFError ("extractContigSamplesBytes", 
2662                "Invalid end column value %d ignored", end);
2663     end = cols;
2664     }
2665
2666   dst_rowsize = (bps * (end - start) * count) / 8;
2667
2668   bytes_per_sample = (bps + 7) / 8; 
2669   /* Optimize case for copying all samples */
2670   if (count == spp)
2671     {
2672     src = in + (start * spp * bytes_per_sample);
2673     _TIFFmemcpy (dst, src, dst_rowsize);
2674     }
2675   else
2676     {
2677     for (col = start; col < end; col++)
2678       {
2679       for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2680         {
2681         bit_offset = col * bps * spp;
2682         if (sindex == 0)
2683           {
2684           src_byte = bit_offset / 8;
2685           src_bit  = bit_offset % 8;
2686           }
2687         else
2688           {
2689           src_byte = (bit_offset + (sindex * bps)) / 8;
2690           src_bit  = (bit_offset + (sindex * bps)) % 8;
2691           }
2692         src = in + src_byte;
2693         for (i = 0; i < bytes_per_sample; i++)
2694             *dst++ = *src++;
2695         }
2696       }
2697     }
2698
2699   return (0);
2700   } /* end extractContigSamplesBytes */
2701
2702 static int
2703 extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
2704                            tsample_t sample, uint16 spp, uint16 bps, 
2705                            tsample_t count, uint32 start, uint32 end)
2706   {
2707   int    ready_bits = 0, sindex = 0;
2708   uint32 col, src_byte, src_bit, bit_offset;
2709   uint8  maskbits = 0, matchbits = 0;
2710   uint8  buff1 = 0, buff2 = 0;
2711   uint8 *src = in;
2712   uint8 *dst = out;
2713
2714   if ((src == NULL) || (dst == NULL))
2715     {
2716     TIFFError("extractContigSamples8bits","Invalid input or output buffer");
2717     return (1);
2718     }
2719
2720   if ((start > end) || (start > cols))
2721     {
2722     TIFFError ("extractContigSamples8bits", 
2723                "Invalid start column value %d ignored", start);
2724     start = 0;
2725     }
2726   if ((end == 0) || (end > cols))
2727     {
2728     TIFFError ("extractContigSamples8bits", 
2729                "Invalid end column value %d ignored", end);
2730     end = cols;
2731     }
2732   
2733   ready_bits = 0;
2734   maskbits =  (uint8)-1 >> ( 8 - bps);
2735   buff1 = buff2 = 0;
2736   for (col = start; col < end; col++)
2737     {    /* Compute src byte(s) and bits within byte(s) */
2738     bit_offset = col * bps * spp;
2739     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2740       {
2741       if (sindex == 0)
2742         {
2743         src_byte = bit_offset / 8;
2744         src_bit  = bit_offset % 8;
2745         }
2746       else
2747         {
2748         src_byte = (bit_offset + (sindex * bps)) / 8;
2749         src_bit  = (bit_offset + (sindex * bps)) % 8;
2750         }
2751
2752       src = in + src_byte;
2753       matchbits = maskbits << (8 - src_bit - bps); 
2754       buff1 = ((*src) & matchbits) << (src_bit);
2755
2756       /* If we have a full buffer's worth, write it out */
2757       if (ready_bits >= 8)
2758         {
2759         *dst++ = buff2;
2760         buff2 = buff1;
2761         ready_bits -= 8;
2762         }
2763       else
2764         buff2 = (buff2 | (buff1 >> ready_bits));
2765       ready_bits += bps;
2766       }
2767     }
2768
2769   while (ready_bits > 0)
2770     {
2771     buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
2772     *dst++ = buff1;
2773     ready_bits -= 8;
2774     }
2775
2776   return (0);
2777   } /* end extractContigSamples8bits */
2778
2779 static int
2780 extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols, 
2781                             tsample_t sample, uint16 spp, uint16 bps, 
2782                             tsample_t count, uint32 start, uint32 end)
2783   {
2784   int    ready_bits = 0, sindex = 0;
2785   uint32 col, src_byte, src_bit, bit_offset;
2786   uint16 maskbits = 0, matchbits = 0;
2787   uint16 buff1 = 0, buff2 = 0;
2788   uint8  bytebuff = 0;
2789   uint8 *src = in;
2790   uint8 *dst = out;
2791
2792   if ((src == NULL) || (dst == NULL))
2793     {
2794     TIFFError("extractContigSamples16bits","Invalid input or output buffer");
2795     return (1);
2796     }
2797
2798   if ((start > end) || (start > cols))
2799     {
2800     TIFFError ("extractContigSamples16bits", 
2801                "Invalid start column value %d ignored", start);
2802     start = 0;
2803     }
2804   if ((end == 0) || (end > cols))
2805     {
2806     TIFFError ("extractContigSamples16bits", 
2807                "Invalid end column value %d ignored", end);
2808     end = cols;
2809     }
2810
2811   ready_bits = 0;
2812   maskbits = (uint16)-1 >> (16 - bps);
2813
2814   for (col = start; col < end; col++)
2815     {    /* Compute src byte(s) and bits within byte(s) */
2816     bit_offset = col * bps * spp;
2817     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2818       {
2819       if (sindex == 0)
2820         {
2821         src_byte = bit_offset / 8;
2822         src_bit  = bit_offset % 8;
2823         }
2824       else
2825         {
2826         src_byte = (bit_offset + (sindex * bps)) / 8;
2827         src_bit  = (bit_offset + (sindex * bps)) % 8;
2828         }
2829
2830       src = in + src_byte;
2831       matchbits = maskbits << (16 - src_bit - bps); 
2832
2833       if (little_endian)
2834         buff1 = (src[0] << 8) | src[1];
2835       else
2836         buff1 = (src[1] << 8) | src[0];
2837
2838       buff1 = (buff1 & matchbits) << (src_bit);
2839       if (ready_bits < 8) /* add another bps bits to the buffer */
2840         { 
2841         bytebuff = 0;
2842         buff2 = (buff2 | (buff1 >> ready_bits));
2843         }
2844       else /* If we have a full buffer's worth, write it out */
2845         {
2846         bytebuff = (buff2 >> 8);
2847         *dst++ = bytebuff;
2848         ready_bits -= 8;
2849         /* shift in new bits */
2850         buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
2851         }
2852       ready_bits += bps;
2853       }
2854     }
2855
2856   /* catch any trailing bits at the end of the line */
2857   while (ready_bits > 0)
2858     {
2859     bytebuff = (buff2 >> 8);
2860     *dst++ = bytebuff;
2861     ready_bits -= 8;
2862     }
2863   
2864   return (0);
2865   } /* end extractContigSamples16bits */
2866
2867
2868 static int
2869 extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
2870                             tsample_t sample, uint16 spp, uint16 bps, 
2871                             tsample_t count, uint32 start, uint32 end)
2872   {
2873   int    ready_bits = 0, sindex = 0;
2874   uint32 col, src_byte, src_bit, bit_offset;
2875   uint32 maskbits = 0, matchbits = 0;
2876   uint32 buff1 = 0, buff2 = 0;
2877   uint8  bytebuff1 = 0, bytebuff2 = 0;
2878   uint8 *src = in;
2879   uint8 *dst = out;
2880
2881   if ((in == NULL) || (out == NULL))
2882     {
2883     TIFFError("extractContigSamples24bits","Invalid input or output buffer");
2884     return (1);
2885     }
2886
2887   if ((start > end) || (start > cols))
2888     {
2889     TIFFError ("extractContigSamples24bits", 
2890                "Invalid start column value %d ignored", start);
2891     start = 0;
2892     }
2893   if ((end == 0) || (end > cols))
2894     {
2895     TIFFError ("extractContigSamples24bits", 
2896                "Invalid end column value %d ignored", end);
2897     end = cols;
2898     }
2899
2900   ready_bits = 0;
2901   maskbits =  (uint32)-1 >> ( 32 - bps);
2902   for (col = start; col < end; col++)
2903     {
2904     /* Compute src byte(s) and bits within byte(s) */
2905     bit_offset = col * bps * spp;
2906     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2907       {
2908       if (sindex == 0)
2909         {
2910         src_byte = bit_offset / 8;
2911         src_bit  = bit_offset % 8;
2912         }
2913       else
2914         {
2915         src_byte = (bit_offset + (sindex * bps)) / 8;
2916         src_bit  = (bit_offset + (sindex * bps)) % 8;
2917         }
2918
2919       src = in + src_byte;
2920       matchbits = maskbits << (32 - src_bit - bps); 
2921       if (little_endian)
2922         buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
2923       else
2924         buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
2925       buff1 = (buff1 & matchbits) << (src_bit);
2926
2927       if (ready_bits < 16) /* add another bps bits to the buffer */
2928         {
2929         bytebuff1 = bytebuff2 = 0;
2930         buff2 = (buff2 | (buff1 >> ready_bits));
2931         }
2932       else /* If we have a full buffer's worth, write it out */
2933         {
2934         bytebuff1 = (buff2 >> 24);
2935         *dst++ = bytebuff1;
2936         bytebuff2 = (buff2 >> 16);
2937         *dst++ = bytebuff2;
2938         ready_bits -= 16;
2939
2940         /* shift in new bits */
2941         buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
2942         }
2943       ready_bits += bps;
2944       }
2945     }
2946
2947   /* catch any trailing bits at the end of the line */
2948   while (ready_bits > 0)
2949     {
2950     bytebuff1 = (buff2 >> 24);
2951     *dst++ = bytebuff1;
2952
2953     buff2 = (buff2 << 8);
2954     bytebuff2 = bytebuff1;
2955     ready_bits -= 8;
2956     } 
2957   
2958   return (0);
2959   } /* end extractContigSamples24bits */
2960
2961 static int
2962 extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
2963                             tsample_t sample, uint16 spp, uint16 bps, 
2964                             tsample_t count, uint32 start, uint32 end)
2965   {
2966   int    ready_bits = 0, sindex = 0, shift_width = 0;
2967   uint32 col, src_byte, src_bit, bit_offset;
2968   uint32 longbuff1 = 0, longbuff2 = 0;
2969   uint64 maskbits = 0, matchbits = 0;
2970   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
2971   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
2972   uint8 *src = in;
2973   uint8 *dst = out;
2974
2975   if ((in == NULL) || (out == NULL))
2976     {
2977     TIFFError("extractContigSamples32bits","Invalid input or output buffer");
2978     return (1);
2979     }
2980
2981
2982   if ((start > end) || (start > cols))
2983     {
2984     TIFFError ("extractContigSamples32bits", 
2985                "Invalid start column value %d ignored", start);
2986     start = 0;
2987     }
2988   if ((end == 0) || (end > cols))
2989     {
2990     TIFFError ("extractContigSamples32bits", 
2991                "Invalid end column value %d ignored", end);
2992     end = cols;
2993     }
2994
2995   shift_width = ((bps + 7) / 8) + 1; 
2996   ready_bits = 0;
2997   maskbits =  (uint64)-1 >> ( 64 - bps);
2998   for (col = start; col < end; col++)
2999     {
3000     /* Compute src byte(s) and bits within byte(s) */
3001     bit_offset = col * bps * spp;
3002     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3003       {
3004       if (sindex == 0)
3005         {
3006         src_byte = bit_offset / 8;
3007         src_bit  = bit_offset % 8;
3008         }
3009       else
3010         {
3011         src_byte = (bit_offset + (sindex * bps)) / 8;
3012         src_bit  = (bit_offset + (sindex * bps)) % 8;
3013         }
3014
3015       src = in + src_byte;
3016       matchbits = maskbits << (64 - src_bit - bps); 
3017       if (little_endian)
3018         {
3019         longbuff1 = (src[0] << 24) | (src[1] << 16)  | (src[2] << 8) | src[3];
3020         longbuff2 = longbuff1;
3021         }
3022       else
3023         {
3024         longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3025         longbuff2 = longbuff1;
3026         }
3027
3028       buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3029       buff1 = (buff3 & matchbits) << (src_bit);
3030
3031       /* If we have a full buffer's worth, write it out */
3032       if (ready_bits >= 32)
3033         {
3034         bytebuff1 = (buff2 >> 56);
3035         *dst++ = bytebuff1;
3036         bytebuff2 = (buff2 >> 48);
3037         *dst++ = bytebuff2;
3038         bytebuff3 = (buff2 >> 40);
3039         *dst++ = bytebuff3;
3040         bytebuff4 = (buff2 >> 32);
3041         *dst++ = bytebuff4;
3042         ready_bits -= 32;
3043                     
3044         /* shift in new bits */
3045         buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3046         }
3047       else
3048         { /* add another bps bits to the buffer */
3049         bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3050         buff2 = (buff2 | (buff1 >> ready_bits));
3051         }
3052       ready_bits += bps;
3053       }
3054     }
3055   while (ready_bits > 0)
3056     {
3057     bytebuff1 = (buff2 >> 56);
3058     *dst++ = bytebuff1;
3059     buff2 = (buff2 << 8);
3060     ready_bits -= 8;
3061     }
3062   
3063   return (0);
3064   } /* end extractContigSamples32bits */
3065
3066 static int
3067 extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
3068                                   tsample_t sample, uint16 spp, uint16 bps, 
3069                                   tsample_t count, uint32 start, uint32 end,
3070                                   int shift)
3071   {
3072   int    ready_bits = 0, sindex = 0;
3073   uint32 col, src_byte, src_bit, bit_offset;
3074   uint8  maskbits = 0, matchbits = 0;
3075   uint8  buff1 = 0, buff2 = 0;
3076   uint8 *src = in;
3077   uint8 *dst = out;
3078
3079   if ((src == NULL) || (dst == NULL))
3080     {
3081     TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
3082     return (1);
3083     }
3084
3085   if ((start > end) || (start > cols))
3086     {
3087     TIFFError ("extractContigSamplesShifted8bits", 
3088                "Invalid start column value %d ignored", start);
3089     start = 0;
3090     }
3091   if ((end == 0) || (end > cols))
3092     {
3093     TIFFError ("extractContigSamplesShifted8bits", 
3094                "Invalid end column value %d ignored", end);
3095     end = cols;
3096     }
3097
3098   ready_bits = shift;
3099   maskbits =  (uint8)-1 >> ( 8 - bps);
3100   buff1 = buff2 = 0;
3101   for (col = start; col < end; col++)
3102     {    /* Compute src byte(s) and bits within byte(s) */
3103     bit_offset = col * bps * spp;
3104     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3105       {
3106       if (sindex == 0)
3107         {
3108         src_byte = bit_offset / 8;
3109         src_bit  = bit_offset % 8;
3110         }
3111       else
3112         {
3113         src_byte = (bit_offset + (sindex * bps)) / 8;
3114         src_bit  = (bit_offset + (sindex * bps)) % 8;
3115         }
3116
3117       src = in + src_byte;
3118       matchbits = maskbits << (8 - src_bit - bps); 
3119       buff1 = ((*src) & matchbits) << (src_bit);
3120       if ((col == start) && (sindex == sample))
3121         buff2 = *src & ((uint8)-1) << (shift);
3122
3123       /* If we have a full buffer's worth, write it out */
3124       if (ready_bits >= 8)
3125         {
3126         *dst++ |= buff2;
3127         buff2 = buff1;
3128         ready_bits -= 8;
3129         }
3130       else
3131         buff2 = buff2 | (buff1 >> ready_bits);
3132       ready_bits += bps;
3133       }
3134     }
3135
3136   while (ready_bits > 0)
3137     {
3138     buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3139     *dst++ = buff1;
3140     ready_bits -= 8;
3141     }
3142
3143   return (0);
3144   } /* end extractContigSamplesShifted8bits */
3145
3146 static int
3147 extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols, 
3148                                    tsample_t sample, uint16 spp, uint16 bps, 
3149                                    tsample_t count, uint32 start, uint32 end,
3150                                    int shift)
3151   {
3152   int    ready_bits = 0, sindex = 0;
3153   uint32 col, src_byte, src_bit, bit_offset;
3154   uint16 maskbits = 0, matchbits = 0;
3155   uint16 buff1 = 0, buff2 = 0;
3156   uint8  bytebuff = 0;
3157   uint8 *src = in;
3158   uint8 *dst = out;
3159   
3160   if ((src == NULL) || (dst == NULL))
3161     {
3162     TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
3163     return (1);
3164     }
3165
3166   if ((start > end) || (start > cols))
3167     {
3168     TIFFError ("extractContigSamplesShifted16bits", 
3169                "Invalid start column value %d ignored", start);
3170     start = 0;
3171     }
3172   if ((end == 0) || (end > cols))
3173     {
3174     TIFFError ("extractContigSamplesShifted16bits", 
3175                "Invalid end column value %d ignored", end);
3176     end = cols;
3177     }
3178
3179   ready_bits = shift;
3180   maskbits = (uint16)-1 >> (16 - bps);
3181   for (col = start; col < end; col++)
3182     {    /* Compute src byte(s) and bits within byte(s) */
3183     bit_offset = col * bps * spp;
3184     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3185       {
3186       if (sindex == 0)
3187         {
3188         src_byte = bit_offset / 8;
3189         src_bit  = bit_offset % 8;
3190         }
3191       else
3192         {
3193         src_byte = (bit_offset + (sindex * bps)) / 8;
3194         src_bit  = (bit_offset + (sindex * bps)) % 8;
3195         }
3196
3197       src = in + src_byte;
3198       matchbits = maskbits << (16 - src_bit - bps); 
3199       if (little_endian)
3200         buff1 = (src[0] << 8) | src[1];
3201       else
3202         buff1 = (src[1] << 8) | src[0];
3203
3204       if ((col == start) && (sindex == sample))
3205         buff2 = buff1 & ((uint16)-1) << (8 - shift);
3206
3207       buff1 = (buff1 & matchbits) << (src_bit);
3208
3209       if (ready_bits < 8) /* add another bps bits to the buffer */
3210         buff2 = buff2 | (buff1 >> ready_bits);
3211       else  /* If we have a full buffer's worth, write it out */
3212         {
3213         bytebuff = (buff2 >> 8);
3214         *dst++ = bytebuff;
3215         ready_bits -= 8;
3216         /* shift in new bits */
3217         buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3218         }
3219
3220       ready_bits += bps;
3221       }
3222     }
3223
3224   /* catch any trailing bits at the end of the line */
3225   while (ready_bits > 0)
3226     {
3227     bytebuff = (buff2 >> 8);
3228     *dst++ = bytebuff;
3229     ready_bits -= 8;
3230     }
3231   
3232   return (0);
3233   } /* end extractContigSamplesShifted16bits */
3234
3235
3236 static int
3237 extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
3238                                    tsample_t sample, uint16 spp, uint16 bps, 
3239                                    tsample_t count, uint32 start, uint32 end,
3240                                    int shift)
3241   {
3242   int    ready_bits = 0, sindex = 0;
3243   uint32 col, src_byte, src_bit, bit_offset;
3244   uint32 maskbits = 0, matchbits = 0;
3245   uint32 buff1 = 0, buff2 = 0;
3246   uint8  bytebuff1 = 0, bytebuff2 = 0;
3247   uint8 *src = in;
3248   uint8 *dst = out;
3249
3250   if ((in == NULL) || (out == NULL))
3251     {
3252     TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
3253     return (1);
3254     }
3255
3256   if ((start > end) || (start > cols))
3257     {
3258     TIFFError ("extractContigSamplesShifted24bits", 
3259                "Invalid start column value %d ignored", start);
3260     start = 0;
3261     }
3262   if ((end == 0) || (end > cols))
3263     {
3264     TIFFError ("extractContigSamplesShifted24bits", 
3265                "Invalid end column value %d ignored", end);
3266     end = cols;
3267     }
3268
3269   ready_bits = shift;
3270   maskbits =  (uint32)-1 >> ( 32 - bps);
3271   for (col = start; col < end; col++)
3272     {
3273     /* Compute src byte(s) and bits within byte(s) */
3274     bit_offset = col * bps * spp;
3275     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3276       {
3277       if (sindex == 0)
3278         {
3279         src_byte = bit_offset / 8;
3280         src_bit  = bit_offset % 8;
3281         }
3282       else
3283         {
3284         src_byte = (bit_offset + (sindex * bps)) / 8;
3285         src_bit  = (bit_offset + (sindex * bps)) % 8;
3286         }
3287
3288       src = in + src_byte;
3289       matchbits = maskbits << (32 - src_bit - bps); 
3290       if (little_endian)
3291         buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3292       else
3293         buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3294
3295       if ((col == start) && (sindex == sample))
3296         buff2 = buff1 & ((uint32)-1) << (16 - shift);
3297
3298       buff1 = (buff1 & matchbits) << (src_bit);
3299
3300       if (ready_bits < 16)  /* add another bps bits to the buffer */
3301         {
3302         bytebuff1 = bytebuff2 = 0;
3303         buff2 = (buff2 | (buff1 >> ready_bits));
3304         }
3305       else /* If we have a full buffer's worth, write it out */
3306         {
3307         bytebuff1 = (buff2 >> 24);
3308         *dst++ = bytebuff1;
3309         bytebuff2 = (buff2 >> 16);
3310         *dst++ = bytebuff2;
3311         ready_bits -= 16;
3312
3313         /* shift in new bits */
3314         buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3315         }
3316       ready_bits += bps;
3317       }
3318     }
3319
3320   /* catch any trailing bits at the end of the line */
3321   while (ready_bits > 0)
3322     {
3323     bytebuff1 = (buff2 >> 24);
3324     *dst++ = bytebuff1;
3325
3326     buff2 = (buff2 << 8);
3327     bytebuff2 = bytebuff1;
3328     ready_bits -= 8;
3329     }
3330    
3331   return (0);
3332   } /* end extractContigSamplesShifted24bits */
3333
3334 static int
3335 extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
3336                                    tsample_t sample, uint16 spp, uint16 bps, 
3337                                    tsample_t count, uint32 start, uint32 end,
3338                                    int shift)
3339   {
3340   int    ready_bits = 0, sindex = 0, shift_width = 0;
3341   uint32 col, src_byte, src_bit, bit_offset;
3342   uint32 longbuff1 = 0, longbuff2 = 0;
3343   uint64 maskbits = 0, matchbits = 0;
3344   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3345   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3346   uint8 *src = in;
3347   uint8 *dst = out;
3348
3349   if ((in == NULL) || (out == NULL))
3350     {
3351     TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
3352     return (1);
3353     }
3354
3355
3356   if ((start > end) || (start > cols))
3357     {
3358     TIFFError ("extractContigSamplesShifted32bits", 
3359                "Invalid start column value %d ignored", start);
3360     start = 0;
3361     }
3362   if ((end == 0) || (end > cols))
3363     {
3364     TIFFError ("extractContigSamplesShifted32bits", 
3365                "Invalid end column value %d ignored", end);
3366     end = cols;
3367     }
3368
3369   shift_width = ((bps + 7) / 8) + 1; 
3370   ready_bits = shift;
3371   maskbits =  (uint64)-1 >> ( 64 - bps);
3372   for (col = start; col < end; col++)
3373     {
3374     /* Compute src byte(s) and bits within byte(s) */
3375     bit_offset = col * bps * spp;
3376     for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3377       {
3378       if (sindex == 0)
3379         {
3380         src_byte = bit_offset / 8;
3381         src_bit  = bit_offset % 8;
3382         }
3383       else
3384         {
3385         src_byte = (bit_offset + (sindex * bps)) / 8;
3386         src_bit  = (bit_offset + (sindex * bps)) % 8;
3387         }
3388
3389       src = in + src_byte;
3390       matchbits = maskbits << (64 - src_bit - bps); 
3391       if (little_endian)
3392         {
3393         longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3394         longbuff2 = longbuff1;
3395         }
3396       else
3397         {
3398         longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3399         longbuff2 = longbuff1;
3400         }
3401
3402       buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3403       if ((col == start) && (sindex == sample))
3404         buff2 = buff3 & ((uint64)-1) << (32 - shift);
3405
3406       buff1 = (buff3 & matchbits) << (src_bit);
3407
3408       if (ready_bits < 32)
3409         { /* add another bps bits to the buffer */
3410         bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3411         buff2 = (buff2 | (buff1 >> ready_bits));
3412         }
3413       else  /* If we have a full buffer's worth, write it out */
3414         {
3415         bytebuff1 = (buff2 >> 56);
3416         *dst++ = bytebuff1;
3417         bytebuff2 = (buff2 >> 48);
3418         *dst++ = bytebuff2;
3419         bytebuff3 = (buff2 >> 40);
3420         *dst++ = bytebuff3;
3421         bytebuff4 = (buff2 >> 32);
3422         *dst++ = bytebuff4;
3423         ready_bits -= 32;
3424                     
3425         /* shift in new bits */
3426         buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3427         }
3428       ready_bits += bps;
3429       }
3430     }
3431   while (ready_bits > 0)
3432     {
3433     bytebuff1 = (buff2 >> 56);
3434     *dst++ = bytebuff1;
3435     buff2 = (buff2 << 8);
3436     ready_bits -= 8;
3437     }
3438   
3439   return (0);
3440   } /* end extractContigSamplesShifted32bits */
3441
3442 static int
3443 extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3444                              tsample_t sample, uint16 spp, uint16 bps, 
3445                              struct dump_opts *dump)
3446   {
3447   int    shift_width, bytes_per_sample, bytes_per_pixel;
3448   uint32 src_rowsize, src_offset, row, first_col = 0;
3449   uint32 dst_rowsize, dst_offset;
3450   tsample_t count = 1;
3451   uint8 *src, *dst;
3452
3453   bytes_per_sample = (bps + 7) / 8; 
3454   bytes_per_pixel  = ((bps * spp) + 7) / 8;
3455   if ((bps % 8) == 0)
3456     shift_width = 0;
3457   else
3458     {
3459     if (bytes_per_pixel < (bytes_per_sample + 1))
3460       shift_width = bytes_per_pixel;
3461     else
3462       shift_width = bytes_per_sample + 1;
3463     }
3464   src_rowsize = ((bps * spp * cols) + 7) / 8;
3465   dst_rowsize = ((bps * cols) + 7) / 8;
3466
3467   if ((dump->outfile != NULL) && (dump->level == 4))
3468     {
3469     dump_info  (dump->outfile, dump->format, "extractContigSamplesToBuffer", 
3470                 "Sample %d, %d rows", sample + 1, rows + 1);
3471     }
3472   for (row = 0; row < rows; row++)
3473     {
3474     src_offset = row * src_rowsize;
3475     dst_offset = row * dst_rowsize;
3476     src = in + src_offset;
3477     dst = out + dst_offset;
3478
3479     /* pack the data into the scanline */
3480     switch (shift_width)
3481       {  
3482       case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3483                                              spp, bps,  count, first_col, cols))  
3484                 return (1);
3485               break;
3486       case 1: if (bps == 1)
3487                 {
3488                 if (extractContigSamples8bits (src, dst, cols, sample,
3489                                                spp, bps, count, first_col, cols))
3490                   return (1);
3491                 break;
3492                 }
3493               else
3494                  if (extractContigSamples16bits (src, dst, cols, sample,
3495                                                  spp, bps, count, first_col, cols))
3496                  return (1);
3497               break;
3498       case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3499                                               spp, bps,  count, first_col, cols))
3500                  return (1);
3501               break;
3502       case 3:
3503       case 4: 
3504       case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3505                                               spp, bps,  count, first_col, cols))
3506                  return (1);
3507               break;
3508       default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
3509                return (1);
3510       }
3511     if ((dump->outfile != NULL) && (dump->level == 4))
3512       dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3513     }
3514
3515   return (0);
3516   } /* end extractContigSamplesToBuffer */
3517
3518 static int
3519 extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3520                                  uint32 imagewidth, uint32 tilewidth, tsample_t sample,
3521                                  uint16 count, uint16 spp, uint16 bps, struct dump_opts *dump)
3522   {
3523   int    shift_width, bytes_per_sample, bytes_per_pixel;
3524   uint32 src_rowsize, src_offset, row;
3525   uint32 dst_rowsize, dst_offset;
3526   uint8 *src, *dst;
3527
3528   bytes_per_sample = (bps + 7) / 8; 
3529   bytes_per_pixel  = ((bps * spp) + 7) / 8;
3530   if ((bps % 8) == 0)
3531     shift_width = 0;
3532   else
3533     {
3534     if (bytes_per_pixel < (bytes_per_sample + 1))
3535       shift_width = bytes_per_pixel;
3536     else
3537       shift_width = bytes_per_sample + 1;
3538     }
3539
3540   if ((dump->outfile != NULL) && (dump->level == 4))
3541     {
3542     dump_info  (dump->outfile, dump->format, "extractContigSamplesToTileBuffer", 
3543                 "Sample %d, %d rows", sample + 1, rows + 1);
3544     }
3545
3546   src_rowsize = ((bps * spp * imagewidth) + 7) / 8;
3547   dst_rowsize = ((bps * tilewidth * count) + 7) / 8;
3548
3549   for (row = 0; row < rows; row++)
3550     {
3551     src_offset = row * src_rowsize;
3552     dst_offset = row * dst_rowsize;
3553     src = in + src_offset;
3554     dst = out + dst_offset;
3555
3556     /* pack the data into the scanline */
3557     switch (shift_width)
3558       {  
3559       case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3560                                              spp, bps,  count, 0, cols))  
3561                 return (1);
3562               break;
3563       case 1: if (bps == 1)
3564                 {
3565                 if (extractContigSamples8bits (src, dst, cols, sample,
3566                                                spp, bps, count, 0, cols))
3567                   return (1);
3568                 break;
3569                 }
3570               else
3571                  if (extractContigSamples16bits (src, dst, cols, sample,
3572                                                  spp, bps, count, 0, cols))
3573                  return (1);
3574               break;
3575       case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3576                                               spp, bps,  count, 0, cols))
3577                  return (1);
3578               break;
3579       case 3:
3580       case 4: 
3581       case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3582                                               spp, bps,  count, 0, cols))
3583                  return (1);
3584               break;
3585       default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps);
3586                return (1);
3587       }
3588     if ((dump->outfile != NULL) && (dump->level == 4))
3589       dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3590     }
3591
3592   return (0);
3593   } /* end extractContigSamplesToTileBuffer */
3594
3595 static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
3596   {
3597   uint8* bufp = buf;
3598   int32  bytes_read = 0;
3599   uint16 strip, nstrips   = TIFFNumberOfStrips(in);
3600   uint32 stripsize = TIFFStripSize(in);
3601   uint32 rows = 0;
3602   uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
3603   tsize_t scanline_size = TIFFScanlineSize(in);
3604
3605   for (strip = 0; strip < nstrips; strip++)
3606     {
3607     bytes_read = TIFFReadEncodedStrip (in, strip, bufp, -1);
3608     rows = bytes_read / scanline_size;
3609     if ((strip < (nstrips - 1)) && (bytes_read != (int32)stripsize))
3610       TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
3611                 (int)strip + 1, (unsigned long) bytes_read, (unsigned long)stripsize);
3612
3613     if (bytes_read < 0 && !ignore)
3614       {
3615       TIFFError("", "Error reading strip %lu after %lu rows",
3616                 (unsigned long) strip, (unsigned long)rows);
3617       return 0;
3618       }
3619     bufp += bytes_read;
3620     }
3621
3622  return 1;
3623   } /* end readContigStripsIntoBuffer */
3624
3625 static int 
3626 combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
3627                              uint32 cols, uint32 rows, uint16 spp, uint16 bps,
3628                              FILE *dumpfile, int format, int level)
3629   {
3630   int i, bytes_per_sample;
3631   uint32 row, col, col_offset, src_rowsize, dst_rowsize, row_offset;
3632   unsigned char *src;
3633   unsigned char *dst;
3634   tsample_t s;
3635
3636   src = srcbuffs[0];
3637   dst = out;
3638   if ((src == NULL) || (dst == NULL))
3639     {
3640     TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
3641     return (1);
3642     }
3643
3644   bytes_per_sample = (bps + 7) / 8; 
3645
3646   src_rowsize = ((bps * cols) + 7) / 8;
3647   dst_rowsize = ((bps * spp * cols) + 7) / 8;
3648   for (row = 0; row < rows; row++)
3649     {
3650     if ((dumpfile != NULL) && (level == 2))
3651       {
3652       for (s = 0; s < spp; s++)
3653         {
3654         dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
3655         dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
3656         }
3657       }
3658     dst = out + (row * dst_rowsize);
3659     row_offset = row * src_rowsize;
3660     for (col = 0; col < cols; col++)
3661       {
3662       col_offset = row_offset + (col * (bps / 8)); 
3663       for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3664         {
3665         src = srcbuffs[s] + col_offset; 
3666         for (i = 0; i < bytes_per_sample; i++)
3667           *(dst + i) = *(src + i);
3668         src += bytes_per_sample;
3669         dst += bytes_per_sample;
3670         }   
3671       }
3672
3673     if ((dumpfile != NULL) && (level == 2))
3674       {
3675       dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
3676       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3677       }
3678     }
3679
3680   return (0);
3681   } /* end combineSeparateSamplesBytes */
3682
3683 static int
3684 combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
3685                             uint32 rows, uint16 spp, uint16 bps, 
3686                             FILE *dumpfile, int format, int level)
3687   {
3688   int    ready_bits = 0;
3689   int    bytes_per_sample = 0;
3690   uint32 src_rowsize, dst_rowsize, src_offset; 
3691   uint32 bit_offset;
3692   uint32 row, col, src_byte = 0, src_bit = 0;
3693   uint8  maskbits = 0, matchbits = 0;
3694   uint8  buff1 = 0, buff2 = 0;
3695   tsample_t s;
3696   unsigned char *src = in[0];
3697   unsigned char *dst = out;
3698   char           action[32];
3699
3700   if ((src == NULL) || (dst == NULL))
3701     {
3702     TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
3703     return (1);
3704     }
3705
3706   bytes_per_sample = (bps + 7) / 8; 
3707   src_rowsize = ((bps * cols) + 7) / 8;
3708   dst_rowsize = ((bps * cols * spp) + 7) / 8;
3709   maskbits =  (uint8)-1 >> ( 8 - bps);
3710
3711   for (row = 0; row < rows; row++)
3712     {
3713     ready_bits = 0;
3714     buff1 = buff2 = 0;
3715     dst = out + (row * dst_rowsize);
3716     src_offset = row * src_rowsize;
3717     for (col = 0; col < cols; col++)
3718       {
3719       /* Compute src byte(s) and bits within byte(s) */
3720       bit_offset = col * bps;
3721       src_byte = bit_offset / 8;
3722       src_bit  = bit_offset % 8;
3723
3724       matchbits = maskbits << (8 - src_bit - bps); 
3725       /* load up next sample from each plane */
3726       for (s = 0; s < spp; s++)
3727         {
3728         src = in[s] + src_offset + src_byte;
3729         buff1 = ((*src) & matchbits) << (src_bit);
3730
3731         /* If we have a full buffer's worth, write it out */
3732         if (ready_bits >= 8)
3733           {
3734           *dst++ = buff2;
3735           buff2 = buff1;
3736           ready_bits -= 8;
3737           strcpy (action, "Flush");
3738           }
3739         else
3740           {
3741           buff2 = (buff2 | (buff1 >> ready_bits));
3742           strcpy (action, "Update");
3743           }
3744         ready_bits += bps;
3745  
3746         if ((dumpfile != NULL) && (level == 3))
3747           {
3748           dump_info (dumpfile, format, "",
3749                    "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3750                    row + 1, col + 1, s, src_byte, src_bit, dst - out);
3751           dump_byte (dumpfile, format, "Match bits", matchbits);
3752           dump_byte (dumpfile, format, "Src   bits", *src);
3753           dump_byte (dumpfile, format, "Buff1 bits", buff1);
3754           dump_byte (dumpfile, format, "Buff2 bits", buff2);
3755           dump_info (dumpfile, format, "","%s", action); 
3756           }
3757         }
3758       }
3759
3760     if (ready_bits > 0)
3761       {
3762       buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3763       *dst++ = buff1;
3764       if ((dumpfile != NULL) && (level == 3))
3765         {
3766         dump_info (dumpfile, format, "",
3767                  "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3768                  row + 1, col + 1, src_byte, src_bit, dst - out);
3769                  dump_byte (dumpfile, format, "Final bits", buff1);
3770         }
3771       }
3772
3773     if ((dumpfile != NULL) && (level >= 2))
3774       {
3775       dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
3776       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3777       }
3778     }
3779
3780   return (0);
3781   } /* end combineSeparateSamples8bits */
3782
3783 static int
3784 combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
3785                               uint32 rows, uint16 spp, uint16 bps, 
3786                               FILE *dumpfile, int format, int level)
3787   {
3788   int    ready_bits = 0, bytes_per_sample = 0;
3789   uint32 src_rowsize, dst_rowsize; 
3790   uint32 bit_offset, src_offset;
3791   uint32 row, col, src_byte = 0, src_bit = 0;
3792   uint16 maskbits = 0, matchbits = 0;
3793   uint16 buff1 = 0, buff2 = 0;
3794   uint8  bytebuff = 0;
3795   tsample_t s;
3796   unsigned char *src = in[0];
3797   unsigned char *dst = out;
3798   char           action[8];
3799
3800   if ((src == NULL) || (dst == NULL))
3801     {
3802     TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
3803     return (1);
3804     }
3805
3806   bytes_per_sample = (bps + 7) / 8; 
3807   src_rowsize = ((bps * cols) + 7) / 8;
3808   dst_rowsize = ((bps * cols * spp) + 7) / 8;
3809   maskbits = (uint16)-1 >> (16 - bps);
3810
3811   for (row = 0; row < rows; row++)
3812     {
3813     ready_bits = 0;
3814     buff1 = buff2 = 0;
3815     dst = out + (row * dst_rowsize);
3816     src_offset = row * src_rowsize;
3817     for (col = 0; col < cols; col++)
3818       {
3819       /* Compute src byte(s) and bits within byte(s) */
3820       bit_offset = col * bps;
3821       src_byte = bit_offset / 8;
3822       src_bit  = bit_offset % 8;
3823
3824       matchbits = maskbits << (16 - src_bit - bps); 
3825       for (s = 0; s < spp; s++)
3826         {
3827         src = in[s] + src_offset + src_byte;
3828         if (little_endian)
3829           buff1 = (src[0] << 8) | src[1];
3830         else
3831           buff1 = (src[1] << 8) | src[0];
3832
3833         buff1 = (buff1 & matchbits) << (src_bit);
3834
3835         /* If we have a full buffer's worth, write it out */
3836         if (ready_bits >= 8)
3837           {
3838             bytebuff = (buff2 >> 8);
3839             *dst++ = bytebuff;
3840             ready_bits -= 8;
3841             /* shift in new bits */
3842             buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3843             strcpy (action, "Flush");
3844           }
3845         else
3846           { /* add another bps bits to the buffer */
3847             bytebuff = 0;
3848             buff2 = (buff2 | (buff1 >> ready_bits));
3849             strcpy (action, "Update");
3850           }
3851         ready_bits += bps;
3852
3853         if ((dumpfile != NULL) && (level == 3))
3854           {
3855           dump_info (dumpfile, format, "",
3856                        "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3857                        row + 1, col + 1, s, src_byte, src_bit, dst - out);
3858
3859           dump_short (dumpfile, format, "Match bits", matchbits);
3860           dump_data  (dumpfile, format, "Src   bits", src, 2);
3861           dump_short (dumpfile, format, "Buff1 bits", buff1);
3862           dump_short (dumpfile, format, "Buff2 bits", buff2);
3863           dump_byte  (dumpfile, format, "Write byte", bytebuff);
3864           dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
3865           }
3866         }
3867       }
3868
3869     /* catch any trailing bits at the end of the line */
3870     if (ready_bits > 0)
3871       {
3872       bytebuff = (buff2 >> 8);
3873       *dst++ = bytebuff;
3874       if ((dumpfile != NULL) && (level == 3))
3875         {
3876         dump_info (dumpfile, format, "",
3877                        "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3878                        row + 1, col + 1, src_byte, src_bit, dst - out);
3879         dump_byte (dumpfile, format, "Final bits", bytebuff);
3880         }
3881       }
3882
3883     if ((dumpfile != NULL) && (level == 2))
3884       {
3885       dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
3886       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3887       }
3888     }
3889
3890   return (0);
3891   } /* end combineSeparateSamples16bits */
3892
3893 static int
3894 combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
3895                               uint32 rows, uint16 spp, uint16 bps, 
3896                               FILE *dumpfile, int format, int level)
3897   {
3898   int    ready_bits = 0, bytes_per_sample = 0;
3899   uint32 src_rowsize, dst_rowsize; 
3900   uint32 bit_offset, src_offset;
3901   uint32 row, col, src_byte = 0, src_bit = 0;
3902   uint32 maskbits = 0, matchbits = 0;
3903   uint32 buff1 = 0, buff2 = 0;
3904   uint8  bytebuff1 = 0, bytebuff2 = 0;
3905   tsample_t s;
3906   unsigned char *src = in[0];
3907   unsigned char *dst = out;
3908   char           action[8];
3909
3910   if ((src == NULL) || (dst == NULL))
3911     {
3912     TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
3913     return (1);
3914     }
3915
3916   bytes_per_sample = (bps + 7) / 8; 
3917   src_rowsize = ((bps * cols) + 7) / 8;
3918   dst_rowsize = ((bps * cols * spp) + 7) / 8;
3919   maskbits =  (uint32)-1 >> ( 32 - bps);
3920
3921   for (row = 0; row < rows; row++)
3922     {
3923     ready_bits = 0;
3924     buff1 = buff2 = 0;
3925     dst = out + (row * dst_rowsize);
3926     src_offset = row * src_rowsize;
3927     for (col = 0; col < cols; col++)
3928       {
3929       /* Compute src byte(s) and bits within byte(s) */
3930       bit_offset = col * bps;
3931       src_byte = bit_offset / 8;
3932       src_bit  = bit_offset % 8;
3933
3934       matchbits = maskbits << (32 - src_bit - bps); 
3935       for (s = 0; s < spp; s++)
3936         {
3937         src = in[s] + src_offset + src_byte;
3938         if (little_endian)
3939           buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3940         else
3941           buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3942         buff1 = (buff1 & matchbits) << (src_bit);
3943
3944         /* If we have a full buffer's worth, write it out */
3945         if (ready_bits >= 16)
3946           {
3947             bytebuff1 = (buff2 >> 24);
3948             *dst++ = bytebuff1;
3949             bytebuff2 = (buff2 >> 16);
3950             *dst++ = bytebuff2;
3951             ready_bits -= 16;
3952
3953             /* shift in new bits */
3954             buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3955             strcpy (action, "Flush");
3956           }
3957         else
3958           { /* add another bps bits to the buffer */
3959             bytebuff1 = bytebuff2 = 0;
3960             buff2 = (buff2 | (buff1 >> ready_bits));
3961             strcpy (action, "Update");
3962           }
3963         ready_bits += bps;
3964
3965         if ((dumpfile != NULL) && (level == 3))
3966           {
3967           dump_info (dumpfile, format, "",
3968                        "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3969                        row + 1, col + 1, s, src_byte, src_bit, dst - out);
3970           dump_long (dumpfile, format, "Match bits ", matchbits);
3971           dump_data (dumpfile, format, "Src   bits ", src, 4);
3972           dump_long (dumpfile, format, "Buff1 bits ", buff1);
3973           dump_long (dumpfile, format, "Buff2 bits ", buff2);
3974           dump_byte (dumpfile, format, "Write bits1", bytebuff1);
3975           dump_byte (dumpfile, format, "Write bits2", bytebuff2);
3976           dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
3977           }
3978         }
3979       }
3980
3981     /* catch any trailing bits at the end of the line */
3982     while (ready_bits > 0)
3983       {
3984         bytebuff1 = (buff2 >> 24);
3985         *dst++ = bytebuff1;
3986
3987         buff2 = (buff2 << 8);
3988         bytebuff2 = bytebuff1;
3989         ready_bits -= 8;
3990       }
3991  
3992     if ((dumpfile != NULL) && (level == 3))
3993       {
3994       dump_info (dumpfile, format, "",
3995                    "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
3996                    row + 1, col + 1, src_byte, src_bit, dst - out);
3997
3998       dump_long (dumpfile, format, "Match bits ", matchbits);
3999       dump_data (dumpfile, format, "Src   bits ", src, 4);
4000       dump_long (dumpfile, format, "Buff1 bits ", buff1);
4001       dump_long (dumpfile, format, "Buff2 bits ", buff2);
4002       dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4003       dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4004       dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
4005       }
4006
4007     if ((dumpfile != NULL) && (level == 2))
4008       {
4009       dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
4010       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4011       }
4012     }
4013   
4014   return (0);
4015   } /* end combineSeparateSamples24bits */
4016
4017 static int
4018 combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4019                               uint32 rows, uint16 spp, uint16 bps, 
4020                               FILE *dumpfile, int format, int level)
4021   {
4022   int    ready_bits = 0, bytes_per_sample = 0, shift_width = 0;
4023   uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4024   uint32 src_byte = 0, src_bit = 0;
4025   uint32 row, col;
4026   uint32 longbuff1 = 0, longbuff2 = 0;
4027   uint64 maskbits = 0, matchbits = 0;
4028   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4029   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4030   tsample_t s;
4031   unsigned char *src = in[0];
4032   unsigned char *dst = out;
4033   char           action[8];
4034
4035   if ((src == NULL) || (dst == NULL))
4036     {
4037     TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
4038     return (1);
4039     }
4040
4041   bytes_per_sample = (bps + 7) / 8; 
4042   src_rowsize = ((bps * cols) + 7) / 8;
4043   dst_rowsize = ((bps * cols * spp) + 7) / 8;
4044   maskbits =  (uint64)-1 >> ( 64 - bps);
4045   shift_width = ((bps + 7) / 8) + 1; 
4046
4047   for (row = 0; row < rows; row++)
4048     {
4049     ready_bits = 0;
4050     buff1 = buff2 = 0;
4051     dst = out + (row * dst_rowsize);
4052     src_offset = row * src_rowsize;
4053     for (col = 0; col < cols; col++)
4054       {
4055       /* Compute src byte(s) and bits within byte(s) */
4056       bit_offset = col * bps;
4057       src_byte = bit_offset / 8;
4058       src_bit  = bit_offset % 8;
4059
4060       matchbits = maskbits << (64 - src_bit - bps); 
4061       for (s = 0; s < spp; s++)
4062         {
4063         src = in[s] + src_offset + src_byte;
4064         if (little_endian)
4065           {
4066           longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4067           longbuff2 = longbuff1;
4068           }
4069         else
4070           {
4071           longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4072           longbuff2 = longbuff1;
4073           }
4074         buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4075         buff1 = (buff3 & matchbits) << (src_bit);
4076
4077         /* If we have a full buffer's worth, write it out */
4078         if (ready_bits >= 32)
4079           {
4080           bytebuff1 = (buff2 >> 56);
4081           *dst++ = bytebuff1;
4082           bytebuff2 = (buff2 >> 48);
4083           *dst++ = bytebuff2;
4084           bytebuff3 = (buff2 >> 40);
4085           *dst++ = bytebuff3;
4086           bytebuff4 = (buff2 >> 32);
4087           *dst++ = bytebuff4;
4088           ready_bits -= 32;
4089                     
4090           /* shift in new bits */
4091           buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4092           strcpy (action, "Flush");
4093           }
4094         else
4095           { /* add another bps bits to the buffer */
4096           bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4097           buff2 = (buff2 | (buff1 >> ready_bits));
4098           strcpy (action, "Update");
4099           }
4100         ready_bits += bps;
4101
4102         if ((dumpfile != NULL) && (level == 3))
4103           { 
4104           dump_info (dumpfile, format, "",
4105                      "Row %3d, Col %3d, Sample %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4106                      row + 1, col + 1, s, src_byte, src_bit, dst - out);
4107           dump_wide (dumpfile, format, "Match bits ", matchbits);
4108           dump_data (dumpfile, format, "Src   bits ", src, 8);
4109           dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4110           dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4111           dump_info (dumpfile, format, "", "Ready bits:   %d, %s", ready_bits, action); 
4112           }
4113         }
4114       }
4115     while (ready_bits > 0)
4116       {
4117       bytebuff1 = (buff2 >> 56);
4118       *dst++ = bytebuff1;
4119       buff2 = (buff2 << 8);
4120       ready_bits -= 8;
4121       }
4122
4123     if ((dumpfile != NULL) && (level == 3))
4124       {
4125       dump_info (dumpfile, format, "",
4126                  "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4127                  row + 1, col + 1, src_byte, src_bit, dst - out);
4128
4129       dump_long (dumpfile, format, "Match bits ", matchbits);
4130       dump_data (dumpfile, format, "Src   bits ", src, 4);
4131       dump_long (dumpfile, format, "Buff1 bits ", buff1);
4132       dump_long (dumpfile, format, "Buff2 bits ", buff2);
4133       dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4134       dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4135       dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
4136       }
4137
4138     if ((dumpfile != NULL) && (level == 2))
4139       {
4140       dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
4141       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4142       }
4143     }
4144   
4145   return (0);
4146   } /* end combineSeparateSamples32bits */
4147
4148 static int 
4149 combineSeparateTileSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
4150                                  uint32 cols, uint32 rows, uint32 imagewidth,
4151                                  uint32 tw, uint16 spp, uint16 bps,
4152                                  FILE *dumpfile, int format, int level)
4153   {
4154   int i, bytes_per_sample;
4155   uint32 row, col, col_offset, src_rowsize, dst_rowsize, src_offset;
4156   unsigned char *src;
4157   unsigned char *dst;
4158   tsample_t s;
4159
4160   src = srcbuffs[0];
4161   dst = out;
4162   if ((src == NULL) || (dst == NULL))
4163     {
4164     TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
4165     return (1);
4166     }
4167
4168   bytes_per_sample = (bps + 7) / 8; 
4169   src_rowsize = ((bps * tw) + 7) / 8;
4170   dst_rowsize = imagewidth * bytes_per_sample * spp;
4171   for (row = 0; row < rows; row++)
4172     {
4173     if ((dumpfile != NULL) && (level == 2))
4174       {
4175       for (s = 0; s < spp; s++)
4176         {
4177         dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Input data, Sample %d", s);
4178         dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
4179         }
4180       }
4181     dst = out + (row * dst_rowsize);
4182     src_offset = row * src_rowsize;
4183 #ifdef DEVELMODE
4184     TIFFError("","Tile row %4d, Src offset %6d   Dst offset %6d", 
4185               row, src_offset, dst - out);
4186 #endif
4187     for (col = 0; col < cols; col++)
4188       {
4189       col_offset = src_offset + (col * (bps / 8)); 
4190       for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4191         {
4192         src = srcbuffs[s] + col_offset; 
4193         for (i = 0; i < bytes_per_sample; i++)
4194           *(dst + i) = *(src + i);
4195         dst += bytes_per_sample;
4196         }   
4197       }
4198
4199     if ((dumpfile != NULL) && (level == 2))
4200       {
4201       dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Output data, combined samples");
4202       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4203       }
4204     }
4205
4206   return (0);
4207   } /* end combineSeparateTileSamplesBytes */
4208
4209 static int
4210 combineSeparateTileSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
4211                                  uint32 rows, uint32 imagewidth, 
4212                                  uint32 tw, uint16 spp, uint16 bps, 
4213                                  FILE *dumpfile, int format, int level)
4214   {
4215   int    ready_bits = 0;
4216   uint32 src_rowsize, dst_rowsize, src_offset; 
4217   uint32 bit_offset;
4218   uint32 row, col, src_byte = 0, src_bit = 0;
4219   uint8  maskbits = 0, matchbits = 0;
4220   uint8  buff1 = 0, buff2 = 0;
4221   tsample_t s;
4222   unsigned char *src = in[0];
4223   unsigned char *dst = out;
4224   char           action[32];
4225
4226   if ((src == NULL) || (dst == NULL))
4227     {
4228     TIFFError("combineSeparateTileSamples8bits","Invalid input or output buffer");
4229     return (1);
4230     }
4231
4232   src_rowsize = ((bps * tw) + 7) / 8;
4233   dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4234   maskbits =  (uint8)-1 >> ( 8 - bps);
4235
4236   for (row = 0; row < rows; row++)
4237     {
4238     ready_bits = 0;
4239     buff1 = buff2 = 0;
4240     dst = out + (row * dst_rowsize);
4241     src_offset = row * src_rowsize;
4242     for (col = 0; col < cols; col++)
4243       {
4244       /* Compute src byte(s) and bits within byte(s) */
4245       bit_offset = col * bps;
4246       src_byte = bit_offset / 8;
4247       src_bit  = bit_offset % 8;
4248
4249       matchbits = maskbits << (8 - src_bit - bps); 
4250       /* load up next sample from each plane */
4251       for (s = 0; s < spp; s++)
4252         {
4253         src = in[s] + src_offset + src_byte;
4254         buff1 = ((*src) & matchbits) << (src_bit);
4255
4256         /* If we have a full buffer's worth, write it out */
4257         if (ready_bits >= 8)
4258           {
4259           *dst++ = buff2;
4260           buff2 = buff1;
4261           ready_bits -= 8;
4262           strcpy (action, "Flush");
4263           }
4264         else
4265           {
4266           buff2 = (buff2 | (buff1 >> ready_bits));
4267           strcpy (action, "Update");
4268           }
4269         ready_bits += bps;
4270  
4271         if ((dumpfile != NULL) && (level == 3))
4272           {
4273           dump_info (dumpfile, format, "",
4274                    "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4275                    row + 1, col + 1, s, src_byte, src_bit, dst - out);
4276           dump_byte (dumpfile, format, "Match bits", matchbits);
4277           dump_byte (dumpfile, format, "Src   bits", *src);
4278           dump_byte (dumpfile, format, "Buff1 bits", buff1);
4279           dump_byte (dumpfile, format, "Buff2 bits", buff2);
4280           dump_info (dumpfile, format, "","%s", action); 
4281           }
4282         }
4283       }
4284
4285     if (ready_bits > 0)
4286       {
4287       buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
4288       *dst++ = buff1;
4289       if ((dumpfile != NULL) && (level == 3))
4290         {
4291         dump_info (dumpfile, format, "",
4292                  "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4293                  row + 1, col + 1, src_byte, src_bit, dst - out);
4294                  dump_byte (dumpfile, format, "Final bits", buff1);
4295         }
4296       }
4297
4298     if ((dumpfile != NULL) && (level >= 2))
4299       {
4300       dump_info (dumpfile, format, "combineSeparateTileSamples8bits","Output data");
4301       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4302       }
4303     }
4304
4305   return (0);
4306   } /* end combineSeparateTileSamples8bits */
4307
4308 static int
4309 combineSeparateTileSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
4310                                   uint32 rows, uint32 imagewidth, 
4311                                   uint32 tw, uint16 spp, uint16 bps, 
4312                                   FILE *dumpfile, int format, int level)
4313   {
4314   int    ready_bits = 0;
4315   uint32 src_rowsize, dst_rowsize; 
4316   uint32 bit_offset, src_offset;
4317   uint32 row, col, src_byte = 0, src_bit = 0;
4318   uint16 maskbits = 0, matchbits = 0;
4319   uint16 buff1 = 0, buff2 = 0;
4320   uint8  bytebuff = 0;
4321   tsample_t s;
4322   unsigned char *src = in[0];
4323   unsigned char *dst = out;
4324   char           action[8];
4325
4326   if ((src == NULL) || (dst == NULL))
4327     {
4328     TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
4329     return (1);
4330     }
4331
4332   src_rowsize = ((bps * tw) + 7) / 8;
4333   dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4334   maskbits = (uint16)-1 >> (16 - bps);
4335
4336   for (row = 0; row < rows; row++)
4337     {
4338     ready_bits = 0;
4339     buff1 = buff2 = 0;
4340     dst = out + (row * dst_rowsize);
4341     src_offset = row * src_rowsize;
4342     for (col = 0; col < cols; col++)
4343       {
4344       /* Compute src byte(s) and bits within byte(s) */
4345       bit_offset = col * bps;
4346       src_byte = bit_offset / 8;
4347       src_bit  = bit_offset % 8;
4348
4349       matchbits = maskbits << (16 - src_bit - bps); 
4350       for (s = 0; s < spp; s++)
4351         {
4352         src = in[s] + src_offset + src_byte;
4353         if (little_endian)
4354           buff1 = (src[0] << 8) | src[1];
4355         else
4356           buff1 = (src[1] << 8) | src[0];
4357         buff1 = (buff1 & matchbits) << (src_bit);
4358
4359         /* If we have a full buffer's worth, write it out */
4360         if (ready_bits >= 8)
4361           {
4362             bytebuff = (buff2 >> 8);
4363             *dst++ = bytebuff;
4364             ready_bits -= 8;
4365             /* shift in new bits */
4366             buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
4367             strcpy (action, "Flush");
4368           }
4369         else
4370           { /* add another bps bits to the buffer */
4371             bytebuff = 0;
4372             buff2 = (buff2 | (buff1 >> ready_bits));
4373             strcpy (action, "Update");
4374           }
4375         ready_bits += bps;
4376
4377         if ((dumpfile != NULL) && (level == 3))
4378           {
4379           dump_info (dumpfile, format, "",
4380                        "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4381                        row + 1, col + 1, s, src_byte, src_bit, dst - out);
4382
4383           dump_short (dumpfile, format, "Match bits", matchbits);
4384           dump_data  (dumpfile, format, "Src   bits", src, 2);
4385           dump_short (dumpfile, format, "Buff1 bits", buff1);
4386           dump_short (dumpfile, format, "Buff2 bits", buff2);
4387           dump_byte  (dumpfile, format, "Write byte", bytebuff);
4388           dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
4389           }
4390         }
4391       }
4392
4393     /* catch any trailing bits at the end of the line */
4394     if (ready_bits > 0)
4395       {
4396       bytebuff = (buff2 >> 8);
4397       *dst++ = bytebuff;
4398       if ((dumpfile != NULL) && (level == 3))
4399         {
4400         dump_info (dumpfile, format, "",
4401                        "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4402                        row + 1, col + 1, src_byte, src_bit, dst - out);
4403         dump_byte (dumpfile, format, "Final bits", bytebuff);
4404         }
4405       }
4406
4407     if ((dumpfile != NULL) && (level == 2))
4408       {
4409       dump_info (dumpfile, format, "combineSeparateTileSamples16bits","Output data");
4410       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4411       }
4412     }
4413
4414   return (0);
4415   } /* end combineSeparateTileSamples16bits */
4416
4417 static int
4418 combineSeparateTileSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
4419                                   uint32 rows, uint32 imagewidth, 
4420                                   uint32 tw, uint16 spp, uint16 bps, 
4421                                   FILE *dumpfile, int format, int level)
4422   {
4423   int    ready_bits = 0;
4424   uint32 src_rowsize, dst_rowsize; 
4425   uint32 bit_offset, src_offset;
4426   uint32 row, col, src_byte = 0, src_bit = 0;
4427   uint32 maskbits = 0, matchbits = 0;
4428   uint32 buff1 = 0, buff2 = 0;
4429   uint8  bytebuff1 = 0, bytebuff2 = 0;
4430   tsample_t s;
4431   unsigned char *src = in[0];
4432   unsigned char *dst = out;
4433   char           action[8];
4434
4435   if ((src == NULL) || (dst == NULL))
4436     {
4437     TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
4438     return (1);
4439     }
4440
4441   src_rowsize = ((bps * tw) + 7) / 8;
4442   dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4443   maskbits =  (uint32)-1 >> ( 32 - bps);
4444
4445   for (row = 0; row < rows; row++)
4446     {
4447     ready_bits = 0;
4448     buff1 = buff2 = 0;
4449     dst = out + (row * dst_rowsize);
4450     src_offset = row * src_rowsize;
4451     for (col = 0; col < cols; col++)
4452       {
4453       /* Compute src byte(s) and bits within byte(s) */
4454       bit_offset = col * bps;
4455       src_byte = bit_offset / 8;
4456       src_bit  = bit_offset % 8;
4457
4458       matchbits = maskbits << (32 - src_bit - bps); 
4459       for (s = 0; s < spp; s++)
4460         {
4461         src = in[s] + src_offset + src_byte;
4462         if (little_endian)
4463           buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4464         else
4465           buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4466         buff1 = (buff1 & matchbits) << (src_bit);
4467
4468         /* If we have a full buffer's worth, write it out */
4469         if (ready_bits >= 16)
4470           {
4471             bytebuff1 = (buff2 >> 24);
4472             *dst++ = bytebuff1;
4473             bytebuff2 = (buff2 >> 16);
4474             *dst++ = bytebuff2;
4475             ready_bits -= 16;
4476
4477             /* shift in new bits */
4478             buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
4479             strcpy (action, "Flush");
4480           }
4481         else
4482           { /* add another bps bits to the buffer */
4483             bytebuff1 = bytebuff2 = 0;
4484             buff2 = (buff2 | (buff1 >> ready_bits));
4485             strcpy (action, "Update");
4486           }
4487         ready_bits += bps;
4488
4489         if ((dumpfile != NULL) && (level == 3))
4490           {
4491           dump_info (dumpfile, format, "",
4492                        "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4493                        row + 1, col + 1, s, src_byte, src_bit, dst - out);
4494           dump_long (dumpfile, format, "Match bits ", matchbits);
4495           dump_data (dumpfile, format, "Src   bits ", src, 4);
4496           dump_long (dumpfile, format, "Buff1 bits ", buff1);
4497           dump_long (dumpfile, format, "Buff2 bits ", buff2);
4498           dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4499           dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4500           dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
4501           }
4502         }
4503       }
4504
4505     /* catch any trailing bits at the end of the line */
4506     while (ready_bits > 0)
4507       {
4508         bytebuff1 = (buff2 >> 24);
4509         *dst++ = bytebuff1;
4510
4511         buff2 = (buff2 << 8);
4512         bytebuff2 = bytebuff1;
4513         ready_bits -= 8;
4514       }
4515  
4516     if ((dumpfile != NULL) && (level == 3))
4517       {
4518       dump_info (dumpfile, format, "",
4519                    "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4520                    row + 1, col + 1, src_byte, src_bit, dst - out);
4521
4522       dump_long (dumpfile, format, "Match bits ", matchbits);
4523       dump_data (dumpfile, format, "Src   bits ", src, 4);
4524       dump_long (dumpfile, format, "Buff1 bits ", buff1);
4525       dump_long (dumpfile, format, "Buff2 bits ", buff2);
4526       dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4527       dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4528       dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
4529       }
4530
4531     if ((dumpfile != NULL) && (level == 2))
4532       {
4533       dump_info (dumpfile, format, "combineSeparateTileSamples24bits","Output data");
4534       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4535       }
4536     }
4537   
4538   return (0);
4539   } /* end combineSeparateTileSamples24bits */
4540
4541 static int
4542 combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4543                                   uint32 rows, uint32 imagewidth, 
4544                                   uint32 tw, uint16 spp, uint16 bps, 
4545                                   FILE *dumpfile, int format, int level)
4546   {
4547   int    ready_bits = 0, shift_width = 0;
4548   uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4549   uint32 src_byte = 0, src_bit = 0;
4550   uint32 row, col;
4551   uint32 longbuff1 = 0, longbuff2 = 0;
4552   uint64 maskbits = 0, matchbits = 0;
4553   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4554   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4555   tsample_t s;
4556   unsigned char *src = in[0];
4557   unsigned char *dst = out;
4558   char           action[8];
4559
4560   if ((src == NULL) || (dst == NULL))
4561     {
4562     TIFFError("combineSeparateTileSamples32bits","Invalid input or output buffer");
4563     return (1);
4564     }
4565
4566   src_rowsize = ((bps * tw) + 7) / 8;
4567   dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4568   maskbits =  (uint64)-1 >> ( 64 - bps);
4569   shift_width = ((bps + 7) / 8) + 1; 
4570
4571   for (row = 0; row < rows; row++)
4572     {
4573     ready_bits = 0;
4574     buff1 = buff2 = 0;
4575     dst = out + (row * dst_rowsize);
4576     src_offset = row * src_rowsize;
4577     for (col = 0; col < cols; col++)
4578       {
4579       /* Compute src byte(s) and bits within byte(s) */
4580       bit_offset = col * bps;
4581       src_byte = bit_offset / 8;
4582       src_bit  = bit_offset % 8;
4583
4584       matchbits = maskbits << (64 - src_bit - bps); 
4585       for (s = 0; s < spp; s++)
4586         {
4587         src = in[s] + src_offset + src_byte;
4588         if (little_endian)
4589           {
4590           longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4591           longbuff2 = longbuff1;
4592           }
4593         else
4594           {
4595           longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4596           longbuff2 = longbuff1;
4597           }
4598
4599         buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4600         buff1 = (buff3 & matchbits) << (src_bit);
4601
4602         /* If we have a full buffer's worth, write it out */
4603         if (ready_bits >= 32)
4604           {
4605           bytebuff1 = (buff2 >> 56);
4606           *dst++ = bytebuff1;
4607           bytebuff2 = (buff2 >> 48);
4608           *dst++ = bytebuff2;
4609           bytebuff3 = (buff2 >> 40);
4610           *dst++ = bytebuff3;
4611           bytebuff4 = (buff2 >> 32);
4612           *dst++ = bytebuff4;
4613           ready_bits -= 32;
4614                     
4615           /* shift in new bits */
4616           buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4617           strcpy (action, "Flush");
4618           }
4619         else
4620           { /* add another bps bits to the buffer */
4621           bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4622           buff2 = (buff2 | (buff1 >> ready_bits));
4623           strcpy (action, "Update");
4624           }
4625         ready_bits += bps;
4626
4627         if ((dumpfile != NULL) && (level == 3))
4628           { 
4629           dump_info (dumpfile, format, "",
4630                      "Row %3d, Col %3d, Sample %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4631                      row + 1, col + 1, s, src_byte, src_bit, dst - out);
4632           dump_wide (dumpfile, format, "Match bits ", matchbits);
4633           dump_data (dumpfile, format, "Src   bits ", src, 8);
4634           dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4635           dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4636           dump_info (dumpfile, format, "", "Ready bits:   %d, %s", ready_bits, action); 
4637           }
4638         }
4639       }
4640     while (ready_bits > 0)
4641       {
4642       bytebuff1 = (buff2 >> 56);
4643       *dst++ = bytebuff1;
4644       buff2 = (buff2 << 8);
4645       ready_bits -= 8;
4646       }
4647
4648     if ((dumpfile != NULL) && (level == 3))
4649       {
4650       dump_info (dumpfile, format, "",
4651                  "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
4652                  row + 1, col + 1, src_byte, src_bit, dst - out);
4653
4654       dump_long (dumpfile, format, "Match bits ", matchbits);
4655       dump_data (dumpfile, format, "Src   bits ", src, 4);
4656       dump_long (dumpfile, format, "Buff1 bits ", buff1);
4657       dump_long (dumpfile, format, "Buff2 bits ", buff2);
4658       dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4659       dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4660       dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
4661       }
4662
4663     if ((dumpfile != NULL) && (level == 2))
4664       {
4665       dump_info (dumpfile, format, "combineSeparateTileSamples32bits","Output data");
4666       dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4667       }
4668     }
4669   
4670   return (0);
4671   } /* end combineSeparateTileSamples32bits */
4672
4673
4674 static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, 
4675                                          uint32 width, uint16 spp,
4676                                          struct dump_opts *dump)
4677   {
4678   int i, j, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
4679   int32  bytes_read = 0;
4680   uint16 bps, nstrips, planar, strips_per_sample;
4681   uint32 src_rowsize, dst_rowsize, rows_processed, rps;
4682   uint32 rows_this_strip = 0;
4683   tsample_t s;
4684   tstrip_t  strip;
4685   tsize_t scanlinesize = TIFFScanlineSize(in);
4686   tsize_t stripsize    = TIFFStripSize(in);
4687   unsigned char *srcbuffs[MAX_SAMPLES];
4688   unsigned char *buff = NULL;
4689   unsigned char *dst = NULL;
4690
4691   if (obuf == NULL)
4692     {
4693     TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
4694     return (0);
4695     }
4696
4697   memset (srcbuffs, '\0', sizeof(srcbuffs));
4698   TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
4699   TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
4700   TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
4701   if (rps > length)
4702     rps = length;
4703
4704   bytes_per_sample = (bps + 7) / 8; 
4705   bytes_per_pixel  = ((bps * spp) + 7) / 8;
4706   if (bytes_per_pixel < (bytes_per_sample + 1))
4707     shift_width = bytes_per_pixel;
4708   else
4709     shift_width = bytes_per_sample + 1;
4710
4711   src_rowsize = ((bps * width) + 7) / 8;
4712   dst_rowsize = ((bps * width * spp) + 7) / 8;
4713   dst = obuf;
4714
4715   if ((dump->infile != NULL) && (dump->level == 3))
4716     {
4717     dump_info  (dump->infile, dump->format, "", 
4718                 "Image width %d, length %d, Scanline size, %4d bytes",
4719                 width, length,  scanlinesize);
4720     dump_info  (dump->infile, dump->format, "", 
4721                 "Bits per sample %d, Samples per pixel %d, Shift width %d",
4722                 bps, spp, shift_width);
4723     }
4724
4725   /* Libtiff seems to assume/require that data for separate planes are 
4726    * written one complete plane after another and not interleaved in any way.
4727    * Multiple scanlines and possibly strips of the same plane must be 
4728    * written before data for any other plane.
4729    */
4730   nstrips = TIFFNumberOfStrips(in);
4731   strips_per_sample = nstrips /spp;
4732
4733   for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4734     {
4735     srcbuffs[s] = NULL;
4736     buff = _TIFFmalloc(stripsize);
4737     if (!buff)
4738       {
4739       TIFFError ("readSeparateStripsIntoBuffer", 
4740                  "Unable to allocate strip read buffer for sample %d", s);
4741       for (i = 0; i < s; i++)
4742         _TIFFfree (srcbuffs[i]);
4743       return 0;
4744       }
4745     srcbuffs[s] = buff;
4746     }
4747
4748   rows_processed = 0;
4749   for (j = 0; (j < strips_per_sample) && (result == 1); j++)
4750     {
4751     for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4752       {
4753       buff = srcbuffs[s];
4754       strip = (s * strips_per_sample) + j; 
4755       bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
4756       rows_this_strip = bytes_read / src_rowsize;
4757       if (bytes_read < 0 && !ignore)
4758         {
4759         TIFFError(TIFFFileName(in),
4760                   "Error, can't read strip %lu for sample %d",
4761                    (unsigned long) strip, s + 1);
4762         result = 0;
4763         break;
4764         }
4765 #ifdef DEVELMODE
4766       TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d", 
4767                 strip, bytes_read, rows_this_strip, shift_width);
4768 #endif
4769       }
4770
4771     if (rps > rows_this_strip)
4772       rps = rows_this_strip;
4773     dst = obuf + (dst_rowsize * rows_processed);
4774     if ((bps % 8) == 0)
4775       {
4776       if (combineSeparateSamplesBytes (srcbuffs, dst, width, rps,
4777                                        spp, bps, dump->infile, 
4778                                        dump->format, dump->level))
4779         {
4780         result = 0;
4781         break;
4782         }
4783       }
4784     else
4785       {
4786       switch (shift_width)
4787         {
4788         case 1: if (combineSeparateSamples8bits (srcbuffs, dst, width, rps,
4789                                                  spp, bps, dump->infile,
4790                                                  dump->format, dump->level))
4791                   {
4792                   result = 0;
4793                   break;
4794                   }
4795                 break;
4796         case 2: if (combineSeparateSamples16bits (srcbuffs, dst, width, rps,
4797                                                   spp, bps, dump->infile,
4798                                                   dump->format, dump->level))
4799                   {
4800                   result = 0;
4801                   break;
4802                   }
4803                 break;
4804         case 3: if (combineSeparateSamples24bits (srcbuffs, dst, width, rps,
4805                                                   spp, bps, dump->infile,
4806                                                   dump->format, dump->level))
4807                   {
4808                   result = 0;
4809                   break;
4810                   }
4811                 break;
4812         case 4: 
4813         case 5:
4814         case 6:
4815         case 7:
4816         case 8: if (combineSeparateSamples32bits (srcbuffs, dst, width, rps,
4817                                                   spp, bps, dump->infile,
4818                                                   dump->format, dump->level))
4819                   {
4820                   result = 0;
4821                   break;
4822                   }
4823                 break;
4824         default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
4825                   result = 0;
4826                   break;
4827         }
4828       }
4829  
4830     if ((rows_processed + rps) > length)
4831       {
4832       rows_processed = length;
4833       rps = length - rows_processed;
4834       }
4835     else
4836       rows_processed += rps;
4837     }
4838
4839   /* free any buffers allocated for each plane or scanline and 
4840    * any temporary buffers 
4841    */
4842   for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4843     {
4844     buff = srcbuffs[s];
4845     if (buff != NULL)
4846       _TIFFfree(buff);
4847     }
4848
4849   return (result);
4850   } /* end readSeparateStripsIntoBuffer */
4851
4852 static int
4853 get_page_geometry (char *name, struct pagedef *page)
4854     {
4855     char *ptr;
4856     int n; 
4857
4858     for (ptr = name; *ptr; ptr++)
4859       *ptr = (char)tolower((int)*ptr);
4860
4861     for (n = 0; n < MAX_PAPERNAMES; n++)
4862       {
4863       if (strcmp(name, PaperTable[n].name) == 0)
4864         {
4865         page->width = PaperTable[n].width;
4866         page->length = PaperTable[n].length;
4867         strncpy (page->name, PaperTable[n].name, 15);
4868         page->name[15] = '\0';
4869         return (0);
4870         }
4871       }
4872
4873   return (1);
4874   }
4875
4876
4877 static void
4878 initPageSetup (struct pagedef *page, struct pageseg *pagelist, 
4879                struct buffinfo seg_buffs[])
4880    {
4881    int i; 
4882
4883    strcpy (page->name, "");
4884    page->mode = PAGE_MODE_NONE;
4885    page->res_unit = RESUNIT_NONE;
4886    page->hres = 0.0;
4887    page->vres = 0.0;
4888    page->width = 0.0;
4889    page->length = 0.0;
4890    page->hmargin = 0.0;
4891    page->vmargin = 0.0;
4892    page->rows = 0;
4893    page->cols = 0;
4894    page->orient = ORIENTATION_NONE;
4895
4896    for (i = 0; i < MAX_SECTIONS; i++)
4897      {
4898      pagelist[i].x1 = (uint32)0;
4899      pagelist[i].x2 = (uint32)0;
4900      pagelist[i].y1 = (uint32)0;
4901      pagelist[i].y2 = (uint32)0;
4902      pagelist[i].buffsize = (uint32)0;
4903      pagelist[i].position = 0;
4904      pagelist[i].total = 0;
4905      }
4906
4907    for (i = 0; i < MAX_OUTBUFFS; i++)
4908      {
4909      seg_buffs[i].size = 0;
4910      seg_buffs[i].buffer = NULL;
4911      }
4912    }
4913
4914 static void
4915 initImageData (struct image_data *image)
4916   {
4917   image->xres = 0.0;
4918   image->yres = 0.0;
4919   image->width = 0;
4920   image->length = 0;
4921   image->res_unit = RESUNIT_NONE;
4922   image->bps = 0;
4923   image->spp = 0;
4924   image->planar = 0;
4925   image->photometric = 0;
4926   image->orientation = 0;
4927   image->compression = COMPRESSION_NONE;
4928   image->adjustments = 0;
4929   }
4930
4931 static void
4932 initCropMasks (struct crop_mask *cps)
4933    {
4934    int i;
4935
4936    cps->crop_mode = CROP_NONE;
4937    cps->res_unit  = RESUNIT_NONE;
4938    cps->edge_ref  = EDGE_TOP;
4939    cps->width = 0;
4940    cps->length = 0;
4941    for (i = 0; i < 4; i++)
4942      cps->margins[i] = 0.0;
4943    cps->bufftotal = (uint32)0;
4944    cps->combined_width = (uint32)0;
4945    cps->combined_length = (uint32)0;
4946    cps->rotation = (uint16)0;
4947    cps->photometric = INVERT_DATA_AND_TAG;
4948    cps->mirror   = (uint16)0;
4949    cps->invert   = (uint16)0;
4950    cps->zones    = (uint32)0;
4951    cps->regions  = (uint32)0;
4952    for (i = 0; i < MAX_REGIONS; i++)
4953      {
4954      cps->corners[i].X1 = 0.0;
4955      cps->corners[i].X2 = 0.0;
4956      cps->corners[i].Y1 = 0.0;
4957      cps->corners[i].Y2 = 0.0;
4958      cps->regionlist[i].x1 = 0;
4959      cps->regionlist[i].x2 = 0;
4960      cps->regionlist[i].y1 = 0;
4961      cps->regionlist[i].y2 = 0;
4962      cps->regionlist[i].width = 0;
4963      cps->regionlist[i].length = 0;
4964      cps->regionlist[i].buffsize = 0;
4965      cps->regionlist[i].buffptr = NULL;
4966      cps->zonelist[i].position = 0;
4967      cps->zonelist[i].total = 0;
4968      }
4969    cps->exp_mode = ONE_FILE_COMPOSITE;
4970    cps->img_mode = COMPOSITE_IMAGES;
4971    }
4972
4973 static void initDumpOptions(struct dump_opts *dump)
4974   {
4975   dump->debug  = 0;
4976   dump->format = DUMP_NONE;
4977   dump->level  = 1;
4978   sprintf (dump->mode, "w");
4979   memset (dump->infilename, '\0', PATH_MAX + 1);
4980   memset (dump->outfilename, '\0',PATH_MAX + 1);
4981   dump->infile = NULL;
4982   dump->outfile = NULL;
4983   }
4984
4985 /* Compute pixel offsets into the image for margins and fixed regions */
4986 static int
4987 computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
4988                          struct offset *off)
4989   {
4990   double scale;
4991   float xres, yres;
4992   /* Values for these offsets are in pixels from start of image, not bytes,
4993    * and are indexed from zero to width - 1 or length - 1 */
4994   uint32 tmargin, bmargin, lmargin, rmargin;
4995   uint32 startx, endx;   /* offsets of first and last columns to extract */
4996   uint32 starty, endy;   /* offsets of first and last row to extract */
4997   uint32 width, length, crop_width, crop_length; 
4998   uint32 i, max_width, max_length, zwidth, zlength, buffsize;
4999   uint32 x1, x2, y1, y2;
5000
5001   if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
5002     {
5003     xres = 1.0;
5004     yres = 1.0;
5005     }
5006   else
5007     {
5008     if (((image->xres == 0) || (image->yres == 0)) && 
5009          (crop->res_unit != RESUNIT_NONE) &&
5010         ((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
5011          (crop->crop_mode & CROP_LENGTH)  || (crop->crop_mode & CROP_WIDTH)))
5012       {
5013       TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
5014       TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
5015       return (-1);
5016       }
5017     xres = image->xres;
5018     yres = image->yres;
5019     }
5020
5021   /* Translate user units to image units */
5022   scale = 1.0;
5023   switch (crop->res_unit) {
5024     case RESUNIT_CENTIMETER:
5025          if (image->res_unit == RESUNIT_INCH)
5026            scale = 1.0/2.54;
5027          break;
5028     case RESUNIT_INCH:
5029          if (image->res_unit == RESUNIT_CENTIMETER)
5030              scale = 2.54;
5031          break;
5032     case RESUNIT_NONE: /* Dimensions in pixels */
5033     default:
5034     break;
5035     }
5036
5037   if (crop->crop_mode & CROP_REGIONS)
5038     {
5039     max_width = max_length = 0;
5040     for (i = 0; i < crop->regions; i++)
5041       {
5042       if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
5043         {
5044         x1 = (uint32) (crop->corners[i].X1 * scale * xres);
5045         x2 = (uint32) (crop->corners[i].X2 * scale * xres);
5046         y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
5047         y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
5048         }
5049       else
5050         {
5051         x1 = (uint32) (crop->corners[i].X1);
5052         x2 = (uint32) (crop->corners[i].X2);
5053         y1 = (uint32) (crop->corners[i].Y1);
5054         y2 = (uint32) (crop->corners[i].Y2);       
5055         }
5056       if (x1 < 1)
5057         crop->regionlist[i].x1 = 0;
5058       else
5059         crop->regionlist[i].x1 = (uint32) (x1 - 1);
5060
5061       if (x2 > image->width - 1)
5062         crop->regionlist[i].x2 = image->width - 1;
5063       else
5064         crop->regionlist[i].x2 = (uint32) (x2 - 1);
5065       zwidth  = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 
5066
5067       if (y1 < 1)
5068         crop->regionlist[i].y1 = 0;
5069       else
5070         crop->regionlist[i].y1 = (uint32) (y1 - 1);
5071
5072       if (y2 > image->length - 1)
5073         crop->regionlist[i].y2 = image->length - 1;
5074       else
5075         crop->regionlist[i].y2 = (uint32) (y2 - 1);
5076
5077       zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 
5078
5079       if (zwidth > max_width)
5080         max_width = zwidth;
5081       if (zlength > max_length)
5082         max_length = zlength;
5083
5084       buffsize = (uint32)
5085           (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
5086
5087       crop->regionlist[i].buffsize = buffsize;
5088       crop->bufftotal += buffsize;
5089       if (crop->img_mode == COMPOSITE_IMAGES)
5090         {
5091         switch (crop->edge_ref)
5092           {
5093           case EDGE_LEFT:
5094           case EDGE_RIGHT:
5095                crop->combined_length = zlength;
5096                crop->combined_width += zwidth;
5097                break;
5098           case EDGE_BOTTOM:
5099           case EDGE_TOP:  /* width from left, length from top */
5100           default:
5101                crop->combined_width = zwidth;
5102                crop->combined_length += zlength;
5103                break;
5104           }
5105         }
5106       }
5107     return (0);
5108     }
5109   
5110   /* Convert crop margins into offsets into image
5111    * Margins are expressed as pixel rows and columns, not bytes
5112    */
5113   if (crop->crop_mode & CROP_MARGINS)
5114     {
5115     if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5116       { /* User has specified pixels as reference unit */
5117       tmargin = (uint32)(crop->margins[0]);
5118       lmargin = (uint32)(crop->margins[1]);
5119       bmargin = (uint32)(crop->margins[2]);
5120       rmargin = (uint32)(crop->margins[3]);
5121       }
5122     else
5123       { /* inches or centimeters specified */
5124       tmargin = (uint32)(crop->margins[0] * scale * yres);
5125       lmargin = (uint32)(crop->margins[1] * scale * xres);
5126       bmargin = (uint32)(crop->margins[2] * scale * yres);
5127       rmargin = (uint32)(crop->margins[3] * scale * xres);
5128       }
5129
5130     if ((lmargin + rmargin) > image->width)
5131       {
5132       TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
5133       lmargin = (uint32) 0;
5134       rmargin = (uint32) 0;
5135       return (-1);
5136       }
5137     if ((tmargin + bmargin) > image->length)
5138       {
5139       TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length"); 
5140       tmargin = (uint32) 0; 
5141       bmargin = (uint32) 0;
5142       return (-1);
5143       }
5144     }
5145   else
5146     { /* no margins requested */
5147     tmargin = (uint32) 0;
5148     lmargin = (uint32) 0;
5149     bmargin = (uint32) 0;
5150     rmargin = (uint32) 0;
5151     }
5152
5153   /* Width, height, and margins are expressed as pixel offsets into image */
5154   if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5155     {
5156     if (crop->crop_mode & CROP_WIDTH)
5157       width = (uint32)crop->width;
5158     else
5159       width = image->width - lmargin - rmargin;
5160
5161     if (crop->crop_mode & CROP_LENGTH)
5162       length  = (uint32)crop->length;
5163     else
5164       length = image->length - tmargin - bmargin;
5165     }
5166   else
5167     {
5168     if (crop->crop_mode & CROP_WIDTH)
5169       width = (uint32)(crop->width * scale * image->xres);
5170     else
5171       width = image->width - lmargin - rmargin;
5172
5173     if (crop->crop_mode & CROP_LENGTH)
5174       length  = (uint32)(crop->length * scale * image->yres);
5175     else
5176       length = image->length - tmargin - bmargin;
5177     }
5178
5179   off->tmargin = tmargin;
5180   off->bmargin = bmargin;
5181   off->lmargin = lmargin;
5182   off->rmargin = rmargin;
5183
5184   /* Calculate regions defined by margins, width, and length. 
5185    * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
5186    * since they are used to compute offsets into buffers */
5187   switch (crop->edge_ref) {
5188     case EDGE_BOTTOM:
5189          startx = lmargin;
5190          if ((startx + width) >= (image->width - rmargin))
5191            endx = image->width - rmargin - 1;
5192          else
5193            endx = startx + width - 1;
5194
5195          endy = image->length - bmargin - 1;
5196          if ((endy - length) <= tmargin)
5197            starty = tmargin;
5198          else
5199            starty = endy - length + 1;
5200          break;
5201     case EDGE_RIGHT:
5202          endx = image->width - rmargin - 1;
5203          if ((endx - width) <= lmargin)
5204            startx = lmargin;
5205          else
5206            startx = endx - width + 1;
5207
5208          starty = tmargin;
5209          if ((starty + length) >= (image->length - bmargin))
5210            endy = image->length - bmargin - 1;
5211          else
5212            endy = starty + length - 1;
5213          break;
5214     case EDGE_TOP:  /* width from left, length from top */
5215     case EDGE_LEFT:
5216     default:
5217          startx = lmargin;
5218          if ((startx + width) >= (image->width - rmargin))
5219            endx = image->width - rmargin - 1;
5220          else
5221            endx = startx + width - 1;
5222
5223          starty = tmargin;
5224          if ((starty + length) >= (image->length - bmargin))
5225            endy = image->length - bmargin - 1;
5226          else
5227            endy = starty + length - 1;
5228          break;
5229     }
5230   off->startx = startx;
5231   off->starty = starty;
5232   off->endx   = endx;
5233   off->endy   = endy;
5234
5235   crop_width  = endx - startx + 1;
5236   crop_length = endy - starty + 1;
5237
5238   if (crop_width <= 0)
5239     {
5240     TIFFError("computeInputPixelOffsets", 
5241                "Invalid left/right margins and /or image crop width requested");
5242     return (-1);
5243     }
5244   if (crop_width > image->width)
5245     crop_width = image->width;
5246
5247   if (crop_length <= 0)
5248     {
5249     TIFFError("computeInputPixelOffsets", 
5250               "Invalid top/bottom margins and /or image crop length requested");
5251     return (-1);
5252     }
5253   if (crop_length > image->length)
5254     crop_length = image->length;
5255
5256   off->crop_width = crop_width;
5257   off->crop_length = crop_length;
5258
5259   return (0);
5260   } /* end computeInputPixelOffsets */
5261
5262 /* 
5263  * Translate crop options into pixel offsets for one or more regions of the image.
5264  * Options are applied in this order: margins, specific width and length, zones,
5265  * but all are optional. Margins are relative to each edge. Width, length and
5266  * zones are relative to the specified reference edge. Zones are expressed as
5267  * X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
5268  * 2:3 would indicate the middle third of the region qualified by margins and
5269  * any explicit width and length specified. Regions are specified by coordinates
5270  * of the top left and lower right corners with range 1 to width or height.
5271  */
5272
5273 static int
5274 getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
5275   {
5276   struct offset offsets;
5277   int    i;
5278   int32  test;
5279   uint32 seg, total, need_buff = 0;
5280   uint32 buffsize;
5281   uint32 zwidth, zlength;
5282
5283   memset(&offsets, '\0', sizeof(struct offset));
5284   crop->bufftotal = 0;
5285   crop->combined_width  = (uint32)0;
5286   crop->combined_length = (uint32)0;
5287   crop->selections = 0;
5288
5289   /* Compute pixel offsets if margins or fixed width or length specified */
5290   if ((crop->crop_mode & CROP_MARGINS) ||
5291       (crop->crop_mode & CROP_REGIONS) ||
5292       (crop->crop_mode & CROP_LENGTH)  || 
5293       (crop->crop_mode & CROP_WIDTH))
5294     {
5295     if (computeInputPixelOffsets(crop, image, &offsets))
5296       {
5297       TIFFError ("getCropOffsets", "Unable to compute crop margins");
5298       return (-1);
5299       }
5300     need_buff = TRUE;
5301     crop->selections = crop->regions;
5302     /* Regions are only calculated from top and left edges with no margins */
5303     if (crop->crop_mode & CROP_REGIONS)
5304       return (0);
5305     }
5306   else
5307     { /* cropped area is the full image */
5308     offsets.tmargin = 0;
5309     offsets.lmargin = 0;
5310     offsets.bmargin = 0;
5311     offsets.rmargin = 0;
5312     offsets.crop_width = image->width;
5313     offsets.crop_length = image->length;
5314     offsets.startx = 0;
5315     offsets.endx = image->width - 1;
5316     offsets.starty = 0;
5317     offsets.endy = image->length - 1;
5318     need_buff = FALSE;
5319     }
5320
5321   if (dump->outfile != NULL)
5322     {
5323     dump_info (dump->outfile, dump->format, "", "Margins: Top: %d  Left: %d  Bottom: %d  Right: %d", 
5324            offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin); 
5325     dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width:  %6d  Length: %6d", 
5326            offsets.crop_width, offsets.crop_length);
5327     }
5328
5329   if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
5330     {
5331     if (need_buff == FALSE)  /* No margins or fixed width or length areas */
5332       {
5333       crop->selections = 0;
5334       crop->combined_width  = image->width;
5335       crop->combined_length = image->length;
5336       return (0);
5337       }
5338     else 
5339       {
5340       /* Use one region for margins and fixed width or length areas
5341        * even though it was not formally declared as a region.
5342        */
5343       crop->selections = 1;
5344       crop->zones = 1;
5345       crop->zonelist[0].total = 1;
5346       crop->zonelist[0].position = 1;
5347       }
5348     }     
5349   else
5350     crop->selections = crop->zones;
5351
5352   for (i = 0; i < crop->zones; i++)
5353     {
5354     seg = crop->zonelist[i].position;
5355     total = crop->zonelist[i].total;
5356
5357     switch (crop->edge_ref) 
5358       {
5359       case EDGE_LEFT: /* zones from left to right, length from top */
5360            zlength = offsets.crop_length;
5361            crop->regionlist[i].y1 = offsets.starty;
5362            crop->regionlist[i].y2 = offsets.endy;
5363
5364            crop->regionlist[i].x1 = offsets.startx + 
5365                                   (uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
5366            test = (int32)offsets.startx + 
5367                   (int32)(offsets.crop_width * 1.0 * seg / total);
5368            if (test < 1 )
5369              crop->regionlist[i].x2 = 0;
5370            else
5371              {
5372              if (test > (int32)(image->width - 1))
5373                crop->regionlist[i].x2 = image->width - 1;
5374              else
5375                crop->regionlist[i].x2 = test - 1;
5376              }
5377            zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
5378
5379            /* This is passed to extractCropZone or extractCompositeZones */
5380            crop->combined_length = (uint32)zlength;
5381            if (crop->exp_mode == COMPOSITE_IMAGES)
5382              crop->combined_width += (uint32)zwidth;
5383            else
5384              crop->combined_width = (uint32)zwidth;
5385            break;
5386       case EDGE_BOTTOM: /* width from left, zones from bottom to top */
5387            zwidth = offsets.crop_width;
5388            crop->regionlist[i].x1 = offsets.startx;
5389            crop->regionlist[i].x2 = offsets.endx;
5390
5391            test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
5392            if (test < 1 )
5393              crop->regionlist[i].y1 = 0;
5394            else
5395              crop->regionlist[i].y1 = test + 1;
5396
5397            test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total);
5398            if (test < 1 )
5399              crop->regionlist[i].y2 = 0;
5400            else
5401              {
5402              if (test > (int32)(image->length - 1))
5403                crop->regionlist[i].y2 = image->length - 1;
5404              else 
5405                crop->regionlist[i].y2 = test;
5406              }
5407            zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5408
5409            /* This is passed to extractCropZone or extractCompositeZones */
5410            if (crop->exp_mode == COMPOSITE_IMAGES)
5411              crop->combined_length += (uint32)zlength;
5412            else
5413              crop->combined_length = (uint32)zlength;
5414            crop->combined_width = (uint32)zwidth;
5415            break;
5416       case EDGE_RIGHT: /* zones from right to left, length from top */
5417            zlength = offsets.crop_length;
5418            crop->regionlist[i].y1 = offsets.starty;
5419            crop->regionlist[i].y2 = offsets.endy;
5420
5421            crop->regionlist[i].x1 = offsets.startx +
5422                                   (uint32)(offsets.crop_width  * (total - seg) * 1.0 / total);
5423            test = offsets.startx + 
5424                   (offsets.crop_width * (total - seg + 1) * 1.0 / total);
5425            if (test < 1 )
5426              crop->regionlist[i].x2 = 0;
5427            else
5428              {
5429              if (test > (int32)(image->width - 1))
5430                crop->regionlist[i].x2 = image->width - 1;
5431              else
5432                crop->regionlist[i].x2 = test - 1;
5433              }
5434            zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
5435
5436            /* This is passed to extractCropZone or extractCompositeZones */
5437            crop->combined_length = (uint32)zlength;
5438            if (crop->exp_mode == COMPOSITE_IMAGES)
5439              crop->combined_width += (uint32)zwidth;
5440            else
5441              crop->combined_width = (uint32)zwidth;
5442            break;
5443       case EDGE_TOP: /* width from left, zones from top to bottom */
5444       default:
5445            zwidth = offsets.crop_width;
5446            crop->regionlist[i].x1 = offsets.startx;
5447            crop->regionlist[i].x2 = offsets.endx;
5448
5449            crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
5450            test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
5451            if (test < 1 )
5452              crop->regionlist[i].y2 = 0;
5453            else
5454              {
5455              if (test > (int32)(image->length - 1))
5456                crop->regionlist[i].y2 = image->length - 1;
5457              else
5458                crop->regionlist[i].y2 = test - 1;
5459              }
5460            zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5461
5462            /* This is passed to extractCropZone or extractCompositeZones */
5463            if (crop->exp_mode == COMPOSITE_IMAGES)
5464              crop->combined_length += (uint32)zlength;
5465            else
5466              crop->combined_length = (uint32)zlength;
5467            crop->combined_width = (uint32)zwidth;
5468            break;
5469       } /* end switch statement */
5470
5471     buffsize = (uint32)
5472           ((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
5473     crop->regionlist[i].width = (uint32) zwidth;
5474     crop->regionlist[i].length = (uint32) zlength;
5475     crop->regionlist[i].buffsize = buffsize;
5476     crop->bufftotal += buffsize;
5477
5478
5479   if (dump->outfile != NULL)
5480     dump_info (dump->outfile, dump->format, "",  "Zone %d, width: %4d, length: %4d, x1: %4d  x2: %4d  y1: %4d  y2: %4d",
5481                     i + 1, (uint32)zwidth, (uint32)zlength,
5482                     crop->regionlist[i].x1, crop->regionlist[i].x2, 
5483                     crop->regionlist[i].y1, crop->regionlist[i].y2);
5484     }
5485
5486   return (0);
5487   } /* end getCropOffsets */
5488
5489
5490 static int
5491 computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
5492                            struct pagedef *page, struct pageseg *sections,
5493                            struct dump_opts* dump)
5494   {
5495   double scale;
5496   double pwidth, plength;          /* Output page width and length in user units*/
5497   uint32 iwidth, ilength;          /* Input image width and length in pixels*/
5498   uint32 owidth, olength;          /* Output image width and length in pixels*/
5499   uint32 orows, ocols;             /* rows and cols for output */
5500   uint32 hmargin, vmargin;         /* Horizontal and vertical margins */
5501   uint32 x1, x2, y1, y2, line_bytes;
5502   unsigned int orientation;
5503   uint32 i, j, k;
5504  
5505   scale = 1.0;
5506   if (page->res_unit == RESUNIT_NONE)
5507     page->res_unit = image->res_unit;
5508
5509   switch (image->res_unit) {
5510     case RESUNIT_CENTIMETER:
5511          if (page->res_unit == RESUNIT_INCH)
5512            scale = 1.0/2.54;
5513          break;
5514     case RESUNIT_INCH:
5515          if (page->res_unit == RESUNIT_CENTIMETER)
5516              scale = 2.54;
5517          break;
5518     case RESUNIT_NONE: /* Dimensions in pixels */
5519     default:
5520     break;
5521     }
5522
5523   /* get width, height, resolutions of input image selection */
5524   if (crop->combined_width > 0)
5525     iwidth = crop->combined_width;
5526   else
5527     iwidth = image->width;
5528   if (crop->combined_length > 0)
5529     ilength = crop->combined_length;
5530   else
5531     ilength = image->length;
5532
5533   if (page->hres <= 1.0)
5534     page->hres = image->xres;
5535   if (page->vres <= 1.0)
5536     page->vres = image->yres;
5537
5538   if ((page->hres < 1.0) || (page->vres < 1.0))
5539     {
5540     TIFFError("computeOutputPixelOffsets",
5541     "Invalid horizontal or vertical resolution specified or read from input image");
5542     return (1);
5543     }
5544
5545   /* If no page sizes are being specified, we just use the input image size to
5546    * calculate maximum margins that can be taken from image.
5547    */
5548   if (page->width <= 0)
5549     pwidth = iwidth;
5550   else
5551     pwidth = page->width;
5552
5553   if (page->length <= 0)
5554     plength = ilength;
5555   else
5556     plength = page->length;
5557
5558   if (dump->debug)
5559     {
5560     TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
5561                    "Hmargin: %3.2f, Vmargin: %3.2f",
5562              page->name, page->vres, page->hres,
5563              page->hmargin, page->vmargin);
5564     TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f", 
5565            page->res_unit, scale, pwidth, plength);
5566     }
5567
5568   /* compute margins at specified unit and resolution */
5569   if (page->mode & PAGE_MODE_MARGINS)
5570     {
5571     if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
5572       { /* inches or centimeters specified */
5573       hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
5574       vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
5575       }
5576     else
5577       { /* Otherwise user has specified pixels as reference unit */
5578       hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
5579       vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
5580       }
5581
5582     if ((hmargin * 2.0) > (pwidth * page->hres))
5583       {
5584       TIFFError("computeOutputPixelOffsets", 
5585                 "Combined left and right margins exceed page width");
5586       hmargin = (uint32) 0;
5587       return (-1);
5588       }
5589     if ((vmargin * 2.0) > (plength * page->vres))
5590       {
5591       TIFFError("computeOutputPixelOffsets", 
5592                 "Combined top and bottom margins exceed page length"); 
5593       vmargin = (uint32) 0; 
5594       return (-1);
5595       }
5596     }
5597   else
5598     {
5599     hmargin = 0;
5600     vmargin = 0;
5601     }
5602
5603   if (page->mode & PAGE_MODE_ROWSCOLS )
5604     {
5605     /* Maybe someday but not for now */
5606     if (page->mode & PAGE_MODE_MARGINS)
5607       TIFFError("computeOutputPixelOffsets", 
5608       "Output margins cannot be specified with rows and columns"); 
5609
5610     owidth  = TIFFhowmany(iwidth, page->cols);
5611     olength = TIFFhowmany(ilength, page->rows);
5612     }
5613   else
5614     {
5615     if (page->mode & PAGE_MODE_PAPERSIZE )
5616       {
5617       owidth  = (uint32)((pwidth * page->hres) - (hmargin * 2));
5618       olength = (uint32)((plength * page->vres) - (vmargin * 2));
5619       }
5620     else
5621       {
5622       owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
5623       olength = (uint32)(ilength - (vmargin * 2 * page->vres));
5624       }
5625     }
5626
5627   if (owidth > iwidth)
5628     owidth = iwidth;
5629   if (olength > ilength)
5630     olength = ilength;
5631
5632   /* Compute the number of pages required for Portrait or Landscape */
5633   switch (page->orient)
5634     {
5635     case ORIENTATION_NONE:
5636     case ORIENTATION_PORTRAIT:
5637          ocols = TIFFhowmany(iwidth, owidth);
5638          orows = TIFFhowmany(ilength, olength);
5639          orientation = ORIENTATION_PORTRAIT;
5640          break;
5641
5642     case ORIENTATION_LANDSCAPE:
5643          ocols = TIFFhowmany(iwidth, olength);
5644          orows = TIFFhowmany(ilength, owidth);
5645          x1 = olength;
5646          olength = owidth;
5647          owidth = x1;
5648          orientation = ORIENTATION_LANDSCAPE;
5649          break;
5650
5651     case ORIENTATION_AUTO:
5652     default:
5653          x1 = TIFFhowmany(iwidth, owidth);
5654          x2 = TIFFhowmany(ilength, olength); 
5655          y1 = TIFFhowmany(iwidth, olength);
5656          y2 = TIFFhowmany(ilength, owidth); 
5657
5658          if ( (x1 * x2) < (y1 * y2))
5659            { /* Portrait */
5660            ocols = x1;
5661            orows = x2;
5662            orientation = ORIENTATION_PORTRAIT;
5663            }
5664          else
5665            { /* Landscape */
5666            ocols = y1;
5667            orows = y2;
5668            x1 = olength;
5669            olength = owidth;
5670            owidth = x1;
5671            orientation = ORIENTATION_LANDSCAPE;
5672            }
5673     }
5674
5675   if (ocols < 1)
5676     ocols = 1;
5677   if (orows < 1)
5678     orows = 1;
5679
5680   /* If user did not specify rows and cols, set them from calcuation */
5681   if (page->rows < 1)
5682     page->rows = orows;
5683   if (page->cols < 1)
5684     page->cols = ocols;
5685
5686   line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
5687
5688   if ((page->rows * page->cols) > MAX_SECTIONS)
5689    {
5690    TIFFError("computeOutputPixelOffsets",
5691              "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
5692    return (-1);
5693    }
5694
5695   /* build the list of offsets for each output section */
5696   for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
5697     {
5698     y1 = (uint32)(olength * i);
5699     y2 = (uint32)(olength * (i +  1) - 1);
5700     if (y2 >= ilength)
5701       y2 = ilength - 1;
5702     for (j = 0; j < ocols; j++, k++)
5703       {
5704       x1 = (uint32)(owidth * j); 
5705       x2 = (uint32)(owidth * (j + 1) - 1);
5706       if (x2 >= iwidth)
5707         x2 = iwidth - 1;
5708       sections[k].x1 = x1;
5709       sections[k].x2 = x2;
5710       sections[k].y1 = y1;
5711       sections[k].y2 = y2;
5712       sections[k].buffsize = line_bytes * olength;
5713       sections[k].position = k + 1;
5714       sections[k].total = orows * ocols;
5715       } 
5716     } 
5717   return (0);
5718   } /* end computeOutputPixelOffsets */
5719
5720 static int
5721 loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned char **read_ptr)
5722   {
5723   uint32   i;
5724   float    xres = 0.0, yres = 0.0;
5725   uint16   nstrips = 0, ntiles = 0, planar = 0;
5726   uint16   bps = 0, spp = 0, res_unit = 0;
5727   uint16   orientation = 0;
5728   uint16   input_compression = 0, input_photometric = 0;
5729   uint16   subsampling_horiz, subsampling_vert;
5730   uint32   width = 0, length = 0;
5731   uint32   stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
5732   uint32   tw = 0, tl = 0;       /* Tile width and length */
5733   uint32   tile_rowsize = 0;
5734   unsigned char *read_buff = NULL;
5735   unsigned char *new_buff  = NULL;
5736   int      readunit = 0;
5737   static   uint32  prev_readsize = 0;
5738
5739   TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
5740   TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
5741   TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
5742   TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
5743   if (! TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric))
5744     TIFFError("loadImage","Image lacks Photometric interpreation tag");
5745   if (! TIFFGetField(in, TIFFTAG_IMAGEWIDTH,  &width))
5746     TIFFError("loadimage","Image lacks image width tag");
5747   if(! TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length))
5748     TIFFError("loadimage","Image lacks image length tag");
5749   TIFFGetFieldDefaulted(in, TIFFTAG_XRESOLUTION, &xres);
5750   TIFFGetFieldDefaulted(in, TIFFTAG_YRESOLUTION, &yres);
5751   if (!TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit))
5752     res_unit = RESUNIT_INCH;
5753   if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression))
5754     input_compression = COMPRESSION_NONE;
5755
5756 #ifdef DEBUG2
5757   char compressionid[16];
5758
5759   switch (input_compression)
5760     {
5761     case COMPRESSION_NONE:      /* 1  dump mode */
5762          strcpy (compressionid, "None/dump");
5763          break;         
5764     case COMPRESSION_CCITTRLE:    /* 2 CCITT modified Huffman RLE */
5765          strcpy (compressionid, "Huffman RLE");
5766          break;         
5767     case COMPRESSION_CCITTFAX3:   /* 3 CCITT Group 3 fax encoding */
5768          strcpy (compressionid, "Group3 Fax");
5769          break;         
5770     case COMPRESSION_CCITTFAX4:   /* 4 CCITT Group 4 fax encoding */
5771          strcpy (compressionid, "Group4 Fax");
5772          break;         
5773     case COMPRESSION_LZW:         /* 5 Lempel-Ziv  & Welch */
5774          strcpy (compressionid, "LZW");
5775          break;         
5776     case COMPRESSION_OJPEG:       /* 6 !6.0 JPEG */
5777          strcpy (compressionid, "Old Jpeg");
5778          break;         
5779     case COMPRESSION_JPEG:        /* 7 %JPEG DCT compression */
5780          strcpy (compressionid, "New Jpeg");
5781          break;         
5782     case COMPRESSION_NEXT:        /* 32766 NeXT 2-bit RLE */
5783          strcpy (compressionid, "Next RLE");
5784          break;         
5785     case COMPRESSION_CCITTRLEW:   /* 32771 #1 w/ word alignment */
5786          strcpy (compressionid, "CITTRLEW");
5787          break;         
5788     case COMPRESSION_PACKBITS:    /* 32773 Macintosh RLE */
5789          strcpy (compressionid, "Mac Packbits");
5790          break;         
5791     case COMPRESSION_THUNDERSCAN: /* 32809 ThunderScan RLE */
5792          strcpy (compressionid, "Thunderscan");
5793          break;         
5794     case COMPRESSION_IT8CTPAD:    /* 32895 IT8 CT w/padding */
5795          strcpy (compressionid, "IT8 padded");
5796          break;         
5797     case COMPRESSION_IT8LW:       /* 32896 IT8 Linework RLE */
5798          strcpy (compressionid, "IT8 RLE");
5799          break;         
5800     case COMPRESSION_IT8MP:       /* 32897 IT8 Monochrome picture */
5801          strcpy (compressionid, "IT8 mono");
5802          break;         
5803     case COMPRESSION_IT8BL:       /* 32898 IT8 Binary line art */
5804          strcpy (compressionid, "IT8 lineart");
5805          break;         
5806     case COMPRESSION_PIXARFILM:   /* 32908 Pixar companded 10bit LZW */
5807          strcpy (compressionid, "Pixar 10 bit");
5808          break;         
5809     case COMPRESSION_PIXARLOG:    /* 32909 Pixar companded 11bit ZIP */
5810          strcpy (compressionid, "Pixar 11bit");
5811          break;         
5812     case COMPRESSION_DEFLATE:     /* 32946 Deflate compression */
5813          strcpy (compressionid, "Deflate");
5814          break;         
5815     case COMPRESSION_ADOBE_DEFLATE: /* 8 Deflate compression */
5816          strcpy (compressionid, "Adobe deflate");
5817          break;         
5818     default:
5819          strcpy (compressionid, "None/unknown");
5820          break;         
5821     }
5822   TIFFError("loadImage", "Input compression %s", compressionid);
5823 #endif
5824
5825   scanlinesize = TIFFScanlineSize(in);
5826   image->bps = bps;
5827   image->spp = spp;
5828   image->planar = planar;
5829   image->width = width;
5830   image->length = length;
5831   image->xres = xres;
5832   image->yres = yres;
5833   image->res_unit = res_unit;
5834   image->compression = input_compression;
5835   image->photometric = input_photometric;
5836 #ifdef DEBUG2
5837   char photometricid[12];
5838
5839   switch (input_photometric)
5840     {
5841     case PHOTOMETRIC_MINISWHITE:
5842          strcpy (photometricid, "MinIsWhite");
5843          break;
5844     case PHOTOMETRIC_MINISBLACK:
5845          strcpy (photometricid, "MinIsBlack");
5846          break;
5847     case PHOTOMETRIC_RGB:
5848          strcpy (photometricid, "RGB");
5849          break;
5850     case PHOTOMETRIC_PALETTE:
5851          strcpy (photometricid, "Palette");
5852          break;
5853     case PHOTOMETRIC_MASK:
5854          strcpy (photometricid, "Mask");
5855          break;
5856     case PHOTOMETRIC_SEPARATED:
5857          strcpy (photometricid, "Separated");
5858          break;
5859     case PHOTOMETRIC_YCBCR:
5860          strcpy (photometricid, "YCBCR");
5861          break;
5862     case PHOTOMETRIC_CIELAB:
5863          strcpy (photometricid, "CIELab");
5864          break;
5865     case PHOTOMETRIC_ICCLAB:
5866          strcpy (photometricid, "ICCLab");
5867          break;
5868     case PHOTOMETRIC_ITULAB:
5869          strcpy (photometricid, "ITULab");
5870          break;
5871     case PHOTOMETRIC_LOGL:
5872          strcpy (photometricid, "LogL");
5873          break;
5874     case PHOTOMETRIC_LOGLUV:
5875          strcpy (photometricid, "LOGLuv");
5876          break;
5877     default:
5878          strcpy (photometricid, "Unknown");
5879          break;
5880     }
5881   TIFFError("loadImage", "Input photometric interpretation %s", photometricid);
5882
5883 #endif
5884   image->orientation = orientation;
5885   switch (orientation)
5886     {
5887     case 0:
5888     case ORIENTATION_TOPLEFT:
5889          image->adjustments = 0;
5890          break;
5891     case ORIENTATION_TOPRIGHT:
5892          image->adjustments = MIRROR_HORIZ;
5893          break;
5894     case ORIENTATION_BOTRIGHT:
5895          image->adjustments = ROTATECW_180;
5896          break;
5897     case ORIENTATION_BOTLEFT:
5898          image->adjustments = MIRROR_VERT; 
5899          break;
5900     case ORIENTATION_LEFTTOP:
5901          image->adjustments = MIRROR_VERT | ROTATECW_90;
5902          break;
5903     case ORIENTATION_RIGHTTOP:
5904          image->adjustments = ROTATECW_90;
5905          break;
5906     case ORIENTATION_RIGHTBOT:
5907          image->adjustments = MIRROR_VERT | ROTATECW_270;
5908          break; 
5909     case ORIENTATION_LEFTBOT:
5910          image->adjustments = ROTATECW_270;
5911          break;
5912     default:
5913          image->adjustments = 0;
5914          image->orientation = ORIENTATION_TOPLEFT;
5915    }
5916
5917   if ((bps == 0) || (spp == 0))
5918     {
5919     TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
5920                spp, bps);
5921     return (-1);
5922     }
5923
5924   if (TIFFIsTiled(in))
5925     {
5926     readunit = TILE;
5927     tlsize = TIFFTileSize(in);
5928     ntiles = TIFFNumberOfTiles(in);
5929     TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
5930     TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
5931
5932     tile_rowsize  = TIFFTileRowSize(in);      
5933     buffsize = tlsize * ntiles;
5934
5935         
5936     if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
5937       {
5938       buffsize = ntiles * tl * tile_rowsize;
5939 #ifdef DEBUG2
5940       TIFFError("loadImage",
5941                 "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
5942                 tlsize, (unsigned long)buffsize);
5943 #endif
5944       }
5945     
5946     if (dump->infile != NULL)
5947       dump_info (dump->infile, dump->format, "", 
5948                  "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
5949                  tlsize, ntiles, tile_rowsize);
5950     }
5951   else
5952     {
5953     readunit = STRIP;
5954     TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
5955     stsize = TIFFStripSize(in);
5956     nstrips = TIFFNumberOfStrips(in);
5957     buffsize = stsize * nstrips;
5958     
5959     if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
5960       {
5961       buffsize =  ((length * width * spp * bps) + 7) / 8;
5962 #ifdef DEBUG2
5963       TIFFError("loadImage",
5964                 "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
5965                 stsize, (unsigned long)buffsize);
5966 #endif
5967       }
5968     
5969     if (dump->infile != NULL)
5970       dump_info (dump->infile, dump->format, "",
5971                  "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
5972                  stsize, nstrips, rowsperstrip, scanlinesize);
5973     }
5974   
5975   if (input_compression == COMPRESSION_JPEG)
5976     {  /* Force conversion to RGB */
5977     jpegcolormode = JPEGCOLORMODE_RGB;
5978     TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
5979     }
5980   /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
5981   else 
5982     {   /* Otherwise, can't handle subsampled input */
5983     if (input_photometric == PHOTOMETRIC_YCBCR)
5984       {
5985       TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
5986                            &subsampling_horiz, &subsampling_vert);
5987       if (subsampling_horiz != 1 || subsampling_vert != 1)
5988         {
5989         TIFFError("loadImage", 
5990                 "Can't copy/convert subsampled image with subsampling %d horiz %d vert",
5991                 subsampling_horiz, subsampling_vert);
5992         return (-1);
5993         }
5994         }
5995     }
5996  
5997   read_buff = *read_ptr;
5998   if (!read_buff)
5999     read_buff = (unsigned char *)_TIFFmalloc(buffsize);
6000   else
6001     {
6002     if (prev_readsize < buffsize)
6003       {
6004       new_buff = _TIFFrealloc(read_buff, buffsize);
6005       if (!new_buff)
6006         {
6007         free (read_buff);
6008         read_buff = (unsigned char *)_TIFFmalloc(buffsize);
6009         }
6010       else
6011         read_buff = new_buff;
6012       }
6013     }
6014
6015   if (!read_buff)
6016     {
6017     TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6018     return (-1);
6019     }
6020
6021   prev_readsize = buffsize;
6022   *read_ptr = read_buff;
6023
6024   /* N.B. The read functions used copy separate plane data into a buffer as interleaved
6025    * samples rather than separate planes so the same logic works to extract regions
6026    * regardless of the way the data are organized in the input file.
6027    */
6028   switch (readunit) {
6029     case STRIP:
6030          if (planar == PLANARCONFIG_CONTIG)
6031            {
6032              if (!(readContigStripsIntoBuffer(in, read_buff)))
6033              {
6034              TIFFError("loadImage", "Unable to read contiguous strips into buffer");
6035              return (-1);
6036              }
6037            }
6038          else
6039            {
6040            if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
6041              {
6042              TIFFError("loadImage", "Unable to read separate strips into buffer");
6043              return (-1);
6044              }
6045            }
6046          break;
6047
6048     case TILE:
6049          if (planar == PLANARCONFIG_CONTIG)
6050            {
6051            if (!(readContigTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6052              {
6053              TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
6054              return (-1);
6055              }
6056            }
6057          else
6058            {
6059            if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6060              {
6061              TIFFError("loadImage", "Unable to read separate tiles into buffer");
6062              return (-1);
6063              }
6064            }
6065          break;
6066     default: TIFFError("loadImage", "Unsupported image file format");
6067           return (-1);
6068           break;
6069     }
6070   if ((dump->infile != NULL) && (dump->level == 2))
6071     {
6072     dump_info  (dump->infile, dump->format, "loadImage", 
6073                 "Image width %d, length %d, Raw image data, %4d bytes",
6074                 width, length,  buffsize);
6075     dump_info  (dump->infile, dump->format, "", 
6076                 "Bits per sample %d, Samples per pixel %d", bps, spp);
6077
6078     for (i = 0; i < length; i++)
6079       dump_buffer(dump->infile, dump->format, 1, scanlinesize, 
6080                   i, read_buff + (i * scanlinesize));
6081     }
6082   return (0);
6083   }   /* end loadImage */
6084
6085 static int  correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
6086   {
6087   uint16 mirror, rotation;
6088   unsigned char *work_buff;
6089
6090   work_buff = *work_buff_ptr;
6091   if ((image == NULL) || (work_buff == NULL))
6092     {
6093     TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
6094     return (-1);
6095     }
6096
6097   if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
6098     {
6099     mirror = (uint16)(image->adjustments & MIRROR_BOTH);
6100     if (mirrorImage(image->spp, image->bps, mirror, 
6101         image->width, image->length, work_buff))
6102       {
6103       TIFFError ("correct_orientation", "Unable to mirror image");
6104       return (-1);
6105       }
6106     }
6107
6108   if (image->adjustments & ROTATE_ANY)
6109     {
6110     if (image->adjustments & ROTATECW_90)
6111       rotation = (uint16) 90;
6112     else
6113     if (image->adjustments & ROTATECW_180)
6114       rotation = (uint16) 180;
6115     else
6116     if (image->adjustments & ROTATECW_270)
6117       rotation = (uint16) 270;
6118     else
6119       {
6120       TIFFError ("correct_orientation", "Invalid rotation value: %d", 
6121                   image->adjustments & ROTATE_ANY);
6122       return (-1);
6123       }
6124  
6125     if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
6126       {
6127       TIFFError ("correct_orientation", "Unable to rotate image");
6128       return (-1);
6129       }
6130     image->orientation = ORIENTATION_TOPLEFT;
6131     }
6132
6133   return (0);
6134   } /* end correct_orientation */
6135
6136
6137 /* Extract multiple zones from an image and combine into a single composite image */
6138 static int
6139 extractCompositeRegions(struct image_data *image,  struct crop_mask *crop, 
6140                         unsigned char *read_buff, unsigned char *crop_buff)
6141   {
6142   int       shift_width, bytes_per_sample, bytes_per_pixel;
6143   uint32    i, trailing_bits, prev_trailing_bits;
6144   uint32    row, first_row, last_row, first_col, last_col;
6145   uint32    src_rowsize, dst_rowsize, src_offset, dst_offset;
6146   uint32    crop_width, crop_length, img_width, img_length;
6147   uint32    prev_length, prev_width, composite_width;
6148   uint16    bps, spp;
6149   uint8    *src, *dst;
6150   tsample_t count, sample = 0;   /* Update to extract one or more samples */
6151
6152   img_width = image->width;
6153   img_length = image->length;
6154   bps = image->bps;
6155   spp = image->spp;
6156   count = spp;
6157
6158   bytes_per_sample = (bps + 7) / 8; 
6159   bytes_per_pixel  = ((bps * spp) + 7) / 8;
6160   if ((bps % 8) == 0)
6161     shift_width = 0;
6162   else
6163     {
6164     if (bytes_per_pixel < (bytes_per_sample + 1))
6165       shift_width = bytes_per_pixel;
6166     else
6167       shift_width = bytes_per_sample + 1;
6168     }
6169   src = read_buff;
6170   dst = crop_buff;
6171
6172   /* These are setup for adding additional sections */
6173   prev_width = prev_length = 0;
6174   prev_trailing_bits = trailing_bits = 0;
6175   composite_width = crop->combined_width;
6176   crop->combined_width = 0;
6177   crop->combined_length = 0;
6178
6179   for (i = 0; i < crop->selections; i++)
6180     {
6181     /* rows, columns, width, length are expressed in pixels */
6182     first_row = crop->regionlist[i].y1;
6183     last_row  = crop->regionlist[i].y2;
6184     first_col = crop->regionlist[i].x1;
6185     last_col  = crop->regionlist[i].x2;
6186
6187     crop_width = last_col - first_col + 1;
6188     crop_length = last_row - first_row + 1;
6189
6190     /* These should not be needed for composite images */
6191     crop->regionlist[i].width = crop_width;
6192     crop->regionlist[i].length = crop_length;
6193     crop->regionlist[i].buffptr = crop_buff;
6194
6195     src_rowsize = ((img_width * bps * spp) + 7) / 8;
6196     dst_rowsize = (((crop_width * bps * count) + 7) / 8);
6197
6198     switch (crop->edge_ref)
6199       {
6200       default:
6201       case EDGE_TOP:
6202       case EDGE_BOTTOM:
6203            if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
6204              {
6205              TIFFError ("extractCompositeRegions", 
6206                           "Only equal width regions can be combined for -E top or bottom");
6207              return (1);
6208              }
6209
6210            crop->combined_width = crop_width;
6211            crop->combined_length += crop_length;
6212
6213            for (row = first_row; row <= last_row; row++)
6214              {
6215              src_offset = row * src_rowsize;
6216              dst_offset = (row - first_row) * dst_rowsize;
6217              src = read_buff + src_offset;
6218              dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
6219              switch (shift_width)
6220                {
6221                case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6222                                                       spp, bps, count, first_col,
6223                                                       last_col + 1))
6224                          {
6225                          TIFFError("extractCompositeRegions",
6226                                    "Unable to extract row %d", row);
6227                          return (1);
6228                          }
6229                        break;
6230                case 1: if (bps == 1)
6231                          { 
6232                          if (extractContigSamplesShifted8bits (src, dst, img_width,
6233                                                                sample, spp, bps, count, 
6234                                                                first_col, last_col + 1,
6235                                                                prev_trailing_bits))
6236                            {
6237                            TIFFError("extractCompositeRegions",
6238                                      "Unable to extract row %d", row);
6239                            return (1);
6240                            }
6241                          break;
6242                          }
6243                        else
6244                          if (extractContigSamplesShifted16bits (src, dst, img_width,
6245                                                                 sample, spp, bps, count, 
6246                                                                 first_col, last_col + 1,
6247                                                                 prev_trailing_bits))
6248                            {
6249                            TIFFError("extractCompositeRegions",
6250                                      "Unable to extract row %d", row);
6251                            return (1);
6252                            }
6253                         break;
6254                case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
6255                                                                sample, spp, bps, count, 
6256                                                                first_col, last_col + 1,
6257                                                                prev_trailing_bits))
6258                           {
6259                           TIFFError("extractCompositeRegions",
6260                                     "Unable to extract row %d", row);
6261                           return (1);
6262                           }
6263                         break;
6264                case 3:
6265                case 4:
6266                case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
6267                                                                sample, spp, bps, count, 
6268                                                                first_col, last_col + 1,
6269                                                                prev_trailing_bits))
6270                           {
6271                           TIFFError("extractCompositeRegions",
6272                                     "Unable to extract row %d", row);
6273                           return (1);
6274                           }
6275                         break;
6276                default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6277                         return (1);
6278                }
6279              }
6280            prev_length += crop_length;
6281            break;
6282       case EDGE_LEFT:  /* splice the pieces of each row together, side by side */
6283       case EDGE_RIGHT:
6284            if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
6285              {
6286              TIFFError ("extractCompositeRegions", 
6287                           "Only equal length regions can be combined for -E left or right");
6288              return (1);
6289              }
6290            crop->combined_width += crop_width;
6291            crop->combined_length = crop_length;
6292            dst_rowsize = (((composite_width * bps * count) + 7) / 8);
6293            trailing_bits = (crop_width * bps * count) % 8;
6294            for (row = first_row; row <= last_row; row++)
6295              {
6296              src_offset = row * src_rowsize;
6297              dst_offset = (row - first_row) * dst_rowsize;
6298              src = read_buff + src_offset;
6299              dst = crop_buff + dst_offset + prev_width;
6300
6301              switch (shift_width)
6302                {
6303                case 0: if (extractContigSamplesBytes (src, dst, img_width,
6304                                                       sample, spp, bps, count,
6305                                                       first_col, last_col + 1))
6306                          {
6307                          TIFFError("extractCompositeRegions",
6308                                    "Unable to extract row %d", row);
6309                          return (1);
6310                          }
6311                        break;
6312                case 1: if (bps == 1)
6313                          { 
6314                          if (extractContigSamplesShifted8bits (src, dst, img_width,
6315                                                                sample, spp, bps, count, 
6316                                                                first_col, last_col + 1,
6317                                                                prev_trailing_bits))
6318                            {
6319                            TIFFError("extractCompositeRegions",
6320                                      "Unable to extract row %d", row);
6321                            return (1);
6322                            }
6323                          break;
6324                          }
6325                        else
6326                          if (extractContigSamplesShifted16bits (src, dst, img_width,
6327                                                                 sample, spp, bps, count, 
6328                                                                 first_col, last_col + 1,
6329                                                                 prev_trailing_bits))
6330                            {
6331                            TIFFError("extractCompositeRegions",
6332                                      "Unable to extract row %d", row);
6333                            return (1);
6334                            }
6335                         break;
6336               case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
6337                                                                sample, spp, bps, count, 
6338                                                                first_col, last_col + 1,
6339                                                                prev_trailing_bits))
6340                           {
6341                           TIFFError("extractCompositeRegions",
6342                                     "Unable to extract row %d", row);
6343                           return (1);
6344                           }
6345                         break;
6346                case 3:
6347                case 4:
6348                case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
6349                                                                sample, spp, bps, count, 
6350                                                                first_col, last_col + 1,
6351                                                                prev_trailing_bits))
6352                           {
6353                           TIFFError("extractCompositeRegions",
6354                                     "Unable to extract row %d", row);
6355                           return (1);
6356                           }
6357                         break;
6358                default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6359                         return (1);
6360                }
6361              }
6362            prev_width += (crop_width * bps * count) / 8;
6363            prev_trailing_bits += trailing_bits;
6364            if (prev_trailing_bits > 7)
6365              prev_trailing_bits-= 8;
6366            break;
6367       }
6368     }
6369   if (crop->combined_width != composite_width)
6370     TIFFError("combineSeparateRegions","Combined width does not match composite width");
6371       
6372   return (0);
6373   }  /* end extractCompositeRegions */
6374
6375 /* Copy a single region of input buffer to an output buffer. 
6376  * The read functions used copy separate plane data into a buffer 
6377  * as interleaved samples rather than separate planes so the same
6378  * logic works to extract regions regardless of the way the data 
6379  * are organized in the input file. This function can be used to
6380  * extract one or more samples from the input image by updating the 
6381  * parameters for starting sample and number of samples to copy in the
6382  * fifth and eighth arguments of the call to extractContigSamples.
6383  * They would be passed as new elements of the crop_mask struct.
6384  */
6385
6386 static int
6387 extractSeparateRegion(struct image_data *image,  struct crop_mask *crop,
6388                       unsigned char *read_buff, unsigned char *crop_buff,
6389                       int region)
6390   {
6391   int     shift_width, prev_trailing_bits = 0;
6392   uint32  bytes_per_sample, bytes_per_pixel;
6393   uint32  src_rowsize, dst_rowsize;
6394   uint32  row, first_row, last_row, first_col, last_col;
6395   uint32  src_offset, dst_offset;
6396   uint32  crop_width, crop_length, img_width, img_length;
6397   uint16  bps, spp;
6398   uint8  *src, *dst;
6399   tsample_t count, sample = 0;   /* Update to extract more or more samples */
6400
6401   img_width = image->width;
6402   img_length = image->length;
6403   bps = image->bps;
6404   spp = image->spp;
6405   count = spp;
6406
6407   bytes_per_sample = (bps + 7) / 8; 
6408   bytes_per_pixel  = ((bps * spp) + 7) / 8;
6409   if ((bps % 8) == 0)
6410     shift_width = 0; /* Byte aligned data only */
6411   else
6412     {
6413     if (bytes_per_pixel < (bytes_per_sample + 1))
6414       shift_width = bytes_per_pixel;
6415     else
6416       shift_width = bytes_per_sample + 1;
6417     }
6418
6419   /* rows, columns, width, length are expressed in pixels */
6420   first_row = crop->regionlist[region].y1;
6421   last_row  = crop->regionlist[region].y2;
6422   first_col = crop->regionlist[region].x1;
6423   last_col  = crop->regionlist[region].x2;
6424
6425   crop_width = last_col - first_col + 1;
6426   crop_length = last_row - first_row + 1;
6427
6428   crop->regionlist[region].width = crop_width;
6429   crop->regionlist[region].length = crop_length;
6430   crop->regionlist[region].buffptr = crop_buff;
6431
6432   src = read_buff;
6433   dst = crop_buff;
6434   src_rowsize = ((img_width * bps * spp) + 7) / 8;
6435   dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
6436
6437   for (row = first_row; row <= last_row; row++)
6438     {
6439     src_offset = row * src_rowsize;
6440     dst_offset = (row  - first_row) * dst_rowsize;
6441     src = read_buff + src_offset;
6442     dst = crop_buff + dst_offset;
6443
6444     switch (shift_width)
6445       {
6446       case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6447                                              spp, bps, count, first_col,
6448                                              last_col + 1))
6449                 {
6450                 TIFFError("extractSeparateRegion",
6451                           "Unable to extract row %d", row);
6452                 return (1);
6453                 }
6454               break;
6455       case 1: if (bps == 1)
6456                 { 
6457                 if (extractContigSamplesShifted8bits (src, dst, img_width,
6458                                                       sample, spp, bps, count, 
6459                                                       first_col, last_col + 1,
6460                                                       prev_trailing_bits))
6461                   {
6462                   TIFFError("extractSeparateRegion",
6463                             "Unable to extract row %d", row);
6464                   return (1);
6465                   }
6466                   break;
6467                 }
6468               else
6469                 if (extractContigSamplesShifted16bits (src, dst, img_width,
6470                                                        sample, spp, bps, count, 
6471                                                        first_col, last_col + 1,
6472                                                        prev_trailing_bits))
6473                   {
6474                   TIFFError("extractSeparateRegion",
6475                             "Unable to extract row %d", row);
6476                   return (1);
6477                   }
6478               break;
6479       case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
6480                                                      sample, spp, bps, count, 
6481                                                      first_col, last_col + 1,
6482                                                      prev_trailing_bits))
6483                 {
6484                 TIFFError("extractSeparateRegion",
6485                           "Unable to extract row %d", row);
6486                 return (1);
6487                 }
6488               break;
6489       case 3:
6490       case 4:
6491       case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
6492                                                      sample, spp, bps, count, 
6493                                                      first_col, last_col + 1,
6494                                                      prev_trailing_bits))
6495                 {
6496                 TIFFError("extractSeparateRegion",
6497                           "Unable to extract row %d", row);
6498                 return (1);
6499                 }
6500               break;
6501       default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
6502                return (1);
6503       }
6504     }
6505           
6506   return (0);
6507   }  /* end extractSeparateRegion */
6508
6509 static int
6510 extractImageSection(struct image_data *image, struct pageseg *section, 
6511                     unsigned char *src_buff, unsigned char *sect_buff)
6512   {
6513   unsigned  char  bytebuff1, bytebuff2;
6514   unsigned  char *src, *dst;
6515
6516   uint32    img_width, img_length, img_rowsize;
6517   uint32    j, shift1, shift2, trailing_bits;
6518   uint32    row, first_row, last_row, first_col, last_col;
6519   uint32    src_offset, dst_offset, row_offset, col_offset;
6520   uint32    offset1, offset2, full_bytes;
6521   uint32    sect_width, sect_length;
6522   uint16    bps, spp;
6523
6524 #ifdef DEVELMODE
6525   int      k;
6526   unsigned char bitset;
6527   static char *bitarray = NULL;
6528 #endif
6529
6530   img_width = image->width;
6531   img_length = image->length;
6532   bps = image->bps;
6533   spp = image->spp;
6534
6535   src = src_buff;
6536   dst = sect_buff;
6537   src_offset = 0;
6538   dst_offset = 0;
6539
6540 #ifdef DEVELMODE
6541   if (bitarray == NULL)
6542     {
6543     if ((bitarray = (char *)malloc(img_width)) == NULL)
6544       {
6545       TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
6546       return (-1);
6547       }
6548     }
6549 #endif
6550
6551   /* rows, columns, width, length are expressed in pixels */
6552   first_row = section->y1;
6553   last_row  = section->y2;
6554   first_col = section->x1;
6555   last_col  = section->x2;
6556
6557   sect_width = last_col - first_col + 1;
6558   sect_length = last_row - first_row + 1;
6559   img_rowsize = ((img_width * bps + 7) / 8) * spp;
6560   full_bytes = (sect_width * spp * bps) / 8;   /* number of COMPLETE bytes per row in section */
6561   trailing_bits = (sect_width * bps) % 8;
6562
6563 #ifdef DEVELMODE
6564     TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
6565            first_row, last_row, first_col, last_col);
6566     TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
6567            img_width, img_length, bps, spp);
6568     TIFFError ("", "Sect  width: %d,  Sect length: %d, full bytes: %d trailing bits %d\n", 
6569            sect_width, sect_length, full_bytes, trailing_bits);
6570 #endif
6571
6572   if ((bps % 8) == 0)
6573     {
6574     col_offset = first_col * spp * bps / 8;
6575     for (row = first_row; row <= last_row; row++)
6576       {
6577       /* row_offset = row * img_width * spp * bps / 8; */
6578       row_offset = row * img_rowsize;
6579       src_offset = row_offset + col_offset;
6580
6581 #ifdef DEVELMODE
6582         TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset, dst_offset); 
6583 #endif
6584       _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
6585       dst_offset += full_bytes;
6586       }        
6587     }
6588   else
6589     { /* bps != 8 */
6590     shift1  = spp * ((first_col * bps) % 8);
6591     shift2  = spp * ((last_col * bps) % 8);
6592     for (row = first_row; row <= last_row; row++)
6593       {
6594       /* pull out the first byte */
6595       row_offset = row * img_rowsize;
6596       offset1 = row_offset + (first_col * bps / 8);
6597       offset2 = row_offset + (last_col * bps / 8);
6598
6599 #ifdef DEVELMODE
6600       for (j = 0, k = 7; j < 8; j++, k--)
6601         {
6602         bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
6603         sprintf(&bitarray[j], (bitset) ? "1" : "0");
6604         }
6605       sprintf(&bitarray[8], " ");
6606       sprintf(&bitarray[9], " ");
6607       for (j = 10, k = 7; j < 18; j++, k--)
6608         {
6609         bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
6610         sprintf(&bitarray[j], (bitset) ? "1" : "0");
6611         }
6612       bitarray[18] = '\0';
6613       TIFFError ("", "Row: %3d Offset1: %d,  Shift1: %d,    Offset2: %d,  Shift2:  %d\n", 
6614                  row, offset1, shift1, offset2, shift2); 
6615 #endif
6616
6617       bytebuff1 = bytebuff2 = 0;
6618       if (shift1 == 0) /* the region is byte and sample alligned */
6619         {
6620         _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
6621
6622 #ifdef DEVELMODE
6623         TIFFError ("", "        Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset); 
6624         sprintf(&bitarray[18], "\n");
6625         sprintf(&bitarray[19], "\t");
6626         for (j = 20, k = 7; j < 28; j++, k--)
6627           {
6628           bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6629           sprintf(&bitarray[j], (bitset) ? "1" : "0");
6630           }
6631         bitarray[28] = ' ';
6632         bitarray[29] = ' ';
6633 #endif
6634         dst_offset += full_bytes;
6635
6636         if (trailing_bits != 0)
6637           {
6638           bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
6639           sect_buff[dst_offset] = bytebuff2;
6640 #ifdef DEVELMODE
6641           TIFFError ("", "        Trailing bits src offset:  %8d, Dst offset: %8d\n", 
6642                               offset2, dst_offset); 
6643           for (j = 30, k = 7; j < 38; j++, k--)
6644             {
6645             bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6646             sprintf(&bitarray[j], (bitset) ? "1" : "0");
6647             }
6648           bitarray[38] = '\0';
6649           TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6650 #endif
6651           dst_offset++;
6652           }
6653         }
6654       else   /* each destination byte will have to be built from two source bytes*/
6655         {
6656 #ifdef DEVELMODE
6657           TIFFError ("", "        Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset); 
6658 #endif
6659         for (j = 0; j <= full_bytes; j++) 
6660           {
6661           bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
6662           bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
6663           sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
6664           }
6665 #ifdef DEVELMODE
6666         sprintf(&bitarray[18], "\n");
6667         sprintf(&bitarray[19], "\t");
6668         for (j = 20, k = 7; j < 28; j++, k--)
6669           {
6670           bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6671           sprintf(&bitarray[j], (bitset) ? "1" : "0");
6672           }
6673         bitarray[28] = ' ';
6674         bitarray[29] = ' ';
6675 #endif
6676         dst_offset += full_bytes;
6677
6678         if (trailing_bits != 0)
6679           {
6680 #ifdef DEVELMODE
6681             TIFFError ("", "        Trailing bits   src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset); 
6682 #endif
6683           if (shift2 > shift1)
6684             {
6685             bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
6686             bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
6687             sect_buff[dst_offset] = bytebuff2;
6688 #ifdef DEVELMODE
6689             TIFFError ("", "        Shift2 > Shift1\n"); 
6690 #endif
6691             }
6692           else
6693             {
6694             if (shift2 < shift1)
6695               {
6696               bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
6697               sect_buff[dst_offset] &= bytebuff2;
6698 #ifdef DEVELMODE
6699               TIFFError ("", "        Shift2 < Shift1\n"); 
6700 #endif
6701               }
6702 #ifdef DEVELMODE
6703             else
6704               TIFFError ("", "        Shift2 == Shift1\n"); 
6705 #endif
6706             }
6707           }
6708 #ifdef DEVELMODE
6709           sprintf(&bitarray[28], " ");
6710           sprintf(&bitarray[29], " ");
6711           for (j = 30, k = 7; j < 38; j++, k--)
6712             {
6713             bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6714             sprintf(&bitarray[j], (bitset) ? "1" : "0");
6715             }
6716           bitarray[38] = '\0';
6717           TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6718 #endif
6719         dst_offset++;
6720         }
6721       }
6722     }
6723
6724   return (0);
6725   } /* end extractImageSection */
6726
6727 static int 
6728 writeSelections(TIFF *in, TIFF **out, struct crop_mask *crop, 
6729                 struct image_data *image, struct dump_opts *dump,
6730                 struct buffinfo seg_buffs[], char *mp, char *filename, 
6731                 unsigned int *page, unsigned int total_pages)
6732   {
6733   int i, page_count;
6734   int autoindex = 0;
6735   unsigned char *crop_buff = NULL;
6736
6737   /* Where we open a new file depends on the export mode */  
6738   switch (crop->exp_mode)
6739     {
6740     case ONE_FILE_COMPOSITE: /* Regions combined into single image */
6741          autoindex = 0;
6742          crop_buff = seg_buffs[0].buffer;
6743          if (update_output_file (out, mp, autoindex, filename, page))
6744            return (1);
6745          page_count = total_pages;
6746          if (writeCroppedImage(in, *out, image, dump,
6747                                crop->combined_width, 
6748                                crop->combined_length,
6749                                crop_buff, *page, total_pages))
6750             {
6751              TIFFError("writeRegions", "Unable to write new image");
6752              return (-1);
6753              }
6754          break;
6755     case ONE_FILE_SEPARATED: /* Regions as separated images */
6756          autoindex = 0;
6757          if (update_output_file (out, mp, autoindex, filename, page))
6758            return (1);
6759          page_count = crop->selections * total_pages;
6760          for (i = 0; i < crop->selections; i++)
6761            {
6762            crop_buff = seg_buffs[i].buffer;
6763            if (writeCroppedImage(in, *out, image, dump,
6764                                  crop->regionlist[i].width, 
6765                                  crop->regionlist[i].length, 
6766                                  crop_buff, *page, page_count))
6767              {
6768              TIFFError("writeRegions", "Unable to write new image");
6769              return (-1);
6770              }
6771            }
6772          break;
6773     case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
6774          autoindex = 1;
6775          if (update_output_file (out, mp, autoindex, filename, page))
6776            return (1);
6777
6778          crop_buff = seg_buffs[0].buffer;
6779          if (writeCroppedImage(in, *out, image, dump,
6780                                crop->combined_width, 
6781                                crop->combined_length, 
6782                                crop_buff, *page, total_pages))
6783            {
6784            TIFFError("writeRegions", "Unable to write new image");
6785            return (-1);
6786            }
6787          break;
6788     case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
6789          autoindex = 1;
6790          page_count = crop->selections;
6791          if (update_output_file (out, mp, autoindex, filename, page))
6792            return (1);
6793                 
6794          for (i = 0; i < crop->selections; i++)
6795            {
6796            crop_buff = seg_buffs[i].buffer;
6797            /* Write the current region to the current file */
6798            if (writeCroppedImage(in, *out, image, dump,
6799                                  crop->regionlist[i].width, 
6800                                  crop->regionlist[i].length, 
6801                                  crop_buff, *page, page_count))
6802              {
6803              TIFFError("writeRegions", "Unable to write new image");
6804              return (-1);
6805              }
6806            }
6807          break;
6808     case FILE_PER_SELECTION:
6809          autoindex = 1;
6810          page_count = 1;
6811          for (i = 0; i < crop->selections; i++)
6812            {
6813            if (update_output_file (out, mp, autoindex, filename, page))
6814              return (1);
6815
6816            crop_buff = seg_buffs[i].buffer;
6817            /* Write the current region to the current file */
6818            if (writeCroppedImage(in, *out, image, dump,
6819                                  crop->regionlist[i].width, 
6820                                  crop->regionlist[i].length, 
6821                                  crop_buff, *page, page_count))
6822              {
6823              TIFFError("writeRegions", "Unable to write new image");
6824              return (-1);
6825              }
6826            }
6827          break;
6828     default: return (1);
6829     }
6830
6831   return (0);
6832   } /* end writeRegions */
6833
6834 static int
6835 writeImageSections(TIFF *in, TIFF *out, struct image_data *image,
6836                    struct pagedef *page, struct pageseg *sections,
6837                    struct dump_opts * dump, unsigned char *src_buff,
6838                    unsigned char **sect_buff_ptr)
6839   {
6840   double  hres, vres;
6841   uint32  i, k, width, length, sectsize;
6842   unsigned char *sect_buff = *sect_buff_ptr;
6843
6844   hres = page->hres;
6845   vres = page->vres;
6846
6847   k = page->cols * page->rows;
6848   if ((k < 1) || (k > MAX_SECTIONS))
6849    {
6850    TIFFError("writeImageSections",
6851              "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
6852    return (-1);
6853    }
6854
6855   for (i = 0; i < k; i++)
6856     {
6857     width  = sections[i].x2 - sections[i].x1 + 1;
6858     length = sections[i].y2 - sections[i].y1 + 1;
6859     sectsize = (uint32)
6860             ceil((width * image->bps + 7) / (double)8) * image->spp * length;
6861     /* allocate a buffer if we don't have one already */
6862     if (createImageSection(sectsize, sect_buff_ptr))
6863       {
6864       TIFFError("writeImageSections", "Unable to allocate section buffer");
6865       exit (-1);
6866       }
6867     sect_buff = *sect_buff_ptr;
6868
6869     if (extractImageSection (image, &sections[i], src_buff, sect_buff))
6870       {
6871       TIFFError("writeImageSections", "Unable to extract image sections");
6872       exit (-1);
6873       }
6874
6875   /* call the write routine here instead of outside the loop */
6876     if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
6877       {
6878       TIFFError("writeImageSections", "Unable to write image section");
6879       exit (-1);
6880       }
6881     }
6882
6883   return (0);
6884   } /* end writeImageSections */
6885
6886 /* Code in this function is heavily indebted to code in tiffcp
6887  * with modifications by Richard Nolde to handle orientation correctly.
6888  * It will have to be updated significantly if support is added to
6889  * extract one or more samples from original image since the 
6890  * original code assumes we are always copying all samples.
6891  */
6892 static int  
6893 writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
6894                    struct dump_opts *dump, uint32 width, uint32 length,
6895                    double hres, double vres,
6896                    unsigned char *sect_buff)
6897   {
6898   uint16 bps, spp;
6899   uint16 input_compression, input_photometric;
6900   uint16 input_planar;
6901   struct cpTag* p;
6902
6903   /*  Calling this seems to reset the compression mode on the TIFF *in file.
6904   TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
6905   */
6906   input_compression = image->compression;
6907   input_photometric = image->photometric;
6908
6909   spp = image->spp;
6910   bps = image->bps;
6911   TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
6912   TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
6913   TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
6914   TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
6915
6916 #ifdef DEBUG2
6917   TIFFError("writeSingleSection", "Input compression: %s",
6918             (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
6919             ((input_compression == COMPRESSION_JPEG) ?  "New Jpeg" : "Non Jpeg"));
6920 #endif
6921   /* This is the global variable compression which is set 
6922    * if the user has specified a command line option for 
6923    * a compression option.  Should be passed around in one
6924    * of the parameters instead of as a global. If no user
6925    * option specified it will still be (uint16) -1. */
6926   if (compression != (uint16)-1)
6927     TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
6928   else
6929     { /* OJPEG is no longer supported for writing so upgrade to JPEG */
6930     if (input_compression == COMPRESSION_OJPEG)
6931       {
6932       compression = COMPRESSION_JPEG;
6933       jpegcolormode = JPEGCOLORMODE_RAW;
6934       TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
6935       }
6936     else /* Use the compression from the input file */
6937       TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
6938     }
6939
6940   if (compression == COMPRESSION_JPEG)
6941     {
6942     if ((input_photometric == PHOTOMETRIC_PALETTE) ||  /* color map indexed */
6943         (input_photometric == PHOTOMETRIC_MASK))       /* holdout mask */
6944       {
6945       TIFFError ("writeSingleSection",
6946                  "JPEG compression cannot be used with %s image data",
6947                  (input_photometric == PHOTOMETRIC_PALETTE) ?
6948                  "palette" : "mask");
6949       return (-1);
6950       }
6951     if ((input_photometric == PHOTOMETRIC_RGB) &&
6952         (jpegcolormode == JPEGCOLORMODE_RGB))
6953       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
6954     else
6955         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
6956     }
6957   else
6958     {
6959     if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
6960       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
6961                         PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
6962     else
6963       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
6964     }
6965
6966 #ifdef DEBUG2
6967   TIFFError("writeSingleSection", "Input photometric: %s",
6968             (input_photometric == PHOTOMETRIC_RGB) ? "RGB" :
6969             ((input_photometric == PHOTOMETRIC_YCBCR) ?  "YCbCr" : "Not RGB or YCbCr"));
6970 #endif
6971
6972   if (((input_photometric == PHOTOMETRIC_LOGL) ||
6973        (input_photometric ==  PHOTOMETRIC_LOGLUV)) &&
6974       ((compression != COMPRESSION_SGILOG) && 
6975        (compression != COMPRESSION_SGILOG24)))
6976     {
6977     TIFFError("writeSingleSection",
6978               "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
6979     return (-1);
6980     }
6981
6982   if (fillorder != 0)
6983     TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
6984   else
6985     CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
6986
6987   /* The loadimage function reads input orientation and sets
6988    * image->orientation. The correct_image_orientation function
6989    * applies the required rotation and mirror operations to 
6990    * present the data in TOPLEFT orientation and updates 
6991    * image->orientation if any transforms are performed, 
6992    * as per EXIF standard.
6993    */
6994   TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
6995
6996   /*
6997    * Choose tiles/strip for the output image according to
6998    * the command line arguments (-tiles, -strips) and the
6999    * structure of the input image.
7000    */
7001   if (outtiled == -1)
7002     outtiled = TIFFIsTiled(in);
7003   if (outtiled) {
7004     /*
7005      * Setup output file's tile width&height.  If either
7006      * is not specified, use either the value from the
7007      * input image or, if nothing is defined, use the
7008      * library default.
7009      */
7010     if (tilewidth == (uint32) 0)
7011       TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7012     if (tilelength == (uint32) 0)
7013       TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7014
7015     if (tilewidth == 0 || tilelength == 0)
7016       TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7017     TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7018     TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7019     TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7020     } else {
7021        /*
7022         * RowsPerStrip is left unspecified: use either the
7023         * value from the input image or, if nothing is defined,
7024         * use the library default.
7025         */
7026         if (rowsperstrip == (uint32) 0)
7027           {
7028           if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7029             rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7030           if (compression != COMPRESSION_JPEG)
7031             {
7032             if (rowsperstrip > length)
7033               rowsperstrip = length;
7034             }
7035           }
7036         else 
7037           if (rowsperstrip == (uint32) -1)
7038             rowsperstrip = length;
7039         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7040         }
7041
7042   TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7043   if (config != (uint16) -1)
7044     TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7045   else
7046     CopyField(TIFFTAG_PLANARCONFIG, config);
7047   if (spp <= 4)
7048     CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7049   CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7050
7051 /* SMinSampleValue & SMaxSampleValue */
7052   switch (compression) {
7053     /* These are references to GLOBAL variables set by defaults
7054      * and /or the compression flag
7055      */
7056     case COMPRESSION_JPEG:
7057          if (((bps % 8) == 0) || ((bps % 12) == 0))
7058            {
7059            TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7060            TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7061            }
7062          else
7063            {
7064            TIFFError("writeSingleSection",
7065                      "JPEG compression requires 8 or 12 bits per sample");
7066            return (-1);
7067            }
7068          break;
7069    case COMPRESSION_LZW:
7070    case COMPRESSION_ADOBE_DEFLATE:
7071    case COMPRESSION_DEFLATE:
7072         if (predictor != (uint16)-1)
7073           TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7074         else
7075           CopyField(TIFFTAG_PREDICTOR, predictor);
7076         break;
7077    case COMPRESSION_CCITTFAX3:
7078    case COMPRESSION_CCITTFAX4:
7079         if (compression == COMPRESSION_CCITTFAX3) {
7080           if (g3opts != (uint32) -1)
7081             TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7082           else
7083             CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7084         } else
7085             CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7086             CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7087             CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7088             CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7089             CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7090             CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7091             CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7092         break;
7093    }
7094    { uint32 len32;
7095      void** data;
7096      if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7097        TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7098    }
7099    { uint16 ninks;
7100      const char* inknames;
7101      if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7102        TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7103        if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7104          int inknameslen = strlen(inknames) + 1;
7105          const char* cp = inknames;
7106          while (ninks > 1) {
7107            cp = strchr(cp, '\0');
7108            if (cp) {
7109              cp++;
7110              inknameslen += (strlen(cp) + 1);
7111            }
7112            ninks--;
7113          }
7114          TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7115        }
7116      }
7117    }
7118    {
7119    unsigned short pg0, pg1;
7120    if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7121      if (pageNum < 0) /* only one input file */
7122         TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
7123      else 
7124         TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
7125      }
7126    }
7127
7128   for (p = tags; p < &tags[NTAGS]; p++)
7129                 CopyTag(p->tag, p->count, p->type);
7130
7131   /* Update these since they are overwritten from input res by loop above */
7132   TIFFSetField(out, TIFFTAG_XRESOLUTION, (float)hres);
7133   TIFFSetField(out, TIFFTAG_YRESOLUTION, (float)vres);
7134
7135   /* Compute the tile or strip dimensions and write to disk */
7136   if (outtiled)
7137     {
7138     if (config == PLANARCONFIG_CONTIG)
7139       writeBufferToContigTiles (out, sect_buff, length, width, spp, dump);
7140     else
7141       writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
7142     }
7143   else
7144     {
7145     if (config == PLANARCONFIG_CONTIG)
7146       writeBufferToContigStrips (out, sect_buff, length);
7147     else
7148       writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
7149     }
7150
7151   if (!TIFFWriteDirectory(out))
7152     {
7153     TIFFClose(out);
7154     return (-1);
7155     }
7156
7157   return (0);
7158   } /* end writeSingleSection */
7159
7160
7161 /* Create a buffer to write one section at a time */
7162 static int
7163 createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
7164   {
7165   unsigned  char *sect_buff = NULL;
7166   unsigned  char *new_buff  = NULL;
7167   static    uint32  prev_sectsize = 0;
7168   
7169   sect_buff = *sect_buff_ptr;
7170
7171   if (!sect_buff)
7172     {
7173     sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7174     *sect_buff_ptr = sect_buff;
7175     _TIFFmemset(sect_buff, 0, sectsize);
7176     }
7177   else
7178     {
7179     if (prev_sectsize < sectsize)
7180       {
7181       new_buff = _TIFFrealloc(sect_buff, sectsize);
7182       if (!new_buff)
7183         {
7184         free (sect_buff);
7185         sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7186         }
7187       else
7188         sect_buff = new_buff;
7189
7190       _TIFFmemset(sect_buff, 0, sectsize);
7191       }
7192     }
7193
7194   if (!sect_buff)
7195     {
7196     TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
7197     return (-1);
7198     }
7199   prev_sectsize = sectsize;
7200   *sect_buff_ptr = sect_buff;
7201
7202   return (0);
7203   }  /* end createImageSection */
7204
7205
7206 /* Process selections defined by regions, zones, margins, or fixed sized areas */
7207 static int
7208 processCropSelections(struct image_data *image, struct crop_mask *crop, 
7209                       unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
7210   {
7211   int       i;
7212   uint32    width, length, total_width, total_length;
7213   tsize_t   cropsize;
7214   unsigned  char *crop_buff = NULL;
7215   unsigned  char *read_buff = NULL;
7216   unsigned  char *next_buff = NULL;
7217   tsize_t   prev_cropsize = 0;
7218
7219   read_buff = *read_buff_ptr;
7220
7221   if (crop->img_mode == COMPOSITE_IMAGES)
7222     {
7223     cropsize = crop->bufftotal;
7224     crop_buff = seg_buffs[0].buffer; 
7225     if (!crop_buff)
7226       crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7227     else
7228       {
7229       prev_cropsize = seg_buffs[0].size;
7230       if (prev_cropsize < cropsize)
7231         {
7232         next_buff = _TIFFrealloc(crop_buff, cropsize);
7233         if (! next_buff)
7234           {
7235           _TIFFfree (crop_buff);
7236           crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7237           }
7238         else
7239           crop_buff = next_buff;
7240         }
7241       }
7242
7243     if (!crop_buff)
7244       {
7245       TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7246       return (-1);
7247       }
7248  
7249     _TIFFmemset(crop_buff, 0, cropsize);
7250     seg_buffs[0].buffer = crop_buff;
7251     seg_buffs[0].size = cropsize;
7252
7253     /* Checks for matching width or length as required */
7254     if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
7255       return (1);
7256
7257     if (crop->crop_mode & CROP_INVERT)
7258       {
7259       switch (crop->photometric)
7260         {
7261         /* Just change the interpretation */
7262         case PHOTOMETRIC_MINISWHITE:
7263         case PHOTOMETRIC_MINISBLACK:
7264              image->photometric = crop->photometric;
7265              break;
7266         case INVERT_DATA_ONLY:
7267         case INVERT_DATA_AND_TAG:
7268              if (invertImage(image->photometric, image->spp, image->bps, 
7269                              crop->combined_width, crop->combined_length, crop_buff))
7270                {
7271                TIFFError("processCropSelections", 
7272                          "Failed to invert colorspace for composite regions");
7273                return (-1);
7274                }
7275              if (crop->photometric == INVERT_DATA_AND_TAG)
7276                {
7277                switch (image->photometric)
7278                  {
7279                  case PHOTOMETRIC_MINISWHITE:
7280                       image->photometric = PHOTOMETRIC_MINISBLACK;
7281                       break;
7282                  case PHOTOMETRIC_MINISBLACK:
7283                       image->photometric = PHOTOMETRIC_MINISWHITE;
7284                       break;
7285                  default:
7286                       break;
7287                  }
7288                }
7289              break;
7290         default: break;
7291         }
7292       }
7293
7294     /* Mirror and Rotate will not work with multiple regions unless they are the same width */
7295     if (crop->crop_mode & CROP_MIRROR)
7296       {
7297       if (mirrorImage(image->spp, image->bps, crop->mirror, 
7298                       crop->combined_width, crop->combined_length, crop_buff))
7299         {
7300         TIFFError("processCropSelections", "Failed to mirror composite regions %s", 
7301                  (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7302         return (-1);
7303         }
7304       }
7305
7306     if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7307       {
7308       if (rotateImage(crop->rotation, image, &crop->combined_width, 
7309                       &crop->combined_length, &crop_buff))
7310         {
7311         TIFFError("processCropSelections", 
7312                   "Failed to rotate composite regions by %d degrees", crop->rotation);
7313         return (-1);
7314         }
7315       seg_buffs[0].buffer = crop_buff;
7316       seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
7317                             * image->spp) * crop->combined_length; 
7318       }
7319     }
7320   else  /* Separated Images */
7321     {
7322     total_width = total_length = 0;
7323     for (i = 0; i < crop->selections; i++)
7324       {
7325       cropsize = crop->bufftotal;
7326       crop_buff = seg_buffs[i].buffer; 
7327       if (!crop_buff)
7328         crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7329       else
7330         {
7331         prev_cropsize = seg_buffs[0].size;
7332         if (prev_cropsize < cropsize)
7333           {
7334           next_buff = _TIFFrealloc(crop_buff, cropsize);
7335           if (! next_buff)
7336             {
7337             _TIFFfree (crop_buff);
7338             crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7339             }
7340           else
7341             crop_buff = next_buff;
7342           }
7343         }
7344
7345       if (!crop_buff)
7346         {
7347         TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7348         return (-1);
7349         }
7350  
7351       _TIFFmemset(crop_buff, 0, cropsize);
7352       seg_buffs[i].buffer = crop_buff;
7353       seg_buffs[i].size = cropsize;
7354
7355       if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
7356         {
7357         TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
7358         return (-1);
7359         }
7360     
7361       width  = crop->regionlist[i].width;
7362       length = crop->regionlist[i].length;
7363
7364       if (crop->crop_mode & CROP_INVERT)
7365         {
7366         switch (crop->photometric)
7367           {
7368           /* Just change the interpretation */
7369           case PHOTOMETRIC_MINISWHITE:
7370           case PHOTOMETRIC_MINISBLACK:
7371                image->photometric = crop->photometric;
7372                break;
7373           case INVERT_DATA_ONLY:
7374           case INVERT_DATA_AND_TAG:
7375                if (invertImage(image->photometric, image->spp, image->bps, 
7376                                width, length, crop_buff))
7377                  {
7378                  TIFFError("processCropSelections", 
7379                            "Failed to invert colorspace for region");
7380                  return (-1);
7381                  }
7382                if (crop->photometric == INVERT_DATA_AND_TAG)
7383                  {
7384                  switch (image->photometric)
7385                    {
7386                    case PHOTOMETRIC_MINISWHITE:
7387                         image->photometric = PHOTOMETRIC_MINISBLACK;
7388                         break;
7389                    case PHOTOMETRIC_MINISBLACK:
7390                         image->photometric = PHOTOMETRIC_MINISWHITE;
7391                         break;
7392                    default:
7393                         break;
7394                    }
7395                  }
7396                break;
7397           default: break;
7398           }
7399         }
7400
7401       if (crop->crop_mode & CROP_MIRROR)
7402         {
7403         if (mirrorImage(image->spp, image->bps, crop->mirror, 
7404                         width, length, crop_buff))
7405           {
7406           TIFFError("processCropSelections", "Failed to mirror crop region %s", 
7407                    (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7408           return (-1);
7409           }
7410         }
7411
7412       if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7413         {
7414         if (rotateImage(crop->rotation, image, &crop->regionlist[i].width, 
7415                         &crop->regionlist[i].length, &crop_buff))
7416           {
7417           TIFFError("processCropSelections", 
7418                     "Failed to rotate crop region by %d degrees", crop->rotation);
7419           return (-1);
7420           }
7421         total_width  += crop->regionlist[i].width;
7422         total_length += crop->regionlist[i].length;
7423         crop->combined_width = total_width;
7424         crop->combined_length = total_length;
7425         seg_buffs[i].buffer = crop_buff;
7426         seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
7427                                * image->spp) * crop->regionlist[i].length; 
7428         }
7429       }
7430     }
7431   return (0);
7432   } /* end processCropSelections */
7433
7434 /* Copy the crop section of the data from the current image into a buffer
7435  * and adjust the IFD values to reflect the new size. If no cropping is
7436  * required, use the origial read buffer as the crop buffer.
7437  *
7438  * There is quite a bit of redundancy between this routine and the more
7439  * specialized processCropSelections, but this provides
7440  * the most optimized path when no Zones or Regions are required.
7441  */
7442 static int
7443 createCroppedImage(struct image_data *image, struct crop_mask *crop, 
7444                    unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
7445   {
7446   tsize_t   cropsize;
7447   unsigned  char *read_buff = NULL;
7448   unsigned  char *crop_buff = NULL;
7449   unsigned  char *new_buff  = NULL;
7450   static    tsize_t  prev_cropsize = 0;
7451
7452   read_buff = *read_buff_ptr;
7453
7454   /* process full image, no crop buffer needed */
7455   crop_buff = read_buff;
7456   *crop_buff_ptr = read_buff;
7457   crop->combined_width = image->width;
7458   crop->combined_length = image->length;
7459
7460   cropsize = crop->bufftotal;
7461   crop_buff = *crop_buff_ptr;
7462   if (!crop_buff)
7463     {
7464     crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7465     *crop_buff_ptr = crop_buff;
7466     _TIFFmemset(crop_buff, 0, cropsize);
7467     prev_cropsize = cropsize;
7468     }
7469   else
7470     {
7471     if (prev_cropsize < cropsize)
7472       {
7473       new_buff = _TIFFrealloc(crop_buff, cropsize);
7474       if (!new_buff)
7475         {
7476         free (crop_buff);
7477         crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7478         }
7479       else
7480         crop_buff = new_buff;
7481       _TIFFmemset(crop_buff, 0, cropsize);
7482       }
7483     }
7484
7485   if (!crop_buff)
7486     {
7487     TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
7488     return (-1);
7489     }
7490   *crop_buff_ptr = crop_buff;
7491
7492   if (crop->crop_mode & CROP_INVERT)
7493     {
7494     switch (crop->photometric)
7495       {
7496       /* Just change the interpretation */
7497       case PHOTOMETRIC_MINISWHITE:
7498       case PHOTOMETRIC_MINISBLACK:
7499            image->photometric = crop->photometric;
7500            break;
7501       case INVERT_DATA_ONLY:
7502       case INVERT_DATA_AND_TAG:
7503            if (invertImage(image->photometric, image->spp, image->bps, 
7504                            crop->combined_width, crop->combined_length, crop_buff))
7505              {
7506              TIFFError("createCroppedImage", 
7507                        "Failed to invert colorspace for image or cropped selection");
7508              return (-1);
7509              }
7510            if (crop->photometric == INVERT_DATA_AND_TAG)
7511              {
7512              switch (image->photometric)
7513                {
7514                case PHOTOMETRIC_MINISWHITE:
7515                     image->photometric = PHOTOMETRIC_MINISBLACK;
7516                     break;
7517                case PHOTOMETRIC_MINISBLACK:
7518                     image->photometric = PHOTOMETRIC_MINISWHITE;
7519                     break;
7520                default:
7521                     break;
7522                }
7523              }
7524            break;
7525       default: break;
7526       }
7527     }
7528
7529   if (crop->crop_mode & CROP_MIRROR)
7530     {
7531     if (mirrorImage(image->spp, image->bps, crop->mirror, 
7532                     crop->combined_width, crop->combined_length, crop_buff))
7533       {
7534       TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s", 
7535                (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7536       return (-1);
7537       }
7538     }
7539
7540   if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7541     {
7542     if (rotateImage(crop->rotation, image, &crop->combined_width, 
7543                     &crop->combined_length, crop_buff_ptr))
7544       {
7545       TIFFError("createCroppedImage", 
7546                 "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
7547       return (-1);
7548       }
7549     }
7550
7551   if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
7552     *read_buff_ptr = NULL;    /* so we don't try to free it later */
7553
7554   return (0);
7555   } /* end createCroppedImage */
7556
7557
7558 /* Code in this function is heavily indebted to code in tiffcp
7559  * with modifications by Richard Nolde to handle orientation correctly.
7560  * It will have to be updated significantly if support is added to
7561  * extract one or more samples from original image since the 
7562  * original code assumes we are always copying all samples.
7563  * Use of global variables for config, compression and others
7564  * should be replaced by addition to the crop_mask struct (which
7565  * will be renamed to proc_opts indicating that is controlls
7566  * user supplied processing options, not just cropping) and 
7567  * then passed in as an argument.
7568  */
7569 static int  
7570 writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image, 
7571                   struct dump_opts *dump, uint32 width, uint32 length, 
7572                   unsigned char *crop_buff, int pagenum, int total_pages)
7573   {
7574   uint16 bps, spp;
7575   uint16 input_compression, input_photometric;
7576   uint16 input_planar;
7577   struct cpTag* p;
7578
7579   input_compression = image->compression;
7580   input_photometric = image->photometric;
7581   spp = image->spp;
7582   bps = image->bps;
7583
7584   TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
7585   TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
7586   TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
7587   TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
7588
7589 #ifdef DEBUG2
7590   TIFFError("writeCroppedImage", "Input compression: %s",
7591             (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
7592             ((input_compression == COMPRESSION_JPEG) ?  "New Jpeg" : "Non Jpeg"));
7593 #endif
7594
7595   if (compression != (uint16)-1)
7596     TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
7597   else
7598     {
7599     if (input_compression == COMPRESSION_OJPEG)
7600       {
7601       compression = COMPRESSION_JPEG;
7602       jpegcolormode = JPEGCOLORMODE_RAW;
7603       TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
7604       }
7605     else
7606       CopyField(TIFFTAG_COMPRESSION, compression);
7607     }
7608
7609   if (compression == COMPRESSION_JPEG)
7610     {
7611     if ((input_photometric == PHOTOMETRIC_PALETTE) ||  /* color map indexed */
7612         (input_photometric == PHOTOMETRIC_MASK))       /* $holdout mask */
7613       {
7614       TIFFError ("writeCroppedImage",
7615                  "JPEG compression cannot be used with %s image data",
7616                 (input_photometric == PHOTOMETRIC_PALETTE) ?
7617                  "palette" : "mask");
7618       return (-1);
7619       }
7620     if ((input_photometric == PHOTOMETRIC_RGB) &&
7621         (jpegcolormode == JPEGCOLORMODE_RGB))
7622       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
7623     else
7624         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
7625     }
7626   else
7627     {
7628     if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
7629       {
7630       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7631                         PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7632       }
7633     else
7634       {
7635       if (input_compression == COMPRESSION_SGILOG ||
7636           input_compression == COMPRESSION_SGILOG24)
7637         {
7638         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7639                           PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7640         }
7641       else
7642         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
7643       }
7644     }
7645
7646   if (((input_photometric == PHOTOMETRIC_LOGL) ||
7647        (input_photometric ==  PHOTOMETRIC_LOGLUV)) &&
7648       ((compression != COMPRESSION_SGILOG) && 
7649        (compression != COMPRESSION_SGILOG24)))
7650     {
7651     TIFFError("writeCroppedImage",
7652               "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
7653     return (-1);
7654     }
7655
7656   if (fillorder != 0)
7657     TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
7658   else
7659     CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
7660
7661   /* The loadimage function reads input orientation and sets
7662    * image->orientation. The correct_image_orientation function
7663    * applies the required rotation and mirror operations to 
7664    * present the data in TOPLEFT orientation and updates 
7665    * image->orientation if any transforms are performed, 
7666    * as per EXIF standard. 
7667    */
7668   TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
7669         
7670   /*
7671    * Choose tiles/strip for the output image according to
7672    * the command line arguments (-tiles, -strips) and the
7673    * structure of the input image.
7674    */
7675   if (outtiled == -1)
7676     outtiled = TIFFIsTiled(in);
7677   if (outtiled) {
7678     /*
7679      * Setup output file's tile width&height.  If either
7680      * is not specified, use either the value from the
7681      * input image or, if nothing is defined, use the
7682      * library default.
7683      */
7684     if (tilewidth == (uint32) 0)
7685       TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7686     if (tilelength == (uint32) 0)
7687       TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7688
7689     if (tilewidth == 0 || tilelength == 0)
7690       TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7691     TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7692     TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7693     } else {
7694        /*
7695         * RowsPerStrip is left unspecified: use either the
7696         * value from the input image or, if nothing is defined,
7697         * use the library default.
7698         */
7699         if (rowsperstrip == (uint32) 0)
7700           {
7701           if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7702             rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7703           if (compression != COMPRESSION_JPEG)
7704             {
7705             if (rowsperstrip > length)
7706               rowsperstrip = length;
7707             }
7708           }
7709         else 
7710           if (rowsperstrip == (uint32) -1)
7711             rowsperstrip = length;
7712         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7713         }
7714
7715   TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7716   if (config != (uint16) -1)
7717     TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7718   else
7719     CopyField(TIFFTAG_PLANARCONFIG, config);
7720   if (spp <= 4)
7721     CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7722   CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7723
7724 /* SMinSampleValue & SMaxSampleValue */
7725   switch (compression) {
7726     case COMPRESSION_JPEG:
7727          if (((bps % 8) == 0) || ((bps % 12) == 0))
7728            {
7729            TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7730            TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7731            }
7732          else
7733            {
7734            TIFFError("writeCroppedImage",
7735                      "JPEG compression requires 8 or 12 bits per sample");
7736            return (-1);
7737            }
7738          break;
7739    case COMPRESSION_LZW:
7740    case COMPRESSION_ADOBE_DEFLATE:
7741    case COMPRESSION_DEFLATE:
7742         if (predictor != (uint16)-1)
7743           TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7744         else
7745           CopyField(TIFFTAG_PREDICTOR, predictor);
7746         break;
7747    case COMPRESSION_CCITTFAX3:
7748    case COMPRESSION_CCITTFAX4:
7749         if (bps != 1)
7750           {
7751           TIFFError("writeCroppedImage",
7752             "Group 3/4 compression is not usable with bps > 1");
7753           return (-1);
7754           }
7755         if (compression == COMPRESSION_CCITTFAX3) {
7756           if (g3opts != (uint32) -1)
7757             TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7758           else
7759             CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7760         } else
7761             CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7762             CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7763             CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7764             CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7765             CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7766             CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7767             CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7768          break;
7769     case COMPRESSION_NONE:
7770          break;
7771     default: break;
7772    }
7773    { uint32 len32;
7774      void** data;
7775      if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7776        TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7777    }
7778    { uint16 ninks;
7779      const char* inknames;
7780      if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7781        TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7782        if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7783          int inknameslen = strlen(inknames) + 1;
7784          const char* cp = inknames;
7785          while (ninks > 1) {
7786            cp = strchr(cp, '\0');
7787            if (cp) {
7788              cp++;
7789              inknameslen += (strlen(cp) + 1);
7790            }
7791            ninks--;
7792          }
7793          TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7794        }
7795      }
7796    }
7797    {
7798    unsigned short pg0, pg1;
7799    if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7800      TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
7801      }
7802    }
7803
7804   for (p = tags; p < &tags[NTAGS]; p++)
7805                 CopyTag(p->tag, p->count, p->type);
7806
7807   /* Compute the tile or strip dimensions and write to disk */
7808   if (outtiled)
7809     {
7810     if (config == PLANARCONFIG_CONTIG)
7811       {
7812       if (writeBufferToContigTiles (out, crop_buff, length, width, spp, dump))
7813         TIFFError("","Unable to write contiguous tile data for page %d", pagenum);
7814       }
7815     else
7816       {
7817       if (writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump))
7818         TIFFError("","Unable to write separate tile data for page %d", pagenum);
7819       }
7820     }
7821   else
7822     {
7823     if (config == PLANARCONFIG_CONTIG)
7824       {
7825       if (writeBufferToContigStrips (out, crop_buff, length))
7826         TIFFError("","Unable to write contiguous strip data for page %d", pagenum);
7827       }
7828     else
7829       {
7830       if (writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump))
7831         TIFFError("","Unable to write separate strip data for page %d", pagenum);
7832       }
7833     }
7834
7835   if (!TIFFWriteDirectory(out))
7836     {
7837     TIFFError("","Failed to write IFD for page number %d", pagenum);
7838     TIFFClose(out);
7839     return (-1);
7840     }
7841
7842   return (0);
7843   } /* end writeCroppedImage */
7844
7845 static int
7846 rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
7847                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
7848   {
7849   int      ready_bits = 0;
7850   uint32   src_byte = 0, src_bit = 0;
7851   uint32   row, rowsize = 0, bit_offset = 0;
7852   uint8    matchbits = 0, maskbits = 0;
7853   uint8    buff1 = 0, buff2 = 0;
7854   uint8   *next;
7855   tsample_t sample;
7856
7857   if ((src == NULL) || (dst == NULL))
7858     {
7859     TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
7860     return (1);
7861     }
7862
7863   rowsize = ((bps * spp * width) + 7) / 8;
7864   ready_bits = 0;
7865   maskbits =  (uint8)-1 >> ( 8 - bps);
7866   buff1 = buff2 = 0;
7867
7868   for (row = 0; row < length ; row++)
7869     {
7870     bit_offset = col * bps * spp;
7871     for (sample = 0; sample < spp; sample++)
7872       {
7873       if (sample == 0)
7874         {
7875         src_byte = bit_offset / 8;
7876         src_bit  = bit_offset % 8;
7877         }
7878       else
7879         {
7880         src_byte = (bit_offset + (sample * bps)) / 8;
7881         src_bit  = (bit_offset + (sample * bps)) % 8;
7882         }
7883
7884       switch (rotation)
7885         {
7886         case  90: next = src + src_byte - (row * rowsize);
7887                   break;
7888         case 270: next = src + src_byte + (row * rowsize);
7889                   break;
7890         default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
7891                   return (1);
7892         }
7893       matchbits = maskbits << (8 - src_bit - bps); 
7894       buff1 = ((*next) & matchbits) << (src_bit);
7895
7896        /* If we have a full buffer's worth, write it out */
7897       if (ready_bits >= 8)
7898         {
7899         *dst++ = buff2;
7900         buff2 = buff1;
7901         ready_bits -= 8;
7902         }
7903       else
7904         {
7905         buff2 = (buff2 | (buff1 >> ready_bits));
7906         }
7907       ready_bits += bps;
7908       }
7909     }
7910
7911   if (ready_bits > 0)
7912     {
7913     buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
7914     *dst++ = buff1;
7915     }
7916
7917   return (0);
7918   }  /* end rotateContigSamples8bits */
7919
7920
7921 static int
7922 rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
7923                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
7924   {
7925   int      ready_bits = 0;
7926   uint32   row, rowsize, bit_offset;
7927   uint32   src_byte = 0, src_bit = 0;
7928   uint16   matchbits = 0, maskbits = 0;
7929   uint16   buff1 = 0, buff2 = 0;
7930   uint8    bytebuff = 0;
7931   uint8   *next;
7932   tsample_t sample;
7933
7934   if ((src == NULL) || (dst == NULL))
7935     {
7936     TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
7937     return (1);
7938     }
7939
7940   rowsize = ((bps * spp * width) + 7) / 8;
7941   ready_bits = 0;
7942   maskbits =  (uint16)-1 >> (16 - bps);
7943   buff1 = buff2 = 0;
7944   for (row = 0; row < length; row++)
7945     {
7946     bit_offset = col * bps * spp;
7947     for (sample = 0; sample < spp; sample++)
7948       {
7949       if (sample == 0)
7950         {
7951         src_byte = bit_offset / 8;
7952         src_bit  = bit_offset % 8;
7953         }
7954       else
7955         {
7956         src_byte = (bit_offset + (sample * bps)) / 8;
7957         src_bit  = (bit_offset + (sample * bps)) % 8;
7958         }
7959
7960       switch (rotation)
7961         {
7962         case  90: next = src + src_byte - (row * rowsize);
7963                   break;
7964         case 270: next = src + src_byte + (row * rowsize);
7965                   break;
7966         default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
7967                   return (1);
7968         }
7969       matchbits = maskbits << (16 - src_bit - bps); 
7970       if (little_endian)
7971         buff1 = (next[0] << 8) | next[1];
7972       else
7973         buff1 = (next[1] << 8) | next[0];
7974
7975       buff1 = (buff1 & matchbits) << (src_bit);
7976
7977       /* If we have a full buffer's worth, write it out */
7978       if (ready_bits >= 8)
7979         {
7980         bytebuff = (buff2 >> 8);
7981         *dst++ = bytebuff;
7982         ready_bits -= 8;
7983         /* shift in new bits */
7984         buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
7985         }
7986       else
7987         { /* add another bps bits to the buffer */
7988         bytebuff = 0;
7989         buff2 = (buff2 | (buff1 >> ready_bits));
7990         }
7991       ready_bits += bps;
7992       }
7993     }
7994
7995   if (ready_bits > 0)
7996     {
7997     bytebuff = (buff2 >> 8);
7998     *dst++ = bytebuff;
7999     }
8000
8001   return (0);
8002   }  /* end rotateContigSamples16bits */
8003
8004 static int
8005 rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
8006                           uint32 length,   uint32 col, uint8 *src, uint8 *dst)
8007   {
8008   int      ready_bits = 0;
8009   uint32   row, rowsize, bit_offset;
8010   uint32   src_byte = 0, src_bit = 0;
8011   uint32   matchbits = 0, maskbits = 0;
8012   uint32   buff1 = 0, buff2 = 0;
8013   uint8    bytebuff1 = 0, bytebuff2 = 0;
8014   uint8   *next;
8015   tsample_t sample;
8016
8017
8018   if ((src == NULL) || (dst == NULL))
8019     {
8020     TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8021     return (1);
8022     }
8023
8024   rowsize = ((bps * spp * width) + 7) / 8;
8025   ready_bits = 0;
8026   maskbits =  (uint32)-1 >> (32 - bps);
8027   buff1 = buff2 = 0;
8028   for (row = 0; row < length; row++)
8029     {
8030     bit_offset = col * bps * spp;
8031     for (sample = 0; sample < spp; sample++)
8032       {
8033       if (sample == 0)
8034         {
8035         src_byte = bit_offset / 8;
8036         src_bit  = bit_offset % 8;
8037         }
8038       else
8039         {
8040         src_byte = (bit_offset + (sample * bps)) / 8;
8041         src_bit  = (bit_offset + (sample * bps)) % 8;
8042         }
8043
8044       switch (rotation)
8045         {
8046         case  90: next = src + src_byte - (row * rowsize);
8047                   break;
8048         case 270: next = src + src_byte + (row * rowsize);
8049                   break;
8050         default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8051                   return (1);
8052         }
8053       matchbits = maskbits << (32 - src_bit - bps); 
8054       if (little_endian)
8055         buff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8056       else
8057         buff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8058       buff1 = (buff1 & matchbits) << (src_bit);
8059
8060       /* If we have a full buffer's worth, write it out */
8061       if (ready_bits >= 16)
8062         {
8063         bytebuff1 = (buff2 >> 24);
8064         *dst++ = bytebuff1;
8065         bytebuff2 = (buff2 >> 16);
8066         *dst++ = bytebuff2;
8067         ready_bits -= 16;
8068
8069         /* shift in new bits */
8070         buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8071         }
8072       else
8073         { /* add another bps bits to the buffer */
8074         bytebuff1 = bytebuff2 = 0;
8075         buff2 = (buff2 | (buff1 >> ready_bits));
8076         }
8077       ready_bits += bps;
8078       }
8079     }
8080
8081  /* catch any trailing bits at the end of the line */
8082   while (ready_bits > 0)
8083     {
8084     bytebuff1 = (buff2 >> 24);
8085     *dst++ = bytebuff1;
8086
8087     buff2 = (buff2 << 8);
8088     bytebuff2 = bytebuff1;
8089     ready_bits -= 8;
8090     }
8091  
8092   return (0);
8093   }  /* end rotateContigSamples24bits */
8094
8095 static int
8096 rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
8097                           uint32 length,   uint32 col, uint8 *src, uint8 *dst)
8098   {
8099   int    ready_bits = 0, shift_width = 0;
8100   int    bytes_per_sample, bytes_per_pixel;
8101   uint32 row, rowsize, bit_offset;
8102   uint32 src_byte, src_bit;
8103   uint32 longbuff1 = 0, longbuff2 = 0;
8104   uint64 maskbits = 0, matchbits = 0;
8105   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8106   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8107   uint8   *next;
8108   tsample_t sample;
8109
8110
8111   if ((src == NULL) || (dst == NULL))
8112     {
8113     TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8114     return (1);
8115     }
8116
8117   bytes_per_sample = (bps + 7) / 8;
8118   bytes_per_pixel  = ((bps * spp) + 7) / 8;
8119   if (bytes_per_pixel < (bytes_per_sample + 1))
8120     shift_width = bytes_per_pixel;
8121   else
8122     shift_width = bytes_per_sample + 1;
8123
8124   rowsize = ((bps * spp * width) + 7) / 8;
8125   ready_bits = 0;
8126   maskbits =  (uint64)-1 >> (64 - bps);
8127   buff1 = buff2 = 0;
8128   for (row = 0; row < length; row++)
8129     {
8130     bit_offset = col * bps * spp;
8131     for (sample = 0; sample < spp; sample++)
8132       {
8133       if (sample == 0)
8134         {
8135         src_byte = bit_offset / 8;
8136         src_bit  = bit_offset % 8;
8137         }
8138       else
8139         {
8140         src_byte = (bit_offset + (sample * bps)) / 8;
8141         src_bit  = (bit_offset + (sample * bps)) % 8;
8142         }
8143
8144       switch (rotation)
8145         {
8146         case  90: next = src + src_byte - (row * rowsize);
8147                   break;
8148         case 270: next = src + src_byte + (row * rowsize);
8149                   break;
8150         default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8151                   return (1);
8152         }
8153       matchbits = maskbits << (64 - src_bit - bps); 
8154       if (little_endian)
8155         {
8156         longbuff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8157         longbuff2 = longbuff1;
8158         }
8159       else
8160         {
8161         longbuff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8162         longbuff2 = longbuff1;
8163         }
8164
8165       buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8166       buff1 = (buff3 & matchbits) << (src_bit);
8167
8168       if (ready_bits < 32)
8169         { /* add another bps bits to the buffer */
8170         bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8171         buff2 = (buff2 | (buff1 >> ready_bits));
8172         }
8173       else /* If we have a full buffer's worth, write it out */
8174         {
8175         bytebuff1 = (buff2 >> 56);
8176         *dst++ = bytebuff1;
8177         bytebuff2 = (buff2 >> 48);
8178         *dst++ = bytebuff2;
8179         bytebuff3 = (buff2 >> 40);
8180         *dst++ = bytebuff3;
8181         bytebuff4 = (buff2 >> 32);
8182         *dst++ = bytebuff4;
8183         ready_bits -= 32;
8184                     
8185         /* shift in new bits */
8186         buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8187         }
8188       ready_bits += bps;
8189       }
8190     }
8191   while (ready_bits > 0)
8192     {
8193     bytebuff1 = (buff2 >> 56);
8194     *dst++ = bytebuff1;
8195     buff2 = (buff2 << 8);
8196     ready_bits -= 8;
8197     }
8198
8199   return (0);
8200   } /* end rotateContigSamples32bits */
8201
8202
8203 /* Rotate an image by a multiple of 90 degrees clockwise */
8204 static int
8205 rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, 
8206             uint32 *img_length, unsigned char **ibuff_ptr)
8207   {
8208   int      shift_width;
8209   uint32   bytes_per_pixel, bytes_per_sample;
8210   uint32   row, rowsize, src_offset, dst_offset;
8211   uint32   i, col, width, length;
8212   uint32   colsize, buffsize, col_offset, pix_offset;
8213   unsigned char *ibuff;
8214   unsigned char *src;
8215   unsigned char *dst;
8216   uint16   spp, bps;
8217   float    res_temp;
8218   unsigned char *rbuff = NULL;
8219
8220   width  = *img_width;
8221   length = *img_length;
8222   spp = image->spp;
8223   bps = image->bps;
8224
8225   rowsize = ((bps * spp * width) + 7) / 8;
8226   colsize = ((bps * spp * length) + 7) / 8;
8227   if ((colsize * width) > (rowsize * length))
8228     buffsize = (colsize + 1) * width;
8229   else
8230     buffsize = (rowsize + 1) * length;
8231
8232   bytes_per_sample = (bps + 7) / 8;
8233   bytes_per_pixel  = ((bps * spp) + 7) / 8;
8234   if (bytes_per_pixel < (bytes_per_sample + 1))
8235     shift_width = bytes_per_pixel;
8236   else
8237     shift_width = bytes_per_sample + 1;
8238
8239   switch (rotation)
8240     {
8241     case 0:
8242     case 360: return (0);
8243     case 90:
8244     case 180:
8245     case 270: break;
8246     default:  TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
8247               return (-1);
8248     }
8249
8250   if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
8251     {
8252     TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
8253     return (-1);
8254     }
8255   _TIFFmemset(rbuff, '\0', buffsize);
8256
8257   ibuff = *ibuff_ptr;
8258   switch (rotation)
8259     {
8260     case 180: if ((bps % 8) == 0) /* byte alligned data */
8261                 { 
8262                 src = ibuff;
8263                 pix_offset = (spp * bps) / 8;
8264                 for (row = 0; row < length; row++)
8265                    {
8266                    dst_offset = (length - row - 1) * rowsize;
8267                    for (col = 0; col < width; col++)
8268                      { 
8269                      col_offset = (width - col - 1) * pix_offset;
8270                      dst = rbuff + dst_offset + col_offset;
8271
8272                      for (i = 0; i  < bytes_per_pixel; i++)
8273                        *dst++ = *src++;
8274                      }
8275                    }
8276                 }
8277               else
8278                 { /* non 8 bit per sample data */ 
8279                 for (row = 0; row < length; row++)
8280                   {
8281                   src_offset = row * rowsize;
8282                   dst_offset = (length - row - 1) * rowsize;
8283                   src = ibuff + src_offset;
8284                   dst = rbuff + dst_offset;
8285                   switch (shift_width)
8286                     {
8287                     case 1: if (bps == 1)
8288                               {
8289                               if (reverseSamples8bits(spp, bps, width, src, dst))
8290                                 {
8291                                 _TIFFfree(rbuff);
8292                                 return (-1);
8293                                 }
8294                               break;
8295                               }
8296                             if (reverseSamples16bits(spp, bps, width, src, dst))
8297                               {
8298                               _TIFFfree(rbuff);
8299                               return (-1);
8300                               }
8301                              break;
8302                     case 2: if (reverseSamples24bits(spp, bps, width, src, dst))
8303                               {
8304                               _TIFFfree(rbuff);
8305                               return (-1);
8306                               }
8307                              break;
8308                     case 3: 
8309                     case 4: 
8310                     case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
8311                               {
8312                               _TIFFfree(rbuff);
8313                               return (-1);
8314                               }
8315                              break;
8316                     default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8317                              _TIFFfree(rbuff);
8318                              return (-1);      
8319                     }
8320                   }
8321                 }
8322               _TIFFfree(ibuff);
8323               *(ibuff_ptr) = rbuff;
8324               break;
8325
8326     case 90:  if ((bps % 8) == 0) /* byte aligned data */
8327                 {
8328                 for (col = 0; col < width; col++)
8329                   {
8330                   src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
8331                   dst_offset = col * colsize;
8332                   src = ibuff + src_offset;
8333                   dst = rbuff + dst_offset;
8334                   for (row = length; row > 0; row--)
8335                     {
8336                     for (i = 0; i < bytes_per_pixel; i++)
8337                       *dst++ = *(src + i);
8338                     src -= rowsize;
8339                     }
8340                   }
8341                 }
8342               else
8343                 { /* non 8 bit per sample data */ 
8344                 for (col = 0; col < width; col++)
8345                   {
8346                   src_offset = (length - 1) * rowsize;
8347                   dst_offset = col * colsize;
8348                   src = ibuff + src_offset;
8349                   dst = rbuff + dst_offset;
8350                   switch (shift_width)
8351                     {
8352                     case 1: if (bps == 1)
8353                               {
8354                               if (rotateContigSamples8bits(rotation, spp, bps, width, 
8355                                                          length, col, src, dst))
8356                                 {
8357                                 _TIFFfree(rbuff);
8358                                 return (-1);
8359                                 }
8360                               break;
8361                               }
8362                             if (rotateContigSamples16bits(rotation, spp, bps, width, 
8363                                                          length, col, src, dst))
8364                               {
8365                               _TIFFfree(rbuff);
8366                               return (-1);
8367                               }
8368                             break;
8369                     case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
8370                                                           length, col, src, dst))
8371                               {
8372                               _TIFFfree(rbuff);
8373                               return (-1);
8374                               }
8375                              break;
8376                     case 3: 
8377                     case 4: 
8378                     case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
8379                                                           length, col, src, dst))
8380                               {
8381                               _TIFFfree(rbuff);
8382                               return (-1);
8383                               }
8384                              break;
8385                     default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8386                              _TIFFfree(rbuff);
8387                              return (-1);      
8388                     }
8389                   }
8390                 }
8391               _TIFFfree(ibuff);
8392               *(ibuff_ptr) = rbuff;
8393
8394               *img_width = length;
8395               *img_length = width;
8396               image->width = length;
8397               image->length = width;
8398               res_temp = image->xres;
8399               image->xres = image->yres;
8400               image->yres = res_temp;
8401               break;
8402
8403     case 270: if ((bps % 8) == 0) /* byte aligned data */
8404                 {
8405                 for (col = 0; col < width; col++)
8406                   {
8407                   src_offset = col * bytes_per_pixel;
8408                   dst_offset = (width - col - 1) * colsize;
8409                   src = ibuff + src_offset;
8410                   dst = rbuff + dst_offset;
8411                   for (row = length; row > 0; row--)
8412                     {
8413                     for (i = 0; i < bytes_per_pixel; i++)
8414                       *dst++ = *(src + i);
8415                     src += rowsize;
8416                     }
8417                   }
8418                 }
8419               else
8420                 { /* non 8 bit per sample data */ 
8421                 for (col = 0; col < width; col++)
8422                   {
8423                   src_offset = 0;
8424                   dst_offset = (width - col - 1) * colsize;
8425                   src = ibuff + src_offset;
8426                   dst = rbuff + dst_offset;
8427                   switch (shift_width)
8428                     {
8429                     case 1: if (bps == 1)
8430                               {
8431                               if (rotateContigSamples8bits(rotation, spp, bps, width, 
8432                                                          length, col, src, dst))
8433                                 {
8434                                 _TIFFfree(rbuff);
8435                                 return (-1);
8436                                 }
8437                               break;
8438                               }
8439                             if (rotateContigSamples16bits(rotation, spp, bps, width, 
8440                                                          length, col, src, dst))
8441                               {
8442                               _TIFFfree(rbuff);
8443                               return (-1);
8444                               }
8445                             break;
8446                     case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
8447                                                           length, col, src, dst))
8448                               {
8449                               _TIFFfree(rbuff);
8450                               return (-1);
8451                               }
8452                              break;
8453                     case 3: 
8454                     case 4: 
8455                     case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
8456                                                           length, col, src, dst))
8457                               {
8458                               _TIFFfree(rbuff);
8459                               return (-1);
8460                               }
8461                              break;
8462                     default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8463                              _TIFFfree(rbuff);
8464                              return (-1);      
8465                     }
8466                   }
8467                 }
8468               _TIFFfree(ibuff);
8469               *(ibuff_ptr) = rbuff;
8470
8471               *img_width = length;
8472               *img_length = width;
8473               image->width = length;
8474               image->length = width;
8475               res_temp = image->xres;
8476               image->xres = image->yres;
8477               image->yres = res_temp;
8478               break;
8479     default:
8480               break;
8481     }
8482
8483   return (0);
8484   } /* end rotateImage */
8485
8486 static int
8487 reverseSamples8bits (uint16 spp, uint16 bps, uint32 width, 
8488                      uint8 *ibuff, uint8 *obuff)
8489   {
8490   int      ready_bits = 0;
8491   uint32   col;
8492   uint32   src_byte, src_bit;
8493   uint32   bit_offset = 0;
8494   uint8    match_bits = 0, mask_bits = 0;
8495   uint8    buff1 = 0, buff2 = 0;
8496   unsigned char *src;
8497   unsigned char *dst;
8498   tsample_t sample;
8499
8500   if ((ibuff == NULL) || (obuff == NULL))
8501     {
8502     TIFFError("reverseSamples8bits","Invalid image or work buffer");
8503     return (1);
8504     }
8505
8506   ready_bits = 0;
8507   mask_bits =  (uint8)-1 >> ( 8 - bps);
8508   dst = obuff;
8509   for (col = width; col > 0; col--)
8510     {
8511     /* Compute src byte(s) and bits within byte(s) */
8512     bit_offset = (col - 1) * bps * spp;
8513     for (sample = 0; sample < spp; sample++)
8514       {
8515       if (sample == 0)
8516         {
8517         src_byte = bit_offset / 8;
8518         src_bit  = bit_offset % 8;
8519         }
8520       else
8521         {
8522         src_byte = (bit_offset + (sample * bps)) / 8;
8523         src_bit  = (bit_offset + (sample * bps)) % 8;
8524         }
8525
8526       src = ibuff + src_byte;
8527       match_bits = mask_bits << (8 - src_bit - bps); 
8528       buff1 = ((*src) & match_bits) << (src_bit);
8529
8530       if (ready_bits < 8)
8531         buff2 = (buff2 | (buff1 >> ready_bits));
8532       else  /* If we have a full buffer's worth, write it out */
8533         {
8534         *dst++ = buff2;
8535         buff2 = buff1;
8536         ready_bits -= 8;
8537         }
8538       ready_bits += bps;
8539       }
8540     }
8541   if (ready_bits > 0)
8542     {
8543     buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
8544     *dst++ = buff1;
8545     }
8546
8547   return (0);
8548   } /* end reverseSamples8bits */
8549
8550
8551 static int
8552 reverseSamples16bits (uint16 spp, uint16 bps, uint32 width, 
8553                       uint8 *ibuff, uint8 *obuff)
8554   {
8555   int      ready_bits = 0;
8556   uint32   col;
8557   uint32   src_byte = 0, high_bit = 0;
8558   uint32   bit_offset = 0;
8559   uint16   match_bits = 0, mask_bits = 0;
8560   uint16   buff1 = 0, buff2 = 0;
8561   uint8    bytebuff = 0;
8562   unsigned char *src;
8563   unsigned char *dst;
8564   tsample_t sample;
8565
8566   if ((ibuff == NULL) || (obuff == NULL))
8567     {
8568     TIFFError("reverseSample16bits","Invalid image or work buffer");
8569     return (1);
8570     }
8571
8572   ready_bits = 0;
8573   mask_bits =  (uint16)-1 >> (16 - bps);
8574   dst = obuff;
8575   for (col = width; col > 0; col--)
8576     {
8577     /* Compute src byte(s) and bits within byte(s) */
8578     bit_offset = (col - 1) * bps * spp;
8579     for (sample = 0; sample < spp; sample++)
8580       {
8581       if (sample == 0)
8582         {
8583         src_byte = bit_offset / 8;
8584         high_bit  = bit_offset % 8;
8585         }
8586       else
8587         {
8588         src_byte = (bit_offset + (sample * bps)) / 8;
8589         high_bit  = (bit_offset + (sample * bps)) % 8;
8590         }
8591
8592       src = ibuff + src_byte;
8593       match_bits = mask_bits << (16 - high_bit - bps); 
8594       if (little_endian)
8595         buff1 = (src[0] << 8) | src[1];
8596       else
8597         buff1 = (src[1] << 8) | src[0];
8598       buff1 = (buff1 & match_bits) << (high_bit);
8599       
8600       if (ready_bits < 8)
8601         { /* add another bps bits to the buffer */
8602         bytebuff = 0;
8603         buff2 = (buff2 | (buff1 >> ready_bits));
8604         }
8605       else /* If we have a full buffer's worth, write it out */
8606         {
8607         bytebuff = (buff2 >> 8);
8608         *dst++ = bytebuff;
8609         ready_bits -= 8;
8610         /* shift in new bits */
8611         buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
8612         }
8613       ready_bits += bps;
8614       }
8615     }
8616
8617   if (ready_bits > 0)
8618     {
8619     bytebuff = (buff2 >> 8);
8620     *dst++ = bytebuff;
8621     }
8622
8623   return (0);
8624   } /* end reverseSamples16bits */
8625
8626 static int
8627 reverseSamples24bits (uint16 spp, uint16 bps, uint32 width, 
8628                       uint8 *ibuff, uint8 *obuff)
8629   {
8630   int      ready_bits = 0;
8631   uint32   col;
8632   uint32   src_byte = 0, high_bit = 0;
8633   uint32   bit_offset = 0;
8634   uint32   match_bits = 0, mask_bits = 0;
8635   uint32   buff1 = 0, buff2 = 0;
8636   uint8    bytebuff1 = 0, bytebuff2 = 0;
8637   unsigned char *src;
8638   unsigned char *dst;
8639   tsample_t sample;
8640
8641   if ((ibuff == NULL) || (obuff == NULL))
8642     {
8643     TIFFError("reverseSamples24bits","Invalid image or work buffer");
8644     return (1);
8645     }
8646
8647   ready_bits = 0;
8648   mask_bits =  (uint32)-1 >> (32 - bps);
8649   dst = obuff;
8650   for (col = width; col > 0; col--)
8651     {
8652     /* Compute src byte(s) and bits within byte(s) */
8653     bit_offset = (col - 1) * bps * spp;
8654     for (sample = 0; sample < spp; sample++)
8655       {
8656       if (sample == 0)
8657         {
8658         src_byte = bit_offset / 8;
8659         high_bit  = bit_offset % 8;
8660         }
8661       else
8662         {
8663         src_byte = (bit_offset + (sample * bps)) / 8;
8664         high_bit  = (bit_offset + (sample * bps)) % 8;
8665         }
8666
8667       src = ibuff + src_byte;
8668       match_bits = mask_bits << (32 - high_bit - bps); 
8669       if (little_endian)
8670         buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8671       else
8672         buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8673       buff1 = (buff1 & match_bits) << (high_bit);
8674
8675       if (ready_bits < 16)
8676         { /* add another bps bits to the buffer */
8677         bytebuff1 = bytebuff2 = 0;
8678         buff2 = (buff2 | (buff1 >> ready_bits));
8679         }
8680       else /* If we have a full buffer's worth, write it out */
8681         {
8682         bytebuff1 = (buff2 >> 24);
8683         *dst++ = bytebuff1;
8684         bytebuff2 = (buff2 >> 16);
8685         *dst++ = bytebuff2;
8686         ready_bits -= 16;
8687
8688         /* shift in new bits */
8689         buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8690         }
8691       ready_bits += bps;
8692       }
8693     }
8694
8695  /* catch any trailing bits at the end of the line */
8696   while (ready_bits > 0)
8697     {
8698     bytebuff1 = (buff2 >> 24);
8699     *dst++ = bytebuff1;
8700
8701     buff2 = (buff2 << 8);
8702     bytebuff2 = bytebuff1;
8703     ready_bits -= 8;
8704     }
8705  
8706   return (0);
8707   } /* end reverseSamples24bits */
8708
8709
8710 static int
8711 reverseSamples32bits (uint16 spp, uint16 bps, uint32 width, 
8712                       uint8 *ibuff, uint8 *obuff)
8713   {
8714   int    ready_bits = 0, shift_width = 0;
8715   int    bytes_per_sample, bytes_per_pixel;
8716   uint32 bit_offset;
8717   uint32 src_byte = 0, high_bit = 0;
8718   uint32 col;
8719   uint32 longbuff1 = 0, longbuff2 = 0;
8720   uint64 mask_bits = 0, match_bits = 0;
8721   uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8722   uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8723   unsigned char *src;
8724   unsigned char *dst;
8725   tsample_t sample;
8726
8727   if ((ibuff == NULL) || (obuff == NULL))
8728     {
8729     TIFFError("reverseSamples32bits","Invalid image or work buffer");
8730     return (1);
8731     }
8732
8733   ready_bits = 0;
8734   mask_bits =  (uint64)-1 >> (64 - bps);
8735   dst = obuff;
8736
8737   bytes_per_sample = (bps + 7) / 8;
8738   bytes_per_pixel  = ((bps * spp) + 7) / 8;
8739   if (bytes_per_pixel < (bytes_per_sample + 1))
8740     shift_width = bytes_per_pixel;
8741   else
8742     shift_width = bytes_per_sample + 1;
8743
8744   for (col = width; col > 0; col--)
8745     {
8746     /* Compute src byte(s) and bits within byte(s) */
8747     bit_offset = (col - 1) * bps * spp;
8748     for (sample = 0; sample < spp; sample++)
8749       {
8750       if (sample == 0)
8751         {
8752         src_byte = bit_offset / 8;
8753         high_bit  = bit_offset % 8;
8754         }
8755       else
8756         {
8757         src_byte = (bit_offset + (sample * bps)) / 8;
8758         high_bit  = (bit_offset + (sample * bps)) % 8;
8759         }
8760
8761       src = ibuff + src_byte;
8762       match_bits = mask_bits << (64 - high_bit - bps); 
8763       if (little_endian)
8764         {
8765         longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8766         longbuff2 = longbuff1;
8767         }
8768       else
8769         {
8770         longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8771         longbuff2 = longbuff1;
8772         }
8773       buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8774       buff1 = (buff3 & match_bits) << (high_bit);
8775
8776       if (ready_bits < 32)
8777         { /* add another bps bits to the buffer */
8778         bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8779         buff2 = (buff2 | (buff1 >> ready_bits));
8780         }
8781       else /* If we have a full buffer's worth, write it out */
8782         {
8783         bytebuff1 = (buff2 >> 56);
8784         *dst++ = bytebuff1;
8785         bytebuff2 = (buff2 >> 48);
8786         *dst++ = bytebuff2;
8787         bytebuff3 = (buff2 >> 40);
8788         *dst++ = bytebuff3;
8789         bytebuff4 = (buff2 >> 32);
8790         *dst++ = bytebuff4;
8791         ready_bits -= 32;
8792                     
8793         /* shift in new bits */
8794         buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8795         }
8796       ready_bits += bps;
8797       }
8798     }
8799   while (ready_bits > 0)
8800     {
8801     bytebuff1 = (buff2 >> 56);
8802     *dst++ = bytebuff1;
8803     buff2 = (buff2 << 8);
8804     ready_bits -= 8;
8805     }
8806
8807   return (0);
8808   } /* end reverseSamples32bits */
8809
8810 static int
8811 reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width, 
8812                      uint8 *src, uint8 *dst)
8813   {
8814   int i;
8815   uint32  col, bytes_per_pixel, col_offset;
8816   uint8   bytebuff1;
8817   unsigned char swapbuff[32];
8818   
8819   if ((src == NULL) || (dst == NULL))
8820     {
8821     TIFFError("reverseSamplesBytes","Invalid input or output buffer");
8822     return (1);
8823     }
8824
8825   bytes_per_pixel  = ((bps * spp) + 7) / 8;
8826   switch (bps / 8)
8827      {
8828      case 8:  /* Use memcpy for multiple bytes per sample data */
8829      case 4:
8830      case 3:
8831      case 2: for (col = 0; col < (width / 2); col++)
8832                {
8833                col_offset = col * bytes_per_pixel;                     
8834                _TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
8835                _TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
8836                _TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
8837                }
8838              break;
8839      case 1: /* Use byte copy only for single byte per sample data */
8840              for (col = 0; col < (width / 2); col++)
8841                { 
8842                for (i = 0; i < spp; i++)
8843                   {
8844                   bytebuff1 = *src;
8845                   *src++ = *(dst - spp + i);
8846                   *(dst - spp + i) = bytebuff1;
8847                   }
8848                 dst -= spp;
8849                 }
8850              break;
8851      default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
8852        return (1);
8853      }
8854   return (0);
8855   } /* end reverseSamplesBytes */
8856
8857
8858 /* Mirror an image horizontally or vertically */
8859 static int
8860 mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
8861   {
8862   int      shift_width;
8863   uint32   bytes_per_pixel, bytes_per_sample;
8864   uint32   row, rowsize, row_offset;
8865   unsigned char *line_buff = NULL;
8866   unsigned char *src;
8867   unsigned char *dst;
8868
8869   src = ibuff;
8870   rowsize = ((width * bps * spp) + 7) / 8;
8871   switch (mirror)
8872     {
8873     case MIRROR_BOTH:
8874     case MIRROR_VERT: 
8875              line_buff = (unsigned char *)_TIFFmalloc(rowsize);
8876              if (line_buff == NULL)
8877                {
8878                TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
8879                return (-1);
8880                }
8881
8882              dst = ibuff + (rowsize * (length - 1));
8883              for (row = 0; row < length / 2; row++)
8884                {
8885               _TIFFmemcpy(line_buff, src, rowsize);
8886               _TIFFmemcpy(src, dst,  rowsize);
8887               _TIFFmemcpy(dst, line_buff, rowsize);
8888                src += (rowsize);
8889                dst -= (rowsize);                                 
8890                }
8891              if (line_buff)
8892                _TIFFfree(line_buff);
8893              if (mirror == MIRROR_VERT)
8894                break;
8895     case MIRROR_HORIZ :
8896               if ((bps % 8) == 0) /* byte alligned data */
8897                 { 
8898                 for (row = 0; row < length; row++)
8899                   {
8900                   row_offset = row * rowsize;
8901                   src = ibuff + row_offset;
8902                   dst = ibuff + row_offset + rowsize;
8903                   if (reverseSamplesBytes(spp, bps, width, src, dst))
8904                     {
8905                     return (-1);
8906                     }
8907                   }
8908                 }
8909               else
8910                 { /* non 8 bit per sample  data */
8911                 if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
8912                   {
8913                   TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
8914                   return (-1);
8915                   }
8916                 bytes_per_sample = (bps + 7) / 8;
8917                 bytes_per_pixel  = ((bps * spp) + 7) / 8;
8918                 if (bytes_per_pixel < (bytes_per_sample + 1))
8919                   shift_width = bytes_per_pixel;
8920                 else
8921                   shift_width = bytes_per_sample + 1;
8922
8923                 for (row = 0; row < length; row++)
8924                   {
8925                   row_offset = row * rowsize;
8926                   src = ibuff + row_offset;
8927                   _TIFFmemset (line_buff, '\0', rowsize);
8928                   switch (shift_width)
8929                     {
8930                     case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
8931                               {
8932                               _TIFFfree(line_buff);
8933                               return (-1);
8934                               }
8935                              _TIFFmemcpy (src, line_buff, rowsize);
8936                              break;
8937                     case 2: if (reverseSamples24bits(spp, bps, width, src, line_buff))
8938                               {
8939                               _TIFFfree(line_buff);
8940                               return (-1);
8941                               }
8942                              _TIFFmemcpy (src, line_buff, rowsize);
8943                              break;
8944                     case 3: 
8945                     case 4: 
8946                     case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
8947                               {
8948                               _TIFFfree(line_buff);
8949                               return (-1);
8950                               }
8951                              _TIFFmemcpy (src, line_buff, rowsize);
8952                              break;
8953                     default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
8954                              _TIFFfree(line_buff);
8955                              return (-1);      
8956                     }
8957                   }
8958                 if (line_buff)
8959                   _TIFFfree(line_buff);
8960                 }
8961              break;
8962
8963     default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
8964              return (-1);
8965              break;
8966     }
8967
8968   return (0);
8969   }
8970
8971 /* Invert the light and dark values for a bilevel or grayscale image */
8972 static int
8973 invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
8974   {
8975   uint32   row, col;
8976   unsigned char  bytebuff1, bytebuff2, bytebuff3, bytebuff4;
8977   unsigned char *src;
8978   uint16        *src_uint16;
8979   uint32        *src_uint32;
8980
8981   if (spp != 1)
8982     {
8983     TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
8984     return (-1);
8985     }
8986
8987   if (photometric !=  PHOTOMETRIC_MINISWHITE && photometric !=  PHOTOMETRIC_MINISBLACK)
8988     {
8989     TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
8990     return (-1);
8991     }
8992
8993   src = work_buff;
8994   if (src == NULL)
8995     {
8996     TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
8997     return (-1);
8998     }
8999
9000   switch (bps)
9001     {
9002     case 32: src_uint32 = (uint32 *)src;
9003              for (row = 0; row < length; row++)
9004                for (col = 0; col < width; col++)
9005                  {
9006                  *src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
9007                   src_uint32++;
9008                  }
9009             break;
9010     case 16: src_uint16 = (uint16 *)src;
9011              for (row = 0; row < length; row++)
9012                for (col = 0; col < width; col++)
9013                  {
9014                  *src_uint16 = (uint16)0xFFFF - *src_uint16;
9015                   src_uint16++;
9016                  }
9017             break;
9018     case 8: for (row = 0; row < length; row++)
9019               for (col = 0; col < width; col++)
9020                 {
9021                 *src = (uint8)255 - *src;
9022                  src++;
9023                 }
9024             break;
9025     case 4: for (row = 0; row < length; row++)
9026               for (col = 0; col < width; col++)
9027                 {
9028                 bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
9029                 bytebuff2 = 16 - (*src & 15);
9030                 *src = bytebuff1 << 4 & bytebuff2;
9031                 src++;
9032                 }
9033             break;
9034     case 2: for (row = 0; row < length; row++)
9035               for (col = 0; col < width; col++)
9036                 {
9037                 bytebuff1 = 4 - (uint8)(*src & 192 >> 6);
9038                 bytebuff2 = 4 - (uint8)(*src & 48  >> 4);
9039                 bytebuff3 = 4 - (uint8)(*src & 12  >> 2);
9040                 bytebuff4 = 4 - (uint8)(*src & 3);
9041                 *src = (bytebuff1 << 6) || (bytebuff2 << 4) || (bytebuff3 << 2) || bytebuff4;
9042                 src++;
9043                 }
9044             break;
9045     case 1: for (row = 0; row < length; row++)
9046               for (col = 0; col < width; col += 8 /(spp * bps))
9047                 {
9048                 *src = ~(*src);
9049                 src++;
9050                 }
9051             break;
9052     default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
9053       return (-1);
9054     }
9055
9056   return (0);
9057   }
9058
9059 /* vim: set ts=8 sts=8 sw=8 noet: */
9060 /*
9061  * Local Variables:
9062  * mode: c
9063  * c-basic-offset: 8
9064  * fill-column: 78
9065  * End:
9066  */