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