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