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