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