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