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