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