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