1 /* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
2 * the image data through additional options listed below
5 * Copyright (c) 1988-1997 Sam Leffler
6 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Additions (c) Richard Nolde 2006-2010
9 * Permission to use, copy, modify, distribute, and sell this software and
10 * its documentation for any purpose is hereby granted without fee, provided
11 * that (i) the above copyright notices and this permission notice appear in
12 * all copies of the software and related documentation, and (ii) the names of
13 * Sam Leffler and Silicon Graphics may not be used in any advertising or
14 * publicity relating to the software without the specific, prior written
15 * permission of Sam Leffler and Silicon Graphics.
17 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
19 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
21 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS OR ANY OTHER COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL
23 * DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
24 * DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
25 * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
26 * OR PERFORMANCE OF THIS SOFTWARE.
28 * Some portions of the current code are derived from tiffcp, primarily in
29 * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though
30 * some of the original functions have been extended to support arbitrary bit
31 * depths. These functions are presented at the top of this file.
33 * Add support for the options below to extract sections of image(s)
34 * and to modify the whole image or selected portions of each image by
35 * rotations, mirroring, and colorscale/colormap inversion of selected
36 * types of TIFF images when appropriate. Some color model dependent
37 * functions are restricted to bilevel or 8 bit per sample data.
38 * See the man page for the full explanations.
41 * -h Display the syntax guide.
42 * -v Report the version and last build date for tiffcrop and libtiff.
43 * -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1
44 * Specify a series of coordinates to define rectangular
45 * regions by the top left and lower right corners.
46 * -e c|d|i|m|s export mode for images and selections from input images
47 * combined All images and selections are written to a single file (default)
48 * with multiple selections from one image combined into a single image
49 * divided All images and selections are written to a single file
50 * with each selection from one image written to a new image
51 * image Each input image is written to a new file (numeric filename sequence)
52 * with multiple selections from the image combined into one image
53 * multiple Each input image is written to a new file (numeric filename sequence)
54 * with each selection from the image written to a new image
55 * separated Individual selections from each image are written to separate files
56 * -U units [in, cm, px ] inches, centimeters or pixels
57 * -H # Set horizontal resolution of output images to #
58 * -V # Set vertical resolution of output images to #
59 * -J # Horizontal margin of output page to # expressed in current
60 * units when sectioning image into columns x rows
61 * using the -S cols:rows option.
62 * -K # Vertical margin of output page to # expressed in current
63 * units when sectioning image into columns x rows
64 * using the -S cols:rows option.
65 * -X # Horizontal dimension of region to extract expressed in current
67 * -Y # Vertical dimension of region to extract expressed in current
69 * -O orient Orientation for output image, portrait, landscape, auto
70 * -P page Page size for output image segments, eg letter, legal, tabloid,
72 * -S cols:rows Divide the image into equal sized segments using cols across
74 * -E t|l|r|b Edge to use as origin
75 * -m #,#,#,# Margins from edges for selection: top, left, bottom, right
77 * -Z #:#,#:# Zones of the image designated as zone X of Y,
78 * eg 1:3 would be first of three equal portions measured
80 * -N odd|even|#,#-#,#|last
81 * Select sequences and/or ranges of images within file
82 * to process. The words odd or even may be used to specify
83 * all odd or even numbered images the word last may be used
84 * in place of a number in the sequence to indicate the final
85 * image in the file without knowing how many images there are.
86 * -R # Rotate image or crop selection by 90,180,or 270 degrees
88 * -F h|v Flip (mirror) image or crop selection horizontally
90 * -I [black|white|data|both]
91 * Invert color space, eg dark to light for bilevel and grayscale images
92 * If argument is white or black, set the PHOTOMETRIC_INTERPRETATION
93 * tag to MinIsBlack or MinIsWhite without altering the image data
94 * If the argument is data or both, the image data are modified:
95 * both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
96 * data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
97 * -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
98 * Dump raw data for input and/or output images to individual files
99 * in raw (binary) format or text (ASCII) representing binary data
100 * as strings of 1s and 0s. The filename arguments are used as stems
101 * from which individual files are created for each image. Text format
102 * includes annotations for image parameters and scanline info. Level
103 * selects which functions dump data, with higher numbers selecting
104 * lower level, scanline level routines. Debug reports a limited set
105 * of messages to monitor progess without enabling dump logs.
108 static char tiffcrop_version_id[] = "2.4";
109 static char tiffcrop_rev_date[] = "12-13-2010";
111 #include "tif_config.h"
120 #include <sys/stat.h>
132 extern int getopt(int argc, char * const argv[], const char *optstring);
136 # include "libport.h"
142 # define unlink delete
146 #define PATH_MAX 1024
149 #define TIFF_UINT32_MAX 0xFFFFFFFFU
155 #define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
156 #define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
160 * Definitions and data structures required to support cropping and image
166 #define EDGE_BOTTOM 3
168 #define EDGE_CENTER 5
170 #define MIRROR_HORIZ 1
171 #define MIRROR_VERT 2
172 #define MIRROR_BOTH 3
173 #define ROTATECW_90 8
174 #define ROTATECW_180 16
175 #define ROTATECW_270 32
176 #define ROTATE_ANY (ROTATECW_90 | ROTATECW_180 | ROTATECW_270)
179 #define CROP_MARGINS 1
181 #define CROP_LENGTH 4
183 #define CROP_REGIONS 16
184 #define CROP_ROTATE 32
185 #define CROP_MIRROR 64
186 #define CROP_INVERT 128
188 /* Modes for writing out images and selections */
189 #define ONE_FILE_COMPOSITE 0 /* One file, sections combined sections */
190 #define ONE_FILE_SEPARATED 1 /* One file, sections to new IFDs */
191 #define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
192 #define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
193 #define FILE_PER_SELECTION 4 /* One file per selection */
195 #define COMPOSITE_IMAGES 0 /* Selections combined into one image */
196 #define SEPARATED_IMAGES 1 /* Selections saved to separate images */
201 #define MAX_REGIONS 8 /* number of regions to extract from a single page */
202 #define MAX_OUTBUFFS 8 /* must match larger of zones or regions */
203 #define MAX_SECTIONS 32 /* number of sections per page to write to output */
204 #define MAX_IMAGES 2048 /* number of images in descrete list, not in the file */
205 #define MAX_SAMPLES 8 /* maximum number of samples per pixel supported */
206 #define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
207 #define MAX_EXPORT_PAGES 999999 /* maximum number of export pages per file */
213 #define TIFF_DIR_MAX 65534
215 /* Offsets into buffer for margins and fixed width and length segments */
229 /* Description of a zone within the image. Position 1 of 3 zones would be
230 * the first third of the image. These are computed after margins and
231 * width/length requests are applied so that you can extract multiple
232 * zones from within a larger region for OCR or barcode recognition.
236 uint32 size; /* size of this buffer */
237 unsigned char *buffer; /* address of the allocated buffer */
241 int position; /* ordinal of segment to be extracted */
242 int total; /* total equal sized divisions of crop area */
246 uint32 x1; /* index of left edge */
247 uint32 x2; /* index of right edge */
248 uint32 y1; /* index of top edge */
249 uint32 y2; /* index of bottom edge */
250 int position; /* ordinal of segment to be extracted */
251 int total; /* total equal sized divisions of crop area */
252 uint32 buffsize; /* size of buffer needed to hold the cropped zone */
256 double X1; /* index of left edge in current units */
257 double X2; /* index of right edge in current units */
258 double Y1; /* index of top edge in current units */
259 double Y2; /* index of bottom edge in current units */
263 uint32 x1; /* pixel offset of left edge */
264 uint32 x2; /* pixel offset of right edge */
265 uint32 y1; /* pixel offset of top edge */
266 uint32 y2; /* picel offset of bottom edge */
267 uint32 width; /* width in pixels */
268 uint32 length; /* length in pixels */
269 uint32 buffsize; /* size of buffer needed to hold the cropped region */
270 unsigned char *buffptr; /* address of start of the region */
273 /* Cropping parameters from command line and image data
274 * Note: This should be renamed to proc_opts and expanded to include all current globals
275 * if possible, but each function that accesses global variables will have to be redone.
278 double width; /* Selection width for master crop region in requested units */
279 double length; /* Selection length for master crop region in requesed units */
280 double margins[4]; /* Top, left, bottom, right margins */
281 float xres; /* Horizontal resolution read from image*/
282 float yres; /* Vertical resolution read from image */
283 uint32 combined_width; /* Width of combined cropped zones */
284 uint32 combined_length; /* Length of combined cropped zones */
285 uint32 bufftotal; /* Size of buffer needed to hold all the cropped region */
286 uint16 img_mode; /* Composite or separate images created from zones or regions */
287 uint16 exp_mode; /* Export input images or selections to one or more files */
288 uint16 crop_mode; /* Crop options to be applied */
289 uint16 res_unit; /* Resolution unit for margins and selections */
290 uint16 edge_ref; /* Reference edge for sections extraction and combination */
291 uint16 rotation; /* Clockwise rotation of the extracted region or image */
292 uint16 mirror; /* Mirror extracted region or image horizontally or vertically */
293 uint16 invert; /* Invert the color map of image or region */
294 uint16 photometric; /* Status of photometric interpretation for inverted image */
295 uint16 selections; /* Number of regions or zones selected */
296 uint16 regions; /* Number of regions delimited by corner coordinates */
297 struct region regionlist[MAX_REGIONS]; /* Regions within page or master crop region */
298 uint16 zones; /* Number of zones delimited by Ordinal:Total requested */
299 struct zone zonelist[MAX_REGIONS]; /* Zones indices to define a region */
300 struct coordpairs corners[MAX_REGIONS]; /* Coordinates of upper left and lower right corner */
303 #define MAX_PAPERNAMES 49
304 #define MAX_PAPERNAME_LENGTH 15
305 #define DEFAULT_RESUNIT RESUNIT_INCH
306 #define DEFAULT_PAGE_HEIGHT 14.0
307 #define DEFAULT_PAGE_WIDTH 8.5
308 #define DEFAULT_RESOLUTION 300
309 #define DEFAULT_PAPER_SIZE "legal"
311 #define ORIENTATION_NONE 0
312 #define ORIENTATION_PORTRAIT 1
313 #define ORIENTATION_LANDSCAPE 2
314 #define ORIENTATION_SEASCAPE 4
315 #define ORIENTATION_AUTO 16
317 #define PAGE_MODE_NONE 0
318 #define PAGE_MODE_RESOLUTION 1
319 #define PAGE_MODE_PAPERSIZE 2
320 #define PAGE_MODE_MARGINS 4
321 #define PAGE_MODE_ROWSCOLS 8
323 #define INVERT_DATA_ONLY 10
324 #define INVERT_DATA_AND_TAG 11
327 char name[MAX_PAPERNAME_LENGTH];
333 /* European page sizes corrected from update sent by
334 * thomas . jarosch @ intra2net . com on 5/7/2010
335 * Paper Size Width Length Aspect Ratio */
336 struct paperdef PaperTable[MAX_PAPERNAMES] = {
337 {"default", 8.500, 14.000, 0.607},
338 {"pa4", 8.264, 11.000, 0.751},
339 {"letter", 8.500, 11.000, 0.773},
340 {"legal", 8.500, 14.000, 0.607},
341 {"half-letter", 8.500, 5.514, 1.542},
342 {"executive", 7.264, 10.528, 0.690},
343 {"tabloid", 11.000, 17.000, 0.647},
344 {"11x17", 11.000, 17.000, 0.647},
345 {"ledger", 17.000, 11.000, 1.545},
346 {"archa", 9.000, 12.000, 0.750},
347 {"archb", 12.000, 18.000, 0.667},
348 {"archc", 18.000, 24.000, 0.750},
349 {"archd", 24.000, 36.000, 0.667},
350 {"arche", 36.000, 48.000, 0.750},
351 {"csheet", 17.000, 22.000, 0.773},
352 {"dsheet", 22.000, 34.000, 0.647},
353 {"esheet", 34.000, 44.000, 0.773},
354 {"superb", 11.708, 17.042, 0.687},
355 {"commercial", 4.139, 9.528, 0.434},
356 {"monarch", 3.889, 7.528, 0.517},
357 {"envelope-dl", 4.333, 8.681, 0.499},
358 {"envelope-c5", 6.389, 9.028, 0.708},
359 {"europostcard", 4.139, 5.833, 0.710},
360 {"a0", 33.110, 46.811, 0.707},
361 {"a1", 23.386, 33.110, 0.706},
362 {"a2", 16.535, 23.386, 0.707},
363 {"a3", 11.693, 16.535, 0.707},
364 {"a4", 8.268, 11.693, 0.707},
365 {"a5", 5.827, 8.268, 0.705},
366 {"a6", 4.134, 5.827, 0.709},
367 {"a7", 2.913, 4.134, 0.705},
368 {"a8", 2.047, 2.913, 0.703},
369 {"a9", 1.457, 2.047, 0.712},
370 {"a10", 1.024, 1.457, 0.703},
371 {"b0", 39.370, 55.669, 0.707},
372 {"b1", 27.835, 39.370, 0.707},
373 {"b2", 19.685, 27.835, 0.707},
374 {"b3", 13.898, 19.685, 0.706},
375 {"b4", 9.843, 13.898, 0.708},
376 {"b5", 6.929, 9.843, 0.704},
377 {"b6", 4.921, 6.929, 0.710},
378 {"c0", 36.102, 51.063, 0.707},
379 {"c1", 25.512, 36.102, 0.707},
380 {"c2", 18.031, 25.512, 0.707},
381 {"c3", 12.756, 18.031, 0.707},
382 {"c4", 9.016, 12.756, 0.707},
383 {"c5", 6.378, 9.016, 0.707},
384 {"c6", 4.488, 6.378, 0.704},
385 {"", 0.000, 0.000, 1.000}
388 /* Structure to define input image parameters */
404 /* Structure to define the output image modifiers */
407 double width; /* width in pixels */
408 double length; /* length in pixels */
409 double hmargin; /* margins to subtract from width of sections */
410 double vmargin; /* margins to subtract from height of sections */
411 double hres; /* horizontal resolution for output */
412 double vres; /* vertical resolution for output */
413 uint32 mode; /* bitmask of modifiers to page format */
414 uint16 res_unit; /* resolution unit for output image */
415 unsigned int rows; /* number of section rows */
416 unsigned int cols; /* number of section cols */
417 unsigned int orient; /* portrait, landscape, seascape, auto */
425 char infilename[PATH_MAX + 1];
426 char outfilename[PATH_MAX + 1];
432 static int outtiled = -1;
433 static uint32 tilewidth = 0;
434 static uint32 tilelength = 0;
436 static uint16 config = 0;
437 static uint16 compression = 0;
438 static uint16 predictor = 0;
439 static uint16 fillorder = 0;
440 static uint32 rowsperstrip = 0;
441 static uint32 g3opts = 0;
442 static int ignore = FALSE; /* if true, ignore read errors */
443 static uint32 defg3opts = (uint32) -1;
444 static int quality = 100; /* JPEG quality */
445 /* static int jpegcolormode = -1; was JPEGCOLORMODE_RGB; */
446 static int jpegcolormode = JPEGCOLORMODE_RGB;
447 static uint16 defcompression = (uint16) -1;
448 static uint16 defpredictor = (uint16) -1;
449 static int pageNum = 0;
450 static int little_endian = 1;
452 /* Functions adapted from tiffcp with additions or significant modifications */
453 static int readContigStripsIntoBuffer (TIFF*, uint8*);
454 static int readSeparateStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
455 static int readContigTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
456 static int readSeparateTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
457 static int writeBufferToContigStrips (TIFF*, uint8*, uint32);
458 static int writeBufferToContigTiles (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
459 static int writeBufferToSeparateStrips (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
460 static int writeBufferToSeparateTiles (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
461 static int extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, tsample_t,
462 uint16, uint16, struct dump_opts *);
463 static int processCompressOptions(char*);
464 static void usage(void);
466 /* All other functions by Richard Nolde, not found in tiffcp */
467 static void initImageData (struct image_data *);
468 static void initCropMasks (struct crop_mask *);
469 static void initPageSetup (struct pagedef *, struct pageseg *, struct buffinfo []);
470 static void initDumpOptions(struct dump_opts *);
472 /* Command line and file naming functions */
473 void process_command_opts (int, char *[], char *, char *, uint32 *,
474 uint16 *, uint16 *, uint32 *, uint32 *, uint32 *,
475 struct crop_mask *, struct pagedef *,
477 unsigned int *, unsigned int *);
478 static int update_output_file (TIFF **, char *, int, char *, unsigned int *);
481 /* * High level functions for whole image manipulation */
482 static int get_page_geometry (char *, struct pagedef*);
483 static int computeInputPixelOffsets(struct crop_mask *, struct image_data *,
485 static int computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
486 struct pagedef *, struct pageseg *,
488 static int loadImage(TIFF *, struct image_data *, struct dump_opts *, unsigned char **);
489 static int correct_orientation(struct image_data *, unsigned char **);
490 static int getCropOffsets(struct image_data *, struct crop_mask *, struct dump_opts *);
491 static int processCropSelections(struct image_data *, struct crop_mask *,
492 unsigned char **, struct buffinfo []);
493 static int writeSelections(TIFF *, TIFF **, struct crop_mask *, struct image_data *,
494 struct dump_opts *, struct buffinfo [],
495 char *, char *, unsigned int*, unsigned int);
497 /* Section functions */
498 static int createImageSection(uint32, unsigned char **);
499 static int extractImageSection(struct image_data *, struct pageseg *,
500 unsigned char *, unsigned char *);
501 static int writeSingleSection(TIFF *, TIFF *, struct image_data *,
502 struct dump_opts *, uint32, uint32,
503 double, double, unsigned char *);
504 static int writeImageSections(TIFF *, TIFF *, struct image_data *,
505 struct pagedef *, struct pageseg *,
506 struct dump_opts *, unsigned char *,
508 /* Whole image functions */
509 static int createCroppedImage(struct image_data *, struct crop_mask *,
510 unsigned char **, unsigned char **);
511 static int writeCroppedImage(TIFF *, TIFF *, struct image_data *image,
512 struct dump_opts * dump,
513 uint32, uint32, unsigned char *, int, int);
515 /* Image manipulation functions */
516 static int rotateContigSamples8bits(uint16, uint16, uint16, uint32,
517 uint32, uint32, uint8 *, uint8 *);
518 static int rotateContigSamples16bits(uint16, uint16, uint16, uint32,
519 uint32, uint32, uint8 *, uint8 *);
520 static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
521 uint32, uint32, uint8 *, uint8 *);
522 static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
523 uint32, uint32, uint8 *, uint8 *);
524 static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
526 static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
528 static int invertImage(uint16, uint16, uint16, uint32, uint32,
531 /* Functions to reverse the sequence of samples in a scanline */
532 static int reverseSamples8bits (uint16, uint16, uint32, uint8 *, uint8 *);
533 static int reverseSamples16bits (uint16, uint16, uint32, uint8 *, uint8 *);
534 static int reverseSamples24bits (uint16, uint16, uint32, uint8 *, uint8 *);
535 static int reverseSamples32bits (uint16, uint16, uint32, uint8 *, uint8 *);
536 static int reverseSamplesBytes (uint16, uint16, uint32, uint8 *, uint8 *);
538 /* Functions for manipulating individual samples in an image */
539 static int extractSeparateRegion(struct image_data *, struct crop_mask *,
540 unsigned char *, unsigned char *, int);
541 static int extractCompositeRegions(struct image_data *, struct crop_mask *,
542 unsigned char *, unsigned char *);
543 static int extractContigSamples8bits (uint8 *, uint8 *, uint32,
544 tsample_t, uint16, uint16,
545 tsample_t, uint32, uint32);
546 static int extractContigSamples16bits (uint8 *, uint8 *, uint32,
547 tsample_t, uint16, uint16,
548 tsample_t, uint32, uint32);
549 static int extractContigSamples24bits (uint8 *, uint8 *, uint32,
550 tsample_t, uint16, uint16,
551 tsample_t, uint32, uint32);
552 static int extractContigSamples32bits (uint8 *, uint8 *, uint32,
553 tsample_t, uint16, uint16,
554 tsample_t, uint32, uint32);
555 static int extractContigSamplesBytes (uint8 *, uint8 *, uint32,
556 tsample_t, uint16, uint16,
557 tsample_t, uint32, uint32);
558 static int extractContigSamplesShifted8bits (uint8 *, uint8 *, uint32,
559 tsample_t, uint16, uint16,
560 tsample_t, uint32, uint32,
562 static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
563 tsample_t, uint16, uint16,
564 tsample_t, uint32, uint32,
566 static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
567 tsample_t, uint16, uint16,
568 tsample_t, uint32, uint32,
570 static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
571 tsample_t, uint16, uint16,
572 tsample_t, uint32, uint32,
574 static int extractContigSamplesToTileBuffer(uint8 *, uint8 *, uint32, uint32,
575 uint32, uint32, tsample_t, uint16,
576 uint16, uint16, struct dump_opts *);
578 /* Functions to combine separate planes into interleaved planes */
579 static int combineSeparateSamples8bits (uint8 *[], uint8 *, uint32, uint32,
580 uint16, uint16, FILE *, int, int);
581 static int combineSeparateSamples16bits (uint8 *[], uint8 *, uint32, uint32,
582 uint16, uint16, FILE *, int, int);
583 static int combineSeparateSamples24bits (uint8 *[], uint8 *, uint32, uint32,
584 uint16, uint16, FILE *, int, int);
585 static int combineSeparateSamples32bits (uint8 *[], uint8 *, uint32, uint32,
586 uint16, uint16, FILE *, int, int);
587 static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
588 uint32, uint32, tsample_t, uint16,
591 static int combineSeparateTileSamples8bits (uint8 *[], uint8 *, uint32, uint32,
592 uint32, uint32, uint16, uint16,
594 static int combineSeparateTileSamples16bits (uint8 *[], uint8 *, uint32, uint32,
595 uint32, uint32, uint16, uint16,
597 static int combineSeparateTileSamples24bits (uint8 *[], uint8 *, uint32, uint32,
598 uint32, uint32, uint16, uint16,
600 static int combineSeparateTileSamples32bits (uint8 *[], uint8 *, uint32, uint32,
601 uint32, uint32, uint16, uint16,
603 static int combineSeparateTileSamplesBytes (unsigned char *[], unsigned char *,
604 uint32, uint32, uint32, uint32,
605 tsample_t, uint16, FILE *, int, int);
607 /* Dump functions for debugging */
608 static void dump_info (FILE *, int, char *, char *, ...);
609 static int dump_data (FILE *, int, char *, unsigned char *, uint32);
610 static int dump_byte (FILE *, int, char *, unsigned char);
611 static int dump_short (FILE *, int, char *, uint16);
612 static int dump_long (FILE *, int, char *, uint32);
613 static int dump_wide (FILE *, int, char *, uint64);
614 static int dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *);
616 /* End function declarations */
617 /* Functions derived in whole or in part from tiffcp */
618 /* The following functions are taken largely intact from tiffcp */
620 static char* usage_info[] = {
621 "usage: tiffcrop [options] source1 ... sourceN destination",
622 "where options are:",
623 " -h Print this syntax listing",
624 " -v Print tiffcrop version identifier and last revision date",
626 " -a Append to output instead of overwriting",
627 " -d offset Set initial directory offset, counting first image as one, not zero",
628 " -p contig Pack samples contiguously (e.g. RGBRGB...)",
629 " -p separate Store samples separately (e.g. RRR...GGG...BBB...)",
630 " -s Write output in strips",
631 " -t Write output in tiles",
632 " -i Ignore read errors",
634 " -r # Make each strip have no more than # rows",
635 " -w # Set output tile width (pixels)",
636 " -l # Set output tile length (pixels)",
638 " -f lsb2msb Force lsb-to-msb FillOrder for output",
639 " -f msb2lsb Force msb-to-lsb FillOrder for output",
641 " -c lzw[:opts] Compress output with Lempel-Ziv & Welch encoding",
642 " -c zip[:opts] Compress output with deflate encoding",
643 " -c jpeg[:opts] Compress output with JPEG encoding",
644 " -c packbits Compress output with packbits encoding",
645 " -c g3[:opts] Compress output with CCITT Group 3 encoding",
646 " -c g4 Compress output with CCITT Group 4 encoding",
647 " -c none Use no compression algorithm on output",
650 " 1d Use default CCITT Group 3 1D-encoding",
651 " 2d Use optional CCITT Group 3 2D-encoding",
652 " fill Byte-align EOL codes",
653 "For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
656 " # Set compression quality level (0-100, default 100)",
657 " raw Output color image as raw YCbCr",
658 " rgb Output color image as RGB",
659 "For example, -c jpeg:rgb:50 to get JPEG-encoded RGB data with 50% comp. quality",
661 "LZW and deflate options:",
662 " # Set predictor value",
663 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
665 "Page and selection options:",
666 " -N odd|even|#,#-#,#|last sequences and ranges of images within file to process",
667 " The words odd or even may be used to specify all odd or even numbered images.",
668 " The word last may be used in place of a number in the sequence to indicate.",
669 " The final image in the file without knowing how many images there are.",
670 " Numbers are counted from one even though TIFF IFDs are counted from zero.",
672 " -E t|l|r|b edge to use as origin for width and length of crop region",
673 " -U units [in, cm, px ] inches, centimeters or pixels",
675 " -m #,#,#,# margins from edges for selection: top, left, bottom, right separated by commas",
676 " -X # horizontal dimension of region to extract expressed in current units",
677 " -Y # vertical dimension of region to extract expressed in current units",
678 " -Z #:#,#:# zones of the image designated as position X of Y,",
679 " eg 1:3 would be first of three equal portions measured from reference edge",
680 " -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
681 " regions of the image designated by upper left and lower right coordinates",
683 "Export grouping options:",
684 " -e c|d|i|m|s export mode for images and selections from input images.",
685 " When exporting a composite image from multiple zones or regions",
686 " (combined and image modes), the selections must have equal sizes",
687 " for the axis perpendicular to the edge specified with -E.",
688 " c|combined All images and selections are written to a single file (default).",
689 " with multiple selections from one image combined into a single image.",
690 " d|divided All images and selections are written to a single file",
691 " with each selection from one image written to a new image.",
692 " i|image Each input image is written to a new file (numeric filename sequence)",
693 " with multiple selections from the image combined into one image.",
694 " m|multiple Each input image is written to a new file (numeric filename sequence)",
695 " with each selection from the image written to a new image.",
696 " s|separated Individual selections from each image are written to separate files.",
699 " -H # Set horizontal resolution of output images to #",
700 " -V # Set vertical resolution of output images to #",
701 " -J # Set horizontal margin of output page to # expressed in current units",
702 " when sectioning image into columns x rows using the -S cols:rows option",
703 " -K # Set verticalal margin of output page to # expressed in current units",
704 " when sectioning image into columns x rows using the -S cols:rows option",
706 " -O orient orientation for output image, portrait, landscape, auto",
707 " -P page page size for output image segments, eg letter, legal, tabloid, etc",
708 " use #.#x#.# to specify a custom page size in the currently defined units",
709 " where #.# represents the width and length",
710 " -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
713 " flip (mirror) image or region horizontally, vertically, or both",
714 " -R # [90,180,or 270] degrees clockwise rotation of image or extracted region",
715 " -I [black|white|data|both]",
716 " invert color space, eg dark to light for bilevel and grayscale images",
717 " If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
718 " tag to MinIsBlack or MinIsWhite without altering the image data",
719 " If the argument is data or both, the image data are modified:",
720 " both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
721 " data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
723 "-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
724 " Debug/dump program progress and/or data to non-TIFF files.",
725 " Options include the following and must be joined as a comma",
726 " separate list. The use of this option is generally limited to",
727 " program debugging and development of future options.",
729 " debug:N Display limited program progress indicators where larger N",
730 " increase the level of detail. Note: Tiffcrop may be compiled with",
731 " -DDEVELMODE to enable additional very low level debug reporting.",
733 " Format:txt|raw Format any logged data as ASCII text or raw binary ",
734 " values. ASCII text dumps include strings of ones and zeroes",
735 " representing the binary values in the image data plus identifying headers.",
737 " level:N Specify the level of detail presented in the dump files.",
738 " This can vary from dumps of the entire input or output image data to dumps",
739 " of data processed by specific functions. Current range of levels is 1 to 3.",
741 " input:full-path-to-directory/input-dumpname",
743 " output:full-path-to-directory/output-dumpnaem",
745 " When dump files are being written, each image will be written to a separate",
746 " file with the name built by adding a numeric sequence value to the dumpname",
747 " and an extension of .txt for ASCII dumps or .bin for binary dumps.",
749 " The four debug/dump options are independent, though it makes little sense to",
750 " specify a dump file without specifying a detail level.",
755 /* This function could be modified to pass starting sample offset
756 * and number of samples as args to select fewer than spp
757 * from input image. These would then be passed to individual
758 * extractContigSampleXX routines.
760 static int readContigTilesIntoBuffer (TIFF* in, uint8* buf,
763 uint32 tw, uint32 tl,
764 tsample_t spp, uint16 bps)
767 tsample_t sample = 0;
768 tsample_t count = spp;
769 uint32 row, col, trow;
771 uint32 dst_rowsize, shift_width;
772 uint32 bytes_per_sample, bytes_per_pixel;
773 uint32 trailing_bits, prev_trailing_bits;
774 uint32 tile_rowsize = TIFFTileRowSize(in);
775 uint32 src_offset, dst_offset;
776 uint32 row_offset, col_offset;
777 uint8 *bufp = (uint8*) buf;
778 unsigned char *src = NULL;
779 unsigned char *dst = NULL;
780 tsize_t tbytes = 0, tile_buffsize = 0;
781 tsize_t tilesize = TIFFTileSize(in);
782 unsigned char *tilebuf = NULL;
784 bytes_per_sample = (bps + 7) / 8;
785 bytes_per_pixel = ((bps * spp) + 7) / 8;
791 if (bytes_per_pixel < (bytes_per_sample + 1))
792 shift_width = bytes_per_pixel;
794 shift_width = bytes_per_sample + 1;
797 tile_buffsize = tilesize;
798 if (tilesize == 0 || tile_rowsize == 0)
800 TIFFError("readContigTilesIntoBuffer", "Tile size or tile rowsize is zero");
804 if (tilesize < (tsize_t)(tl * tile_rowsize))
807 TIFFError("readContigTilesIntoBuffer",
808 "Tilesize %lu is too small, using alternate calculation %u",
809 tilesize, tl * tile_rowsize);
811 tile_buffsize = tl * tile_rowsize;
812 if (tl != (tile_buffsize / tile_rowsize))
814 TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size.");
819 /* Add 3 padding bytes for extractContigSamplesShifted32bits */
820 if( (size_t) tile_buffsize > 0xFFFFFFFFU - 3U )
822 TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size.");
825 tilebuf = _TIFFmalloc(tile_buffsize + 3);
828 tilebuf[tile_buffsize] = 0;
829 tilebuf[tile_buffsize+1] = 0;
830 tilebuf[tile_buffsize+2] = 0;
832 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
833 for (row = 0; row < imagelength; row += tl)
835 nrow = (row + tl > imagelength) ? imagelength - row : tl;
836 for (col = 0; col < imagewidth; col += tw)
838 tbytes = TIFFReadTile(in, tilebuf, col, row, 0, 0);
839 if (tbytes < tilesize && !ignore)
841 TIFFError(TIFFFileName(in),
842 "Error, can't read tile at row %lu col %lu, Read %lu bytes of %lu",
843 (unsigned long) col, (unsigned long) row, (unsigned long)tbytes,
844 (unsigned long)tilesize);
850 row_offset = row * dst_rowsize;
851 col_offset = ((col * bps * spp) + 7)/ 8;
852 bufp = buf + row_offset + col_offset;
854 if (col + tw > imagewidth)
855 ncol = imagewidth - col;
859 /* Each tile scanline will start on a byte boundary but it
860 * has to be merged into the scanline for the entire
861 * image buffer and the previous segment may not have
862 * ended on a byte boundary
864 /* Optimization for common bit depths, all samples */
865 if (((bps % 8) == 0) && (count == spp))
867 for (trow = 0; trow < nrow; trow++)
869 src_offset = trow * tile_rowsize;
870 _TIFFmemcpy (bufp, tilebuf + src_offset, (ncol * spp * bps) / 8);
871 bufp += (imagewidth * bps * spp) / 8;
876 /* Bit depths not a multiple of 8 and/or extract fewer than spp samples */
877 prev_trailing_bits = trailing_bits = 0;
878 trailing_bits = (ncol * bps * spp) % 8;
880 /* for (trow = 0; tl < nrow; trow++) */
881 for (trow = 0; trow < nrow; trow++)
883 src_offset = trow * tile_rowsize;
884 src = tilebuf + src_offset;
885 dst_offset = (row + trow) * dst_rowsize;
886 dst = buf + dst_offset + col_offset;
889 case 0: if (extractContigSamplesBytes (src, dst, ncol, sample,
890 spp, bps, count, 0, ncol))
892 TIFFError("readContigTilesIntoBuffer",
893 "Unable to extract row %d from tile %lu",
894 row, (unsigned long)TIFFCurrentTile(in));
898 case 1: if (bps == 1)
900 if (extractContigSamplesShifted8bits (src, dst, ncol,
906 TIFFError("readContigTilesIntoBuffer",
907 "Unable to extract row %d from tile %lu",
908 row, (unsigned long)TIFFCurrentTile(in));
914 if (extractContigSamplesShifted16bits (src, dst, ncol,
920 TIFFError("readContigTilesIntoBuffer",
921 "Unable to extract row %d from tile %lu",
922 row, (unsigned long)TIFFCurrentTile(in));
926 case 2: if (extractContigSamplesShifted24bits (src, dst, ncol,
932 TIFFError("readContigTilesIntoBuffer",
933 "Unable to extract row %d from tile %lu",
934 row, (unsigned long)TIFFCurrentTile(in));
940 case 5: if (extractContigSamplesShifted32bits (src, dst, ncol,
946 TIFFError("readContigTilesIntoBuffer",
947 "Unable to extract row %d from tile %lu",
948 row, (unsigned long)TIFFCurrentTile(in));
952 default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %d", bps);
956 prev_trailing_bits += trailing_bits;
957 /* if (prev_trailing_bits > 7) */
958 /* prev_trailing_bits-= 8; */
967 static int readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf,
968 uint32 imagelength, uint32 imagewidth,
969 uint32 tw, uint32 tl,
970 uint16 spp, uint16 bps)
972 int i, status = 1, sample;
973 int shift_width, bytes_per_pixel;
974 uint16 bytes_per_sample;
975 uint32 row, col; /* Current row and col of image */
976 uint32 nrow, ncol; /* Number of rows and cols in current tile */
977 uint32 row_offset, col_offset; /* Output buffer offsets */
978 tsize_t tbytes = 0, tilesize = TIFFTileSize(in);
980 uint8* bufp = (uint8*)obuf;
981 unsigned char *srcbuffs[MAX_SAMPLES];
982 unsigned char *tbuff = NULL;
984 bytes_per_sample = (bps + 7) / 8;
986 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
988 srcbuffs[sample] = NULL;
989 tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
992 TIFFError ("readSeparateTilesIntoBuffer",
993 "Unable to allocate tile read buffer for sample %d", sample);
994 for (i = 0; i < sample; i++)
995 _TIFFfree (srcbuffs[i]);
998 srcbuffs[sample] = tbuff;
1000 /* Each tile contains only the data for a single plane
1001 * arranged in scanlines of tw * bytes_per_sample bytes.
1003 for (row = 0; row < imagelength; row += tl)
1005 nrow = (row + tl > imagelength) ? imagelength - row : tl;
1006 for (col = 0; col < imagewidth; col += tw)
1008 for (s = 0; s < spp && s < MAX_SAMPLES; s++)
1009 { /* Read each plane of a tile set into srcbuffs[s] */
1010 tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
1011 if (tbytes < 0 && !ignore)
1013 TIFFError(TIFFFileName(in),
1014 "Error, can't read tile for row %lu col %lu, "
1016 (unsigned long) col, (unsigned long) row,
1019 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1021 tbuff = srcbuffs[sample];
1028 /* Tiles on the right edge may be padded out to tw
1029 * which must be a multiple of 16.
1030 * Ncol represents the visible (non padding) portion.
1032 if (col + tw > imagewidth)
1033 ncol = imagewidth - col;
1037 row_offset = row * (((imagewidth * spp * bps) + 7) / 8);
1038 col_offset = ((col * spp * bps) + 7) / 8;
1039 bufp = obuf + row_offset + col_offset;
1043 if (combineSeparateTileSamplesBytes(srcbuffs, bufp, ncol, nrow, imagewidth,
1044 tw, spp, bps, NULL, 0, 0))
1052 bytes_per_pixel = ((bps * spp) + 7) / 8;
1053 if (bytes_per_pixel < (bytes_per_sample + 1))
1054 shift_width = bytes_per_pixel;
1056 shift_width = bytes_per_sample + 1;
1058 switch (shift_width)
1060 case 1: if (combineSeparateTileSamples8bits (srcbuffs, bufp, ncol, nrow,
1061 imagewidth, tw, spp, bps,
1068 case 2: if (combineSeparateTileSamples16bits (srcbuffs, bufp, ncol, nrow,
1069 imagewidth, tw, spp, bps,
1076 case 3: if (combineSeparateTileSamples24bits (srcbuffs, bufp, ncol, nrow,
1077 imagewidth, tw, spp, bps,
1088 case 8: if (combineSeparateTileSamples32bits (srcbuffs, bufp, ncol, nrow,
1089 imagewidth, tw, spp, bps,
1096 default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps);
1104 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1106 tbuff = srcbuffs[sample];
1114 static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength)
1116 uint32 row, nrows, rowsperstrip;
1120 TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1121 for (row = 0; row < imagelength; row += rowsperstrip)
1123 nrows = (row + rowsperstrip > imagelength) ?
1124 imagelength - row : rowsperstrip;
1125 stripsize = TIFFVStripSize(out, nrows);
1126 if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
1128 TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1137 /* Abandon plans to modify code so that plannar orientation separate images
1138 * do not have all samples for each channel written before all samples
1139 * for the next channel have been abandoned.
1140 * Libtiff internals seem to depend on all data for a given sample
1141 * being contiguous within a strip or tile when PLANAR_CONFIG is
1142 * separate. All strips or tiles of a given plane are written
1143 * before any strips or tiles of a different plane are stored.
1146 writeBufferToSeparateStrips (TIFF* out, uint8* buf,
1147 uint32 length, uint32 width, uint16 spp,
1148 struct dump_opts *dump)
1152 uint32 row, nrows, rowsize, rowsperstrip;
1153 uint32 bytes_per_sample;
1156 tsize_t stripsize = TIFFStripSize(out);
1157 tsize_t rowstripsize, scanlinesize = TIFFScanlineSize(out);
1158 tsize_t total_bytes = 0;
1161 (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1162 (void) TIFFGetFieldDefaulted(out, TIFFTAG_BITSPERSAMPLE, &bps);
1163 bytes_per_sample = (bps + 7) / 8;
1165 (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / width ||
1166 bps * spp * width > TIFF_UINT32_MAX - 7U )
1168 TIFFError(TIFFFileName(out),
1169 "Error, uint32 overflow when computing (bps * spp * width) + 7");
1172 rowsize = ((bps * spp * width) + 7U) / 8; /* source has interleaved samples */
1173 if( bytes_per_sample == 0 ||
1174 rowsperstrip > TIFF_UINT32_MAX / bytes_per_sample ||
1175 rowsperstrip * bytes_per_sample > TIFF_UINT32_MAX / (width + 1) )
1177 TIFFError(TIFFFileName(out),
1178 "Error, uint32 overflow when computing rowsperstrip * "
1179 "bytes_per_sample * (width + 1)");
1182 rowstripsize = rowsperstrip * bytes_per_sample * (width + 1);
1184 obuf = _TIFFmalloc (rowstripsize);
1188 for (s = 0; s < spp; s++)
1190 for (row = 0; row < length; row += rowsperstrip)
1192 nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
1194 stripsize = TIFFVStripSize(out, nrows);
1195 src = buf + (row * rowsize);
1196 total_bytes += stripsize;
1197 memset (obuf, '\0', rowstripsize);
1198 if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
1203 if ((dump->outfile != NULL) && (dump->level == 1))
1205 dump_info(dump->outfile, dump->format,"",
1206 "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d",
1207 s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
1208 dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
1211 if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
1213 TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1224 /* Extract all planes from contiguous buffer into a single tile buffer
1225 * to be written out as a tile.
1227 static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
1228 uint32 imagewidth, tsample_t spp,
1229 struct dump_opts* dump)
1233 uint32 row, col, nrow, ncol;
1234 uint32 src_rowsize, col_offset;
1235 uint32 tile_rowsize = TIFFTileRowSize(out);
1236 uint8* bufp = (uint8*) buf;
1237 tsize_t tile_buffsize = 0;
1238 tsize_t tilesize = TIFFTileSize(out);
1239 unsigned char *tilebuf = NULL;
1241 if( !TIFFGetField(out, TIFFTAG_TILELENGTH, &tl) ||
1242 !TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw) ||
1243 !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) )
1246 if (tilesize == 0 || tile_rowsize == 0 || tl == 0 || tw == 0)
1248 TIFFError("writeBufferToContigTiles", "Tile size, tile row size, tile width, or tile length is zero");
1252 tile_buffsize = tilesize;
1253 if (tilesize < (tsize_t)(tl * tile_rowsize))
1256 TIFFError("writeBufferToContigTiles",
1257 "Tilesize %lu is too small, using alternate calculation %u",
1258 tilesize, tl * tile_rowsize);
1260 tile_buffsize = tl * tile_rowsize;
1261 if (tl != tile_buffsize / tile_rowsize)
1263 TIFFError("writeBufferToContigTiles", "Integer overflow when calculating buffer size");
1268 if( imagewidth == 0 ||
1269 (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
1270 bps * spp * imagewidth > TIFF_UINT32_MAX - 7U )
1272 TIFFError(TIFFFileName(out),
1273 "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
1276 src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
1278 tilebuf = _TIFFmalloc(tile_buffsize);
1281 for (row = 0; row < imagelength; row += tl)
1283 nrow = (row + tl > imagelength) ? imagelength - row : tl;
1284 for (col = 0; col < imagewidth; col += tw)
1286 /* Calculate visible portion of tile. */
1287 if (col + tw > imagewidth)
1288 ncol = imagewidth - col;
1292 col_offset = (((col * bps * spp) + 7) / 8);
1293 bufp = buf + (row * src_rowsize) + col_offset;
1294 if (extractContigSamplesToTileBuffer(tilebuf, bufp, nrow, ncol, imagewidth,
1295 tw, 0, spp, spp, bps, dump) > 0)
1297 TIFFError("writeBufferToContigTiles",
1298 "Unable to extract data to tile for row %lu, col %lu",
1299 (unsigned long) row, (unsigned long)col);
1304 if (TIFFWriteTile(out, tilebuf, col, row, 0, 0) < 0)
1306 TIFFError("writeBufferToContigTiles",
1307 "Cannot write tile at %lu %lu",
1308 (unsigned long) col, (unsigned long) row);
1317 } /* end writeBufferToContigTiles */
1319 /* Extract each plane from contiguous buffer into a single tile buffer
1320 * to be written out as a tile.
1322 static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
1323 uint32 imagewidth, tsample_t spp,
1324 struct dump_opts * dump)
1326 tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1328 uint32 row, col, nrow, ncol;
1329 uint32 src_rowsize, col_offset;
1332 uint8* bufp = (uint8*) buf;
1337 TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1338 TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1339 TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1341 if( imagewidth == 0 ||
1342 (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
1343 bps * spp * imagewidth > TIFF_UINT32_MAX - 7 )
1345 TIFFError(TIFFFileName(out),
1346 "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
1350 src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
1352 for (row = 0; row < imagelength; row += tl)
1354 nrow = (row + tl > imagelength) ? imagelength - row : tl;
1355 for (col = 0; col < imagewidth; col += tw)
1357 /* Calculate visible portion of tile. */
1358 if (col + tw > imagewidth)
1359 ncol = imagewidth - col;
1363 col_offset = (((col * bps * spp) + 7) / 8);
1364 bufp = buf + (row * src_rowsize) + col_offset;
1366 for (s = 0; s < spp; s++)
1368 if (extractContigSamplesToTileBuffer(obuf, bufp, nrow, ncol, imagewidth,
1369 tw, s, 1, spp, bps, dump) > 0)
1371 TIFFError("writeBufferToSeparateTiles",
1372 "Unable to extract data to tile for row %lu, col %lu sample %d",
1373 (unsigned long) row, (unsigned long)col, (int)s);
1378 if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0)
1380 TIFFError("writeBufferToseparateTiles",
1381 "Cannot write tile at %lu %lu sample %lu",
1382 (unsigned long) col, (unsigned long) row,
1393 } /* end writeBufferToSeparateTiles */
1396 processG3Options(char* cp)
1398 if( (cp = strchr(cp, ':')) ) {
1399 if (defg3opts == (uint32) -1)
1403 if (strneq(cp, "1d", 2))
1404 defg3opts &= ~GROUP3OPT_2DENCODING;
1405 else if (strneq(cp, "2d", 2))
1406 defg3opts |= GROUP3OPT_2DENCODING;
1407 else if (strneq(cp, "fill", 4))
1408 defg3opts |= GROUP3OPT_FILLBITS;
1411 } while( (cp = strchr(cp, ':')) );
1416 processCompressOptions(char* opt)
1420 if (strneq(opt, "none",4))
1422 defcompression = COMPRESSION_NONE;
1424 else if (streq(opt, "packbits"))
1426 defcompression = COMPRESSION_PACKBITS;
1428 else if (strneq(opt, "jpeg", 4))
1430 cp = strchr(opt, ':');
1431 defcompression = COMPRESSION_JPEG;
1435 if (isdigit((int)cp[1]))
1436 quality = atoi(cp + 1);
1437 else if (strneq(cp + 1, "raw", 3 ))
1438 jpegcolormode = JPEGCOLORMODE_RAW;
1439 else if (strneq(cp + 1, "rgb", 3 ))
1440 jpegcolormode = JPEGCOLORMODE_RGB;
1443 cp = strchr(cp + 1, ':');
1446 else if (strneq(opt, "g3", 2))
1448 processG3Options(opt);
1449 defcompression = COMPRESSION_CCITTFAX3;
1451 else if (streq(opt, "g4"))
1453 defcompression = COMPRESSION_CCITTFAX4;
1455 else if (strneq(opt, "lzw", 3))
1457 cp = strchr(opt, ':');
1459 defpredictor = atoi(cp+1);
1460 defcompression = COMPRESSION_LZW;
1462 else if (strneq(opt, "zip", 3))
1464 cp = strchr(opt, ':');
1466 defpredictor = atoi(cp+1);
1467 defcompression = COMPRESSION_ADOBE_DEFLATE;
1480 fprintf(stderr, "\n%s\n", TIFFGetVersion());
1481 for (i = 0; usage_info[i] != NULL; i++)
1482 fprintf(stderr, "%s\n", usage_info[i]);
1486 #define CopyField(tag, v) \
1487 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
1488 #define CopyField2(tag, v1, v2) \
1489 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
1490 #define CopyField3(tag, v1, v2, v3) \
1491 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
1492 #define CopyField4(tag, v1, v2, v3, v4) \
1493 if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
1496 cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
1502 CopyField(tag, shortv);
1503 } else if (count == 2) {
1504 uint16 shortv1, shortv2;
1505 CopyField2(tag, shortv1, shortv2);
1506 } else if (count == 4) {
1507 uint16 *tr, *tg, *tb, *ta;
1508 CopyField4(tag, tr, tg, tb, ta);
1509 } else if (count == (uint16) -1) {
1512 CopyField2(tag, shortv1, shortav);
1517 CopyField(tag, longv);
1523 CopyField(tag, floatv);
1524 } else if (count == (uint16) -1) {
1526 CopyField(tag, floatav);
1531 CopyField(tag, stringv);
1537 CopyField(tag, doublev);
1538 } else if (count == (uint16) -1) {
1540 CopyField(tag, doubleav);
1544 TIFFError(TIFFFileName(in),
1545 "Data type %d is not supported, tag %d skipped",
1550 static struct cpTag {
1555 { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
1556 { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
1557 { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
1558 { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
1559 { TIFFTAG_MAKE, 1, TIFF_ASCII },
1560 { TIFFTAG_MODEL, 1, TIFF_ASCII },
1561 { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
1562 { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
1563 { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
1564 { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
1565 { TIFFTAG_PAGENAME, 1, TIFF_ASCII },
1566 { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
1567 { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
1568 { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
1569 { TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
1570 { TIFFTAG_DATETIME, 1, TIFF_ASCII },
1571 { TIFFTAG_ARTIST, 1, TIFF_ASCII },
1572 { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
1573 { TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
1574 { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
1575 { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
1576 { TIFFTAG_INKSET, 1, TIFF_SHORT },
1577 { TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
1578 { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
1579 { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
1580 { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
1581 { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
1582 { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
1583 { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
1584 { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
1585 { TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
1586 { TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
1587 { TIFFTAG_STONITS, 1, TIFF_DOUBLE },
1589 #define NTAGS (sizeof (tags) / sizeof (tags[0]))
1591 #define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
1593 /* Functions written by Richard Nolde, with exceptions noted. */
1594 void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
1595 uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
1596 uint32 *deftilelength, uint32 *defrowsperstrip,
1597 struct crop_mask *crop_data, struct pagedef *page,
1598 struct dump_opts *dump,
1599 unsigned int *imagelist, unsigned int *image_count )
1601 int c, good_args = 0;
1602 char *opt_offset = NULL; /* Position in string of value sought */
1603 char *opt_ptr = NULL; /* Pointer to next token in option set */
1604 char *sep = NULL; /* Pointer to a token separator */
1605 unsigned int i, j, start, end;
1606 #if !HAVE_DECL_OPTARG
1608 extern char* optarg;
1613 while ((c = getopt(argc, argv,
1614 "ac:d:e:f:hil:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1)
1618 case 'a': mode[0] = 'a'; /* append to output */
1620 case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
1622 TIFFError ("Unknown compression option", "%s", optarg);
1623 TIFFError ("For valid options type", "tiffcrop -h");
1627 case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
1630 TIFFError ("","Directory offset must be greater than zero");
1631 TIFFError ("For valid options type", "tiffcrop -h");
1634 *dirnum = start - 1;
1636 case 'e': switch (tolower((int) optarg[0])) /* image export modes*/
1638 case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
1639 crop_data->img_mode = COMPOSITE_IMAGES;
1640 break; /* Composite */
1641 case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
1642 crop_data->img_mode = SEPARATED_IMAGES;
1643 break; /* Divided */
1644 case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
1645 crop_data->img_mode = COMPOSITE_IMAGES;
1647 case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
1648 crop_data->img_mode = SEPARATED_IMAGES;
1649 break; /* Multiple */
1650 case 's': crop_data->exp_mode = FILE_PER_SELECTION;
1651 crop_data->img_mode = SEPARATED_IMAGES;
1652 break; /* Sections */
1653 default: TIFFError ("Unknown export mode","%s", optarg);
1654 TIFFError ("For valid options type", "tiffcrop -h");
1658 case 'f': if (streq(optarg, "lsb2msb")) /* fill order */
1659 *deffillorder = FILLORDER_LSB2MSB;
1660 else if (streq(optarg, "msb2lsb"))
1661 *deffillorder = FILLORDER_MSB2LSB;
1664 TIFFError ("Unknown fill order", "%s", optarg);
1665 TIFFError ("For valid options type", "tiffcrop -h");
1671 case 'i': ignore = TRUE; /* ignore errors */
1673 case 'l': outtiled = TRUE; /* tile length */
1674 *deftilelength = atoi(optarg);
1676 case 'p': /* planar configuration */
1677 if (streq(optarg, "separate"))
1678 *defconfig = PLANARCONFIG_SEPARATE;
1679 else if (streq(optarg, "contig"))
1680 *defconfig = PLANARCONFIG_CONTIG;
1683 TIFFError ("Unknown planar configuration", "%s", optarg);
1684 TIFFError ("For valid options type", "tiffcrop -h");
1688 case 'r': /* rows/strip */
1689 *defrowsperstrip = atol(optarg);
1691 case 's': /* generate stripped output */
1694 case 't': /* generate tiled output */
1697 case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
1698 TIFFError ("Tiffcrop version", "%s, last updated: %s",
1699 tiffcrop_version_id, tiffcrop_rev_date);
1700 TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
1701 TIFFError (" ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
1702 TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
1705 case 'w': /* tile width */
1707 *deftilewidth = atoi(optarg);
1709 case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
1710 crop_data->crop_mode |= CROP_REGIONS;
1711 for (i = 0, opt_ptr = strtok (optarg, ":");
1712 ((opt_ptr != NULL) && (i < MAX_REGIONS));
1713 (opt_ptr = strtok (NULL, ":")), i++)
1715 crop_data->regions++;
1716 if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
1717 &crop_data->corners[i].X1, &crop_data->corners[i].Y1,
1718 &crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
1720 TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
1721 TIFFError ("For valid options type", "tiffcrop -h");
1725 /* check for remaining elements over MAX_REGIONS */
1726 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
1728 TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
1729 TIFFError ("For valid options type", "tiffcrop -h");
1733 /* options for file open modes */
1734 case 'B': *mp++ = 'b'; *mp = '\0';
1736 case 'L': *mp++ = 'l'; *mp = '\0';
1738 case 'M': *mp++ = 'm'; *mp = '\0';
1740 case 'C': *mp++ = 'c'; *mp = '\0';
1742 /* options for Debugging / data dump */
1743 case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
1745 (opt_ptr = strtok (NULL, ",")), i++)
1747 opt_offset = strpbrk(opt_ptr, ":=");
1748 if (opt_offset == NULL)
1750 TIFFError("Invalid dump option", "%s", optarg);
1751 TIFFError ("For valid options type", "tiffcrop -h");
1756 /* convert option to lowercase */
1757 end = strlen (opt_ptr);
1758 for (i = 0; i < end; i++)
1759 *(opt_ptr + i) = tolower((int) *(opt_ptr + i));
1760 /* Look for dump format specification */
1761 if (strncmp(opt_ptr, "for", 3) == 0)
1763 /* convert value to lowercase */
1764 end = strlen (opt_offset + 1);
1765 for (i = 1; i <= end; i++)
1766 *(opt_offset + i) = tolower((int) *(opt_offset + i));
1767 /* check dump format value */
1768 if (strncmp (opt_offset + 1, "txt", 3) == 0)
1770 dump->format = DUMP_TEXT;
1771 strcpy (dump->mode, "w");
1775 if (strncmp(opt_offset + 1, "raw", 3) == 0)
1777 dump->format = DUMP_RAW;
1778 strcpy (dump->mode, "wb");
1782 TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
1783 TIFFError ("For valid options type", "tiffcrop -h");
1789 { /* Look for dump level specification */
1790 if (strncmp (opt_ptr, "lev", 3) == 0)
1791 dump->level = atoi(opt_offset + 1);
1792 /* Look for input data dump file name */
1793 if (strncmp (opt_ptr, "in", 2) == 0)
1795 strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
1796 dump->infilename[PATH_MAX - 20] = '\0';
1798 /* Look for output data dump file name */
1799 if (strncmp (opt_ptr, "out", 3) == 0)
1801 strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
1802 dump->outfilename[PATH_MAX - 20] = '\0';
1804 if (strncmp (opt_ptr, "deb", 3) == 0)
1805 dump->debug = atoi(opt_offset + 1);
1808 if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
1810 if (dump->level == 1)
1811 TIFFError("","Defaulting to dump level 1, no data.");
1812 if (dump->format == DUMP_NONE)
1814 TIFFError("", "You must specify a dump format for dump files");
1815 TIFFError ("For valid options type", "tiffcrop -h");
1821 /* image manipulation routine options */
1822 case 'm': /* margins to exclude from selection, uppercase M was already used */
1823 /* order of values must be TOP, LEFT, BOTTOM, RIGHT */
1824 crop_data->crop_mode |= CROP_MARGINS;
1825 for (i = 0, opt_ptr = strtok (optarg, ",:");
1826 ((opt_ptr != NULL) && (i < 4));
1827 (opt_ptr = strtok (NULL, ",:")), i++)
1829 crop_data->margins[i] = atof(opt_ptr);
1832 case 'E': /* edge reference */
1833 switch (tolower((int) optarg[0]))
1835 case 't': crop_data->edge_ref = EDGE_TOP;
1837 case 'b': crop_data->edge_ref = EDGE_BOTTOM;
1839 case 'l': crop_data->edge_ref = EDGE_LEFT;
1841 case 'r': crop_data->edge_ref = EDGE_RIGHT;
1843 default: TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
1844 TIFFError ("For valid options type", "tiffcrop -h");
1848 case 'F': /* flip eg mirror image or cropped segment, M was already used */
1849 crop_data->crop_mode |= CROP_MIRROR;
1850 switch (tolower((int) optarg[0]))
1852 case 'h': crop_data->mirror = MIRROR_HORIZ;
1854 case 'v': crop_data->mirror = MIRROR_VERT;
1856 case 'b': crop_data->mirror = MIRROR_BOTH;
1858 default: TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
1859 TIFFError ("For valid options type", "tiffcrop -h");
1863 case 'H': /* set horizontal resolution to new value */
1864 page->hres = atof (optarg);
1865 page->mode |= PAGE_MODE_RESOLUTION;
1867 case 'I': /* invert the color space, eg black to white */
1868 crop_data->crop_mode |= CROP_INVERT;
1869 /* The PHOTOMETIC_INTERPRETATION tag may be updated */
1870 if (streq(optarg, "black"))
1872 crop_data->photometric = PHOTOMETRIC_MINISBLACK;
1875 if (streq(optarg, "white"))
1877 crop_data->photometric = PHOTOMETRIC_MINISWHITE;
1880 if (streq(optarg, "data"))
1882 crop_data->photometric = INVERT_DATA_ONLY;
1885 if (streq(optarg, "both"))
1887 crop_data->photometric = INVERT_DATA_AND_TAG;
1891 TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
1892 TIFFError ("For valid options type", "tiffcrop -h");
1895 case 'J': /* horizontal margin for sectioned ouput pages */
1896 page->hmargin = atof(optarg);
1897 page->mode |= PAGE_MODE_MARGINS;
1899 case 'K': /* vertical margin for sectioned ouput pages*/
1900 page->vmargin = atof(optarg);
1901 page->mode |= PAGE_MODE_MARGINS;
1903 case 'N': /* list of images to process */
1904 for (i = 0, opt_ptr = strtok (optarg, ",");
1905 ((opt_ptr != NULL) && (i < MAX_IMAGES));
1906 (opt_ptr = strtok (NULL, ",")))
1907 { /* We do not know how many images are in file yet
1908 * so we build a list to include the maximum allowed
1909 * and follow it until we hit the end of the file.
1910 * Image count is not accurate for odd, even, last
1911 * so page numbers won't be valid either.
1913 if (streq(opt_ptr, "odd"))
1915 for (j = 1; j <= MAX_IMAGES; j += 2)
1917 *image_count = (MAX_IMAGES - 1) / 2;
1922 if (streq(opt_ptr, "even"))
1924 for (j = 2; j <= MAX_IMAGES; j += 2)
1926 *image_count = MAX_IMAGES / 2;
1931 if (streq(opt_ptr, "last"))
1932 imagelist[i++] = MAX_IMAGES;
1933 else /* single value between commas */
1935 sep = strpbrk(opt_ptr, ":-");
1937 imagelist[i++] = atoi(opt_ptr);
1941 start = atoi (opt_ptr);
1942 if (!strcmp((sep + 1), "last"))
1945 end = atoi (sep + 1);
1946 for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
1955 case 'O': /* page orientation */
1956 switch (tolower((int) optarg[0]))
1958 case 'a': page->orient = ORIENTATION_AUTO;
1960 case 'p': page->orient = ORIENTATION_PORTRAIT;
1962 case 'l': page->orient = ORIENTATION_LANDSCAPE;
1964 default: TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
1965 TIFFError ("For valid options type", "tiffcrop -h");
1969 case 'P': /* page size selection */
1970 if (sscanf(optarg, "%lfx%lf", &page->width, &page->length) == 2)
1972 strcpy (page->name, "Custom");
1973 page->mode |= PAGE_MODE_PAPERSIZE;
1976 if (get_page_geometry (optarg, page))
1978 if (!strcmp(optarg, "list"))
1980 TIFFError("", "Name Width Length (in inches)");
1981 for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1982 TIFFError ("", "%-15.15s %5.2f %5.2f",
1983 PaperTable[i].name, PaperTable[i].width,
1984 PaperTable[i].length);
1988 TIFFError ("Invalid paper size", "%s", optarg);
1989 TIFFError ("", "Select one of:");
1990 TIFFError("", "Name Width Length (in inches)");
1991 for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1992 TIFFError ("", "%-15.15s %5.2f %5.2f",
1993 PaperTable[i].name, PaperTable[i].width,
1994 PaperTable[i].length);
1999 page->mode |= PAGE_MODE_PAPERSIZE;
2002 case 'R': /* rotate image or cropped segment */
2003 crop_data->crop_mode |= CROP_ROTATE;
2004 switch (strtoul(optarg, NULL, 0))
2006 case 90: crop_data->rotation = (uint16)90;
2008 case 180: crop_data->rotation = (uint16)180;
2010 case 270: crop_data->rotation = (uint16)270;
2012 default: TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
2013 TIFFError ("For valid options type", "tiffcrop -h");
2017 case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
2018 sep = strpbrk(optarg, ",:");
2022 page->cols = atoi(optarg);
2023 page->rows = atoi(sep +1);
2027 page->cols = atoi(optarg);
2028 page->rows = atoi(optarg);
2030 if ((page->cols * page->rows) > MAX_SECTIONS)
2032 TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
2035 page->mode |= PAGE_MODE_ROWSCOLS;
2037 case 'U': /* units for measurements and offsets */
2038 if (streq(optarg, "in"))
2040 crop_data->res_unit = RESUNIT_INCH;
2041 page->res_unit = RESUNIT_INCH;
2043 else if (streq(optarg, "cm"))
2045 crop_data->res_unit = RESUNIT_CENTIMETER;
2046 page->res_unit = RESUNIT_CENTIMETER;
2048 else if (streq(optarg, "px"))
2050 crop_data->res_unit = RESUNIT_NONE;
2051 page->res_unit = RESUNIT_NONE;
2055 TIFFError ("Illegal unit of measure","%s", optarg);
2056 TIFFError ("For valid options type", "tiffcrop -h");
2060 case 'V': /* set vertical resolution to new value */
2061 page->vres = atof (optarg);
2062 page->mode |= PAGE_MODE_RESOLUTION;
2064 case 'X': /* selection width */
2065 crop_data->crop_mode |= CROP_WIDTH;
2066 crop_data->width = atof(optarg);
2068 case 'Y': /* selection length */
2069 crop_data->crop_mode |= CROP_LENGTH;
2070 crop_data->length = atof(optarg);
2072 case 'Z': /* zones of an image X:Y read as zone X of Y */
2073 crop_data->crop_mode |= CROP_ZONES;
2074 for (i = 0, opt_ptr = strtok (optarg, ",");
2075 ((opt_ptr != NULL) && (i < MAX_REGIONS));
2076 (opt_ptr = strtok (NULL, ",")), i++)
2079 opt_offset = strchr(opt_ptr, ':');
2081 TIFFError("Wrong parameter syntax for -Z", "tiffcrop -h");
2085 crop_data->zonelist[i].position = atoi(opt_ptr);
2086 crop_data->zonelist[i].total = atoi(opt_offset + 1);
2088 /* check for remaining elements over MAX_REGIONS */
2089 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
2091 TIFFError("Zone list exceeds region limit", "%d", MAX_REGIONS);
2095 case '?': TIFFError ("For valid options type", "tiffcrop -h");
2100 } /* end process_command_opts */
2102 /* Start a new output file if one has not been previously opened or
2103 * autoindex is set to non-zero. Update page and file counters
2104 * so TIFFTAG PAGENUM will be correct in image.
2107 update_output_file (TIFF **tiffout, char *mode, int autoindex,
2108 char *outname, unsigned int *page)
2110 static int findex = 0; /* file sequence indicator */
2111 size_t basename_len;
2113 char export_ext[16];
2114 char exportname[PATH_MAX];
2116 if (autoindex && (*tiffout != NULL))
2118 /* Close any export file that was previously opened */
2119 TIFFClose (*tiffout);
2123 memcpy (export_ext, ".tiff", 6);
2124 memset (exportname, '\0', sizeof(exportname));
2126 /* Leave room for page number portion of the new filename :
2127 * hyphen + 6 digits + dot + 4 extension characters + null terminator */
2128 #define FILENUM_MAX_LENGTH (1+6+1+4+1)
2129 strncpy (exportname, outname, sizeof(exportname) - FILENUM_MAX_LENGTH);
2130 if (*tiffout == NULL) /* This is a new export file */
2133 { /* create a new filename for each export */
2135 if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
2137 strncpy (export_ext, sep, 5);
2141 memcpy (export_ext, ".tiff", 5);
2142 export_ext[5] = '\0';
2143 basename_len = strlen(exportname);
2145 /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
2146 if (findex > MAX_EXPORT_PAGES)
2148 TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES);
2152 /* We previously assured that there will be space left */
2153 snprintf(exportname + basename_len, sizeof(exportname) - basename_len, "-%03d%.5s", findex, export_ext);
2155 exportname[sizeof(exportname) - 1] = '\0';
2157 *tiffout = TIFFOpen(exportname, mode);
2158 if (*tiffout == NULL)
2160 TIFFError("update_output_file", "Unable to open output file %s", exportname);
2171 } /* end update_output_file */
2175 main(int argc, char* argv[])
2178 #if !HAVE_DECL_OPTARG
2181 uint16 defconfig = (uint16) -1;
2182 uint16 deffillorder = 0;
2183 uint32 deftilewidth = (uint32) 0;
2184 uint32 deftilelength = (uint32) 0;
2185 uint32 defrowsperstrip = (uint32) 0;
2193 /** RJN additions **/
2194 struct image_data image; /* Image parameters for one image */
2195 struct crop_mask crop; /* Cropping parameters for all images */
2196 struct pagedef page; /* Page definition for output pages */
2197 struct pageseg sections[MAX_SECTIONS]; /* Sections of one output page */
2198 struct buffinfo seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
2199 struct dump_opts dump; /* Data dump options */
2200 unsigned char *read_buff = NULL; /* Input image data buffer */
2201 unsigned char *crop_buff = NULL; /* Crop area buffer */
2202 unsigned char *sect_buff = NULL; /* Image section buffer */
2203 unsigned char *sect_src = NULL; /* Image section buffer pointer */
2204 unsigned int imagelist[MAX_IMAGES + 1]; /* individually specified images */
2205 unsigned int image_count = 0;
2206 unsigned int dump_images = 0;
2207 unsigned int next_image = 0;
2208 unsigned int next_page = 0;
2209 unsigned int total_pages = 0;
2210 unsigned int total_images = 0;
2211 unsigned int end_of_input = FALSE;
2214 char temp_filename[PATH_MAX + 16]; /* Extra space keeps the compiler from complaining */
2216 little_endian = *((unsigned char *)&little_endian) & '1';
2218 initImageData(&image);
2219 initCropMasks(&crop);
2220 initPageSetup(&page, sections, seg_buffs);
2221 initDumpOptions(&dump);
2223 process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig,
2224 &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
2225 &crop, &page, &dump, imagelist, &image_count);
2227 if (argc - optind < 2)
2230 if ((argc - optind) == 2)
2234 /* Read multiple input files and write to output file(s) */
2235 while (optind < argc - 1)
2237 in = TIFFOpen (argv[optind], "r");
2241 /* If only one input file is specified, we can use directory count */
2242 total_images = TIFFNumberOfDirectories(in);
2243 if (total_images > TIFF_DIR_MAX)
2245 TIFFError (TIFFFileName(in), "File contains too many directories");
2247 (void) TIFFClose(out);
2250 if (image_count == 0)
2253 total_pages = total_images; /* Only valid with single input file */
2257 dirnum = (tdir_t)(imagelist[next_image] - 1);
2260 /* Total pages only valid for enumerated list of pages not derived
2261 * using odd, even, or last keywords.
2263 if (image_count > total_images)
2264 image_count = total_images;
2266 total_pages = image_count;
2269 /* MAX_IMAGES is used for special case "last" in selection list */
2270 if (dirnum == (MAX_IMAGES - 1))
2271 dirnum = total_images - 1;
2273 if (dirnum > (total_images))
2275 TIFFError (TIFFFileName(in),
2276 "Invalid image number %d, File contains only %d images",
2277 (int)dirnum + 1, total_images);
2279 (void) TIFFClose(out);
2283 if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
2285 TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
2287 (void) TIFFClose(out);
2291 end_of_input = FALSE;
2292 while (end_of_input == FALSE)
2295 compression = defcompression;
2296 predictor = defpredictor;
2297 fillorder = deffillorder;
2298 rowsperstrip = defrowsperstrip;
2299 tilewidth = deftilewidth;
2300 tilelength = deftilelength;
2303 if (dump.format != DUMP_NONE)
2305 /* manage input and/or output dump files here */
2307 length = strlen(dump.infilename);
2310 if (dump.infile != NULL)
2311 fclose (dump.infile);
2313 /* dump.infilename is guaranteed to be NUL terminated and have 20 bytes
2314 fewer than PATH_MAX */
2315 snprintf(temp_filename, sizeof(temp_filename), "%s-read-%03d.%s",
2316 dump.infilename, dump_images,
2317 (dump.format == DUMP_TEXT) ? "txt" : "raw");
2318 if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
2320 TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2323 dump_info(dump.infile, dump.format, "Reading image","%d from %s",
2324 dump_images, TIFFFileName(in));
2326 length = strlen(dump.outfilename);
2329 if (dump.outfile != NULL)
2330 fclose (dump.outfile);
2332 /* dump.outfilename is guaranteed to be NUL terminated and have 20 bytes
2333 fewer than PATH_MAX */
2334 snprintf(temp_filename, sizeof(temp_filename), "%s-write-%03d.%s",
2335 dump.outfilename, dump_images,
2336 (dump.format == DUMP_TEXT) ? "txt" : "raw");
2337 if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
2339 TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2342 dump_info(dump.outfile, dump.format, "Writing image","%d from %s",
2343 dump_images, TIFFFileName(in));
2348 TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
2350 if (loadImage(in, &image, &dump, &read_buff))
2352 TIFFError("main", "Unable to load source image");
2356 /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
2358 if (image.adjustments != 0)
2360 if (correct_orientation(&image, &read_buff))
2361 TIFFError("main", "Unable to correct image orientation");
2364 if (getCropOffsets(&image, &crop, &dump))
2366 TIFFError("main", "Unable to define crop regions");
2370 if (crop.selections > 0)
2372 if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
2374 TIFFError("main", "Unable to process image selections");
2378 else /* Single image segment without zones or regions */
2380 if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
2382 TIFFError("main", "Unable to create output image");
2386 if (page.mode == PAGE_MODE_NONE)
2387 { /* Whole image or sections not based on output page size */
2388 if (crop.selections > 0)
2390 writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
2391 mp, argv[argc - 1], &next_page, total_pages);
2393 else /* One file all images and sections */
2395 if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
2398 if (writeCroppedImage(in, out, &image, &dump,crop.combined_width,
2399 crop.combined_length, crop_buff, next_page, total_pages))
2401 TIFFError("main", "Unable to write new image");
2408 /* If we used a crop buffer, our data is there, otherwise it is
2409 * in the read_buffer
2411 if (crop_buff != NULL)
2412 sect_src = crop_buff;
2414 sect_src = read_buff;
2415 /* Break input image into pages or rows and columns */
2416 if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
2418 TIFFError("main", "Unable to compute output section data");
2421 /* If there are multiple files on the command line, the final one is assumed
2422 * to be the output filename into which the images are written.
2424 if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
2427 if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, §_buff))
2429 TIFFError("main", "Unable to write image sections");
2434 /* No image list specified, just read the next image */
2435 if (image_count == 0)
2439 dirnum = (tdir_t)(imagelist[next_image] - 1);
2443 if (dirnum == MAX_IMAGES - 1)
2444 dirnum = TIFFNumberOfDirectories(in) - 1;
2446 if (!TIFFSetDirectory(in, (tdir_t)dirnum))
2447 end_of_input = TRUE;
2453 /* If we did not use the read buffer as the crop buffer */
2455 _TIFFfree(read_buff);
2458 _TIFFfree(crop_buff);
2461 _TIFFfree(sect_buff);
2463 /* Clean up any segment buffers used for zones or regions */
2464 for (seg = 0; seg < crop.selections; seg++)
2465 _TIFFfree (seg_buffs[seg].buffer);
2467 if (dump.format != DUMP_NONE)
2469 if (dump.infile != NULL)
2470 fclose (dump.infile);
2472 if (dump.outfile != NULL)
2474 dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
2475 fclose (dump.outfile);
2485 /* Debugging functions */
2486 static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
2490 char dump_array[10];
2491 unsigned char bitset;
2493 if (dumpfile == NULL)
2495 TIFFError ("", "Invalid FILE pointer for dump file");
2499 if (format == DUMP_TEXT)
2501 fprintf (dumpfile," %s ", dump_tag);
2502 for (i = 0; i < count; i++)
2504 for (j = 0, k = 7; j < 8; j++, k--)
2506 bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
2507 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2509 dump_array[8] = '\0';
2510 fprintf (dumpfile," %s", dump_array);
2512 fprintf (dumpfile,"\n");
2516 if ((fwrite (data, 1, count, dumpfile)) != count)
2518 TIFFError ("", "Unable to write binary data to dump file");
2526 static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
2529 char dump_array[10];
2530 unsigned char bitset;
2532 if (dumpfile == NULL)
2534 TIFFError ("", "Invalid FILE pointer for dump file");
2538 if (format == DUMP_TEXT)
2540 fprintf (dumpfile," %s ", dump_tag);
2541 for (j = 0, k = 7; j < 8; j++, k--)
2543 bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2544 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2546 dump_array[8] = '\0';
2547 fprintf (dumpfile," %s\n", dump_array);
2551 if ((fwrite (&data, 1, 1, dumpfile)) != 1)
2553 TIFFError ("", "Unable to write binary data to dump file");
2561 static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
2564 char dump_array[20];
2565 unsigned char bitset;
2567 if (dumpfile == NULL)
2569 TIFFError ("", "Invalid FILE pointer for dump file");
2573 if (format == DUMP_TEXT)
2575 fprintf (dumpfile," %s ", dump_tag);
2576 for (j = 0, k = 15; k >= 0; j++, k--)
2578 bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2579 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2581 sprintf(&dump_array[++j], " ");
2583 dump_array[17] = '\0';
2584 fprintf (dumpfile," %s\n", dump_array);
2588 if ((fwrite (&data, 2, 1, dumpfile)) != 2)
2590 TIFFError ("", "Unable to write binary data to dump file");
2598 static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
2601 char dump_array[40];
2602 unsigned char bitset;
2604 if (dumpfile == NULL)
2606 TIFFError ("", "Invalid FILE pointer for dump file");
2610 if (format == DUMP_TEXT)
2612 fprintf (dumpfile," %s ", dump_tag);
2613 for (j = 0, k = 31; k >= 0; j++, k--)
2615 bitset = data & (((uint32)1 << k)) ? 1 : 0;
2616 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2618 sprintf(&dump_array[++j], " ");
2620 dump_array[35] = '\0';
2621 fprintf (dumpfile," %s\n", dump_array);
2625 if ((fwrite (&data, 4, 1, dumpfile)) != 4)
2627 TIFFError ("", "Unable to write binary data to dump file");
2634 static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
2637 char dump_array[80];
2638 unsigned char bitset;
2640 if (dumpfile == NULL)
2642 TIFFError ("", "Invalid FILE pointer for dump file");
2646 if (format == DUMP_TEXT)
2648 fprintf (dumpfile," %s ", dump_tag);
2649 for (j = 0, k = 63; k >= 0; j++, k--)
2651 bitset = data & (((uint64)1 << k)) ? 1 : 0;
2652 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2654 sprintf(&dump_array[++j], " ");
2656 dump_array[71] = '\0';
2657 fprintf (dumpfile," %s\n", dump_array);
2661 if ((fwrite (&data, 8, 1, dumpfile)) != 8)
2663 TIFFError ("", "Unable to write binary data to dump file");
2671 static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
2673 if (format == DUMP_TEXT)
2677 fprintf(dumpfile, "%s ", prefix);
2678 vfprintf(dumpfile, msg, ap);
2679 fprintf(dumpfile, "\n");
2684 static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width,
2685 uint32 row, unsigned char *buff)
2689 unsigned char * dump_ptr;
2691 if (dumpfile == NULL)
2693 TIFFError ("", "Invalid FILE pointer for dump file");
2697 for (i = 0; i < rows; i++)
2699 dump_ptr = buff + (i * width);
2700 if (format == DUMP_TEXT)
2701 dump_info (dumpfile, format, "",
2702 "Row %4d, %d bytes at offset %d",
2703 row + i + 1, width, row * width);
2705 for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
2706 dump_data (dumpfile, format, "", dump_ptr, 10);
2708 dump_data (dumpfile, format, "", dump_ptr, k);
2713 /* Extract one or more samples from an interleaved buffer. If count == 1,
2714 * only the sample plane indicated by sample will be extracted. If count > 1,
2715 * count samples beginning at sample will be extracted. Portions of a
2716 * scanline can be extracted by specifying a start and end value.
2720 extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols,
2721 tsample_t sample, uint16 spp, uint16 bps,
2722 tsample_t count, uint32 start, uint32 end)
2724 int i, bytes_per_sample, sindex;
2725 uint32 col, dst_rowsize, bit_offset;
2726 uint32 src_byte /*, src_bit */;
2730 if ((src == NULL) || (dst == NULL))
2732 TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
2736 if ((start > end) || (start > cols))
2738 TIFFError ("extractContigSamplesBytes",
2739 "Invalid start column value %d ignored", start);
2742 if ((end == 0) || (end > cols))
2744 TIFFError ("extractContigSamplesBytes",
2745 "Invalid end column value %d ignored", end);
2749 dst_rowsize = (bps * (end - start) * count) / 8;
2751 bytes_per_sample = (bps + 7) / 8;
2752 /* Optimize case for copying all samples */
2755 src = in + (start * spp * bytes_per_sample);
2756 _TIFFmemcpy (dst, src, dst_rowsize);
2760 for (col = start; col < end; col++)
2762 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2764 bit_offset = col * bps * spp;
2767 src_byte = bit_offset / 8;
2768 /* src_bit = bit_offset % 8; */
2772 src_byte = (bit_offset + (sindex * bps)) / 8;
2773 /* src_bit = (bit_offset + (sindex * bps)) % 8; */
2775 src = in + src_byte;
2776 for (i = 0; i < bytes_per_sample; i++)
2783 } /* end extractContigSamplesBytes */
2786 extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
2787 tsample_t sample, uint16 spp, uint16 bps,
2788 tsample_t count, uint32 start, uint32 end)
2790 int ready_bits = 0, sindex = 0;
2791 uint32 col, src_byte, src_bit, bit_offset;
2792 uint8 maskbits = 0, matchbits = 0;
2793 uint8 buff1 = 0, buff2 = 0;
2797 if ((src == NULL) || (dst == NULL))
2799 TIFFError("extractContigSamples8bits","Invalid input or output buffer");
2803 if ((start > end) || (start > cols))
2805 TIFFError ("extractContigSamples8bits",
2806 "Invalid start column value %d ignored", start);
2809 if ((end == 0) || (end > cols))
2811 TIFFError ("extractContigSamples8bits",
2812 "Invalid end column value %d ignored", end);
2817 maskbits = (uint8)-1 >> ( 8 - bps);
2819 for (col = start; col < end; col++)
2820 { /* Compute src byte(s) and bits within byte(s) */
2821 bit_offset = col * bps * spp;
2822 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2826 src_byte = bit_offset / 8;
2827 src_bit = bit_offset % 8;
2831 src_byte = (bit_offset + (sindex * bps)) / 8;
2832 src_bit = (bit_offset + (sindex * bps)) % 8;
2835 src = in + src_byte;
2836 matchbits = maskbits << (8 - src_bit - bps);
2837 buff1 = ((*src) & matchbits) << (src_bit);
2839 /* If we have a full buffer's worth, write it out */
2840 if (ready_bits >= 8)
2847 buff2 = (buff2 | (buff1 >> ready_bits));
2852 while (ready_bits > 0)
2854 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
2860 } /* end extractContigSamples8bits */
2863 extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols,
2864 tsample_t sample, uint16 spp, uint16 bps,
2865 tsample_t count, uint32 start, uint32 end)
2867 int ready_bits = 0, sindex = 0;
2868 uint32 col, src_byte, src_bit, bit_offset;
2869 uint16 maskbits = 0, matchbits = 0;
2870 uint16 buff1 = 0, buff2 = 0;
2875 if ((src == NULL) || (dst == NULL))
2877 TIFFError("extractContigSamples16bits","Invalid input or output buffer");
2881 if ((start > end) || (start > cols))
2883 TIFFError ("extractContigSamples16bits",
2884 "Invalid start column value %d ignored", start);
2887 if ((end == 0) || (end > cols))
2889 TIFFError ("extractContigSamples16bits",
2890 "Invalid end column value %d ignored", end);
2895 maskbits = (uint16)-1 >> (16 - bps);
2897 for (col = start; col < end; col++)
2898 { /* Compute src byte(s) and bits within byte(s) */
2899 bit_offset = col * bps * spp;
2900 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2904 src_byte = bit_offset / 8;
2905 src_bit = bit_offset % 8;
2909 src_byte = (bit_offset + (sindex * bps)) / 8;
2910 src_bit = (bit_offset + (sindex * bps)) % 8;
2913 src = in + src_byte;
2914 matchbits = maskbits << (16 - src_bit - bps);
2917 buff1 = (src[0] << 8) | src[1];
2919 buff1 = (src[1] << 8) | src[0];
2921 buff1 = (buff1 & matchbits) << (src_bit);
2922 if (ready_bits < 8) /* add another bps bits to the buffer */
2925 buff2 = (buff2 | (buff1 >> ready_bits));
2927 else /* If we have a full buffer's worth, write it out */
2929 bytebuff = (buff2 >> 8);
2932 /* shift in new bits */
2933 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
2939 /* catch any trailing bits at the end of the line */
2940 while (ready_bits > 0)
2942 bytebuff = (buff2 >> 8);
2948 } /* end extractContigSamples16bits */
2952 extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
2953 tsample_t sample, uint16 spp, uint16 bps,
2954 tsample_t count, uint32 start, uint32 end)
2956 int ready_bits = 0, sindex = 0;
2957 uint32 col, src_byte, src_bit, bit_offset;
2958 uint32 maskbits = 0, matchbits = 0;
2959 uint32 buff1 = 0, buff2 = 0;
2960 uint8 bytebuff1 = 0, bytebuff2 = 0;
2964 if ((in == NULL) || (out == NULL))
2966 TIFFError("extractContigSamples24bits","Invalid input or output buffer");
2970 if ((start > end) || (start > cols))
2972 TIFFError ("extractContigSamples24bits",
2973 "Invalid start column value %d ignored", start);
2976 if ((end == 0) || (end > cols))
2978 TIFFError ("extractContigSamples24bits",
2979 "Invalid end column value %d ignored", end);
2984 maskbits = (uint32)-1 >> ( 32 - bps);
2985 for (col = start; col < end; col++)
2987 /* Compute src byte(s) and bits within byte(s) */
2988 bit_offset = col * bps * spp;
2989 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2993 src_byte = bit_offset / 8;
2994 src_bit = bit_offset % 8;
2998 src_byte = (bit_offset + (sindex * bps)) / 8;
2999 src_bit = (bit_offset + (sindex * bps)) % 8;
3002 src = in + src_byte;
3003 matchbits = maskbits << (32 - src_bit - bps);
3005 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3007 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3008 buff1 = (buff1 & matchbits) << (src_bit);
3010 if (ready_bits < 16) /* add another bps bits to the buffer */
3012 bytebuff1 = bytebuff2 = 0;
3013 buff2 = (buff2 | (buff1 >> ready_bits));
3015 else /* If we have a full buffer's worth, write it out */
3017 bytebuff1 = (buff2 >> 24);
3019 bytebuff2 = (buff2 >> 16);
3023 /* shift in new bits */
3024 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3030 /* catch any trailing bits at the end of the line */
3031 while (ready_bits > 0)
3033 bytebuff1 = (buff2 >> 24);
3036 buff2 = (buff2 << 8);
3037 bytebuff2 = bytebuff1;
3042 } /* end extractContigSamples24bits */
3045 extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
3046 tsample_t sample, uint16 spp, uint16 bps,
3047 tsample_t count, uint32 start, uint32 end)
3049 int ready_bits = 0, sindex = 0 /*, shift_width = 0 */;
3050 uint32 col, src_byte, src_bit, bit_offset;
3051 uint32 longbuff1 = 0, longbuff2 = 0;
3052 uint64 maskbits = 0, matchbits = 0;
3053 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3054 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3058 if ((in == NULL) || (out == NULL))
3060 TIFFError("extractContigSamples32bits","Invalid input or output buffer");
3065 if ((start > end) || (start > cols))
3067 TIFFError ("extractContigSamples32bits",
3068 "Invalid start column value %d ignored", start);
3071 if ((end == 0) || (end > cols))
3073 TIFFError ("extractContigSamples32bits",
3074 "Invalid end column value %d ignored", end);
3078 /* shift_width = ((bps + 7) / 8) + 1; */
3080 maskbits = (uint64)-1 >> ( 64 - bps);
3081 for (col = start; col < end; col++)
3083 /* Compute src byte(s) and bits within byte(s) */
3084 bit_offset = col * bps * spp;
3085 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3089 src_byte = bit_offset / 8;
3090 src_bit = bit_offset % 8;
3094 src_byte = (bit_offset + (sindex * bps)) / 8;
3095 src_bit = (bit_offset + (sindex * bps)) % 8;
3098 src = in + src_byte;
3099 matchbits = maskbits << (64 - src_bit - bps);
3102 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3103 longbuff2 = longbuff1;
3107 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3108 longbuff2 = longbuff1;
3111 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3112 buff1 = (buff3 & matchbits) << (src_bit);
3114 /* If we have a full buffer's worth, write it out */
3115 if (ready_bits >= 32)
3117 bytebuff1 = (buff2 >> 56);
3119 bytebuff2 = (buff2 >> 48);
3121 bytebuff3 = (buff2 >> 40);
3123 bytebuff4 = (buff2 >> 32);
3127 /* shift in new bits */
3128 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3131 { /* add another bps bits to the buffer */
3132 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3133 buff2 = (buff2 | (buff1 >> ready_bits));
3138 while (ready_bits > 0)
3140 bytebuff1 = (buff2 >> 56);
3142 buff2 = (buff2 << 8);
3147 } /* end extractContigSamples32bits */
3150 extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
3151 tsample_t sample, uint16 spp, uint16 bps,
3152 tsample_t count, uint32 start, uint32 end,
3155 int ready_bits = 0, sindex = 0;
3156 uint32 col, src_byte, src_bit, bit_offset;
3157 uint8 maskbits = 0, matchbits = 0;
3158 uint8 buff1 = 0, buff2 = 0;
3162 if ((src == NULL) || (dst == NULL))
3164 TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
3168 if ((start > end) || (start > cols))
3170 TIFFError ("extractContigSamplesShifted8bits",
3171 "Invalid start column value %d ignored", start);
3174 if ((end == 0) || (end > cols))
3176 TIFFError ("extractContigSamplesShifted8bits",
3177 "Invalid end column value %d ignored", end);
3182 maskbits = (uint8)-1 >> ( 8 - bps);
3184 for (col = start; col < end; col++)
3185 { /* Compute src byte(s) and bits within byte(s) */
3186 bit_offset = col * bps * spp;
3187 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3191 src_byte = bit_offset / 8;
3192 src_bit = bit_offset % 8;
3196 src_byte = (bit_offset + (sindex * bps)) / 8;
3197 src_bit = (bit_offset + (sindex * bps)) % 8;
3200 src = in + src_byte;
3201 matchbits = maskbits << (8 - src_bit - bps);
3202 buff1 = ((*src) & matchbits) << (src_bit);
3203 if ((col == start) && (sindex == sample))
3204 buff2 = *src & ((uint8)-1) << (shift);
3206 /* If we have a full buffer's worth, write it out */
3207 if (ready_bits >= 8)
3214 buff2 = buff2 | (buff1 >> ready_bits);
3219 while (ready_bits > 0)
3221 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3227 } /* end extractContigSamplesShifted8bits */
3230 extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols,
3231 tsample_t sample, uint16 spp, uint16 bps,
3232 tsample_t count, uint32 start, uint32 end,
3235 int ready_bits = 0, sindex = 0;
3236 uint32 col, src_byte, src_bit, bit_offset;
3237 uint16 maskbits = 0, matchbits = 0;
3238 uint16 buff1 = 0, buff2 = 0;
3243 if ((src == NULL) || (dst == NULL))
3245 TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
3249 if ((start > end) || (start > cols))
3251 TIFFError ("extractContigSamplesShifted16bits",
3252 "Invalid start column value %d ignored", start);
3255 if ((end == 0) || (end > cols))
3257 TIFFError ("extractContigSamplesShifted16bits",
3258 "Invalid end column value %d ignored", end);
3263 maskbits = (uint16)-1 >> (16 - bps);
3264 for (col = start; col < end; col++)
3265 { /* Compute src byte(s) and bits within byte(s) */
3266 bit_offset = col * bps * spp;
3267 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3271 src_byte = bit_offset / 8;
3272 src_bit = bit_offset % 8;
3276 src_byte = (bit_offset + (sindex * bps)) / 8;
3277 src_bit = (bit_offset + (sindex * bps)) % 8;
3280 src = in + src_byte;
3281 matchbits = maskbits << (16 - src_bit - bps);
3283 buff1 = (src[0] << 8) | src[1];
3285 buff1 = (src[1] << 8) | src[0];
3287 if ((col == start) && (sindex == sample))
3288 buff2 = buff1 & ((uint16)-1) << (8 - shift);
3290 buff1 = (buff1 & matchbits) << (src_bit);
3292 if (ready_bits < 8) /* add another bps bits to the buffer */
3293 buff2 = buff2 | (buff1 >> ready_bits);
3294 else /* If we have a full buffer's worth, write it out */
3296 bytebuff = (buff2 >> 8);
3299 /* shift in new bits */
3300 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3307 /* catch any trailing bits at the end of the line */
3308 while (ready_bits > 0)
3310 bytebuff = (buff2 >> 8);
3316 } /* end extractContigSamplesShifted16bits */
3320 extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
3321 tsample_t sample, uint16 spp, uint16 bps,
3322 tsample_t count, uint32 start, uint32 end,
3325 int ready_bits = 0, sindex = 0;
3326 uint32 col, src_byte, src_bit, bit_offset;
3327 uint32 maskbits = 0, matchbits = 0;
3328 uint32 buff1 = 0, buff2 = 0;
3329 uint8 bytebuff1 = 0, bytebuff2 = 0;
3333 if ((in == NULL) || (out == NULL))
3335 TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
3339 if ((start > end) || (start > cols))
3341 TIFFError ("extractContigSamplesShifted24bits",
3342 "Invalid start column value %d ignored", start);
3345 if ((end == 0) || (end > cols))
3347 TIFFError ("extractContigSamplesShifted24bits",
3348 "Invalid end column value %d ignored", end);
3353 maskbits = (uint32)-1 >> ( 32 - bps);
3354 for (col = start; col < end; col++)
3356 /* Compute src byte(s) and bits within byte(s) */
3357 bit_offset = col * bps * spp;
3358 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3362 src_byte = bit_offset / 8;
3363 src_bit = bit_offset % 8;
3367 src_byte = (bit_offset + (sindex * bps)) / 8;
3368 src_bit = (bit_offset + (sindex * bps)) % 8;
3371 src = in + src_byte;
3372 matchbits = maskbits << (32 - src_bit - bps);
3374 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3376 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3378 if ((col == start) && (sindex == sample))
3379 buff2 = buff1 & ((uint32)-1) << (16 - shift);
3381 buff1 = (buff1 & matchbits) << (src_bit);
3383 if (ready_bits < 16) /* add another bps bits to the buffer */
3385 bytebuff1 = bytebuff2 = 0;
3386 buff2 = (buff2 | (buff1 >> ready_bits));
3388 else /* If we have a full buffer's worth, write it out */
3390 bytebuff1 = (buff2 >> 24);
3392 bytebuff2 = (buff2 >> 16);
3396 /* shift in new bits */
3397 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3403 /* catch any trailing bits at the end of the line */
3404 while (ready_bits > 0)
3406 bytebuff1 = (buff2 >> 24);
3409 buff2 = (buff2 << 8);
3410 bytebuff2 = bytebuff1;
3415 } /* end extractContigSamplesShifted24bits */
3418 extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
3419 tsample_t sample, uint16 spp, uint16 bps,
3420 tsample_t count, uint32 start, uint32 end,
3423 int ready_bits = 0, sindex = 0 /*, shift_width = 0 */;
3424 uint32 col, src_byte, src_bit, bit_offset;
3425 uint32 longbuff1 = 0, longbuff2 = 0;
3426 uint64 maskbits = 0, matchbits = 0;
3427 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3428 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3432 if ((in == NULL) || (out == NULL))
3434 TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
3439 if ((start > end) || (start > cols))
3441 TIFFError ("extractContigSamplesShifted32bits",
3442 "Invalid start column value %d ignored", start);
3445 if ((end == 0) || (end > cols))
3447 TIFFError ("extractContigSamplesShifted32bits",
3448 "Invalid end column value %d ignored", end);
3452 /* shift_width = ((bps + 7) / 8) + 1; */
3454 maskbits = (uint64)-1 >> ( 64 - bps);
3455 for (col = start; col < end; col++)
3457 /* Compute src byte(s) and bits within byte(s) */
3458 bit_offset = col * bps * spp;
3459 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3463 src_byte = bit_offset / 8;
3464 src_bit = bit_offset % 8;
3468 src_byte = (bit_offset + (sindex * bps)) / 8;
3469 src_bit = (bit_offset + (sindex * bps)) % 8;
3472 src = in + src_byte;
3473 matchbits = maskbits << (64 - src_bit - bps);
3476 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3477 longbuff2 = longbuff1;
3481 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3482 longbuff2 = longbuff1;
3485 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3486 if ((col == start) && (sindex == sample))
3487 buff2 = buff3 & ((uint64)-1) << (32 - shift);
3489 buff1 = (buff3 & matchbits) << (src_bit);
3491 if (ready_bits < 32)
3492 { /* add another bps bits to the buffer */
3493 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3494 buff2 = (buff2 | (buff1 >> ready_bits));
3496 else /* If we have a full buffer's worth, write it out */
3498 bytebuff1 = (buff2 >> 56);
3500 bytebuff2 = (buff2 >> 48);
3502 bytebuff3 = (buff2 >> 40);
3504 bytebuff4 = (buff2 >> 32);
3508 /* shift in new bits */
3509 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3514 while (ready_bits > 0)
3516 bytebuff1 = (buff2 >> 56);
3518 buff2 = (buff2 << 8);
3523 } /* end extractContigSamplesShifted32bits */
3526 extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3527 tsample_t sample, uint16 spp, uint16 bps,
3528 struct dump_opts *dump)
3530 int shift_width, bytes_per_sample, bytes_per_pixel;
3531 uint32 src_rowsize, src_offset, row, first_col = 0;
3532 uint32 dst_rowsize, dst_offset;
3533 tsample_t count = 1;
3536 bytes_per_sample = (bps + 7) / 8;
3537 bytes_per_pixel = ((bps * spp) + 7) / 8;
3542 if (bytes_per_pixel < (bytes_per_sample + 1))
3543 shift_width = bytes_per_pixel;
3545 shift_width = bytes_per_sample + 1;
3547 src_rowsize = ((bps * spp * cols) + 7) / 8;
3548 dst_rowsize = ((bps * cols) + 7) / 8;
3550 if ((dump->outfile != NULL) && (dump->level == 4))
3552 dump_info (dump->outfile, dump->format, "extractContigSamplesToBuffer",
3553 "Sample %d, %d rows", sample + 1, rows + 1);
3555 for (row = 0; row < rows; row++)
3557 src_offset = row * src_rowsize;
3558 dst_offset = row * dst_rowsize;
3559 src = in + src_offset;
3560 dst = out + dst_offset;
3562 /* pack the data into the scanline */
3563 switch (shift_width)
3565 case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3566 spp, bps, count, first_col, cols))
3569 case 1: if (bps == 1)
3571 if (extractContigSamples8bits (src, dst, cols, sample,
3572 spp, bps, count, first_col, cols))
3577 if (extractContigSamples16bits (src, dst, cols, sample,
3578 spp, bps, count, first_col, cols))
3581 case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3582 spp, bps, count, first_col, cols))
3587 case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3588 spp, bps, count, first_col, cols))
3591 default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
3594 if ((dump->outfile != NULL) && (dump->level == 4))
3595 dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3599 } /* end extractContigSamplesToBuffer */
3602 extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3603 uint32 imagewidth, uint32 tilewidth, tsample_t sample,
3604 uint16 count, uint16 spp, uint16 bps, struct dump_opts *dump)
3606 int shift_width, bytes_per_sample, bytes_per_pixel;
3607 uint32 src_rowsize, src_offset, row;
3608 uint32 dst_rowsize, dst_offset;
3611 bytes_per_sample = (bps + 7) / 8;
3612 bytes_per_pixel = ((bps * spp) + 7) / 8;
3617 if (bytes_per_pixel < (bytes_per_sample + 1))
3618 shift_width = bytes_per_pixel;
3620 shift_width = bytes_per_sample + 1;
3623 if ((dump->outfile != NULL) && (dump->level == 4))
3625 dump_info (dump->outfile, dump->format, "extractContigSamplesToTileBuffer",
3626 "Sample %d, %d rows", sample + 1, rows + 1);
3629 src_rowsize = ((bps * spp * imagewidth) + 7) / 8;
3630 dst_rowsize = ((bps * tilewidth * count) + 7) / 8;
3632 for (row = 0; row < rows; row++)
3634 src_offset = row * src_rowsize;
3635 dst_offset = row * dst_rowsize;
3636 src = in + src_offset;
3637 dst = out + dst_offset;
3639 /* pack the data into the scanline */
3640 switch (shift_width)
3642 case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3643 spp, bps, count, 0, cols))
3646 case 1: if (bps == 1)
3648 if (extractContigSamples8bits (src, dst, cols, sample,
3649 spp, bps, count, 0, cols))
3654 if (extractContigSamples16bits (src, dst, cols, sample,
3655 spp, bps, count, 0, cols))
3658 case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3659 spp, bps, count, 0, cols))
3664 case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3665 spp, bps, count, 0, cols))
3668 default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps);
3671 if ((dump->outfile != NULL) && (dump->level == 4))
3672 dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3676 } /* end extractContigSamplesToTileBuffer */
3678 static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
3681 int32 bytes_read = 0;
3682 uint32 strip, nstrips = TIFFNumberOfStrips(in);
3683 uint32 stripsize = TIFFStripSize(in);
3685 uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
3686 tsize_t scanline_size = TIFFScanlineSize(in);
3688 if (scanline_size == 0) {
3689 TIFFError("", "TIFF scanline size is zero!");
3693 for (strip = 0; strip < nstrips; strip++) {
3694 bytes_read = TIFFReadEncodedStrip (in, strip, bufp, -1);
3695 rows = bytes_read / scanline_size;
3696 if ((strip < (nstrips - 1)) && (bytes_read != (int32)stripsize))
3697 TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
3698 (int)strip + 1, (unsigned long) bytes_read,
3699 (unsigned long)stripsize);
3701 if (bytes_read < 0 && !ignore) {
3702 TIFFError("", "Error reading strip %lu after %lu rows",
3703 (unsigned long) strip, (unsigned long)rows);
3710 } /* end readContigStripsIntoBuffer */
3713 combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
3714 uint32 cols, uint32 rows, uint16 spp, uint16 bps,
3715 FILE *dumpfile, int format, int level)
3717 int i, bytes_per_sample;
3718 uint32 row, col, col_offset, src_rowsize, dst_rowsize, row_offset;
3725 if ((src == NULL) || (dst == NULL))
3727 TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
3731 bytes_per_sample = (bps + 7) / 8;
3733 src_rowsize = ((bps * cols) + 7) / 8;
3734 dst_rowsize = ((bps * spp * cols) + 7) / 8;
3735 for (row = 0; row < rows; row++)
3737 if ((dumpfile != NULL) && (level == 2))
3739 for (s = 0; s < spp; s++)
3741 dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
3742 dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
3745 dst = out + (row * dst_rowsize);
3746 row_offset = row * src_rowsize;
3747 for (col = 0; col < cols; col++)
3749 col_offset = row_offset + (col * (bps / 8));
3750 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3752 src = srcbuffs[s] + col_offset;
3753 for (i = 0; i < bytes_per_sample; i++)
3754 *(dst + i) = *(src + i);
3755 src += bytes_per_sample;
3756 dst += bytes_per_sample;
3760 if ((dumpfile != NULL) && (level == 2))
3762 dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
3763 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3768 } /* end combineSeparateSamplesBytes */
3771 combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
3772 uint32 rows, uint16 spp, uint16 bps,
3773 FILE *dumpfile, int format, int level)
3776 /* int bytes_per_sample = 0; */
3777 uint32 src_rowsize, dst_rowsize, src_offset;
3779 uint32 row, col, src_byte = 0, src_bit = 0;
3780 uint8 maskbits = 0, matchbits = 0;
3781 uint8 buff1 = 0, buff2 = 0;
3783 unsigned char *src = in[0];
3784 unsigned char *dst = out;
3787 if ((src == NULL) || (dst == NULL))
3789 TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
3793 /* bytes_per_sample = (bps + 7) / 8; */
3794 src_rowsize = ((bps * cols) + 7) / 8;
3795 dst_rowsize = ((bps * cols * spp) + 7) / 8;
3796 maskbits = (uint8)-1 >> ( 8 - bps);
3798 for (row = 0; row < rows; row++)
3802 dst = out + (row * dst_rowsize);
3803 src_offset = row * src_rowsize;
3804 for (col = 0; col < cols; col++)
3806 /* Compute src byte(s) and bits within byte(s) */
3807 bit_offset = col * bps;
3808 src_byte = bit_offset / 8;
3809 src_bit = bit_offset % 8;
3811 matchbits = maskbits << (8 - src_bit - bps);
3812 /* load up next sample from each plane */
3813 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3815 src = in[s] + src_offset + src_byte;
3816 buff1 = ((*src) & matchbits) << (src_bit);
3818 /* If we have a full buffer's worth, write it out */
3819 if (ready_bits >= 8)
3824 strcpy (action, "Flush");
3828 buff2 = (buff2 | (buff1 >> ready_bits));
3829 strcpy (action, "Update");
3833 if ((dumpfile != NULL) && (level == 3))
3835 dump_info (dumpfile, format, "",
3836 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3837 row + 1, col + 1, s, src_byte, src_bit, dst - out);
3838 dump_byte (dumpfile, format, "Match bits", matchbits);
3839 dump_byte (dumpfile, format, "Src bits", *src);
3840 dump_byte (dumpfile, format, "Buff1 bits", buff1);
3841 dump_byte (dumpfile, format, "Buff2 bits", buff2);
3842 dump_info (dumpfile, format, "","%s", action);
3849 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3851 if ((dumpfile != NULL) && (level == 3))
3853 dump_info (dumpfile, format, "",
3854 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3855 row + 1, col + 1, src_byte, src_bit, dst - out);
3856 dump_byte (dumpfile, format, "Final bits", buff1);
3860 if ((dumpfile != NULL) && (level >= 2))
3862 dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
3863 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3868 } /* end combineSeparateSamples8bits */
3871 combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
3872 uint32 rows, uint16 spp, uint16 bps,
3873 FILE *dumpfile, int format, int level)
3875 int ready_bits = 0 /*, bytes_per_sample = 0 */;
3876 uint32 src_rowsize, dst_rowsize;
3877 uint32 bit_offset, src_offset;
3878 uint32 row, col, src_byte = 0, src_bit = 0;
3879 uint16 maskbits = 0, matchbits = 0;
3880 uint16 buff1 = 0, buff2 = 0;
3883 unsigned char *src = in[0];
3884 unsigned char *dst = out;
3887 if ((src == NULL) || (dst == NULL))
3889 TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
3893 /* bytes_per_sample = (bps + 7) / 8; */
3894 src_rowsize = ((bps * cols) + 7) / 8;
3895 dst_rowsize = ((bps * cols * spp) + 7) / 8;
3896 maskbits = (uint16)-1 >> (16 - bps);
3898 for (row = 0; row < rows; row++)
3902 dst = out + (row * dst_rowsize);
3903 src_offset = row * src_rowsize;
3904 for (col = 0; col < cols; col++)
3906 /* Compute src byte(s) and bits within byte(s) */
3907 bit_offset = col * bps;
3908 src_byte = bit_offset / 8;
3909 src_bit = bit_offset % 8;
3911 matchbits = maskbits << (16 - src_bit - bps);
3912 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3914 src = in[s] + src_offset + src_byte;
3916 buff1 = (src[0] << 8) | src[1];
3918 buff1 = (src[1] << 8) | src[0];
3920 buff1 = (buff1 & matchbits) << (src_bit);
3922 /* If we have a full buffer's worth, write it out */
3923 if (ready_bits >= 8)
3925 bytebuff = (buff2 >> 8);
3928 /* shift in new bits */
3929 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3930 strcpy (action, "Flush");
3933 { /* add another bps bits to the buffer */
3935 buff2 = (buff2 | (buff1 >> ready_bits));
3936 strcpy (action, "Update");
3940 if ((dumpfile != NULL) && (level == 3))
3942 dump_info (dumpfile, format, "",
3943 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3944 row + 1, col + 1, s, src_byte, src_bit, dst - out);
3946 dump_short (dumpfile, format, "Match bits", matchbits);
3947 dump_data (dumpfile, format, "Src bits", src, 2);
3948 dump_short (dumpfile, format, "Buff1 bits", buff1);
3949 dump_short (dumpfile, format, "Buff2 bits", buff2);
3950 dump_byte (dumpfile, format, "Write byte", bytebuff);
3951 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
3956 /* catch any trailing bits at the end of the line */
3959 bytebuff = (buff2 >> 8);
3961 if ((dumpfile != NULL) && (level == 3))
3963 dump_info (dumpfile, format, "",
3964 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3965 row + 1, col + 1, src_byte, src_bit, dst - out);
3966 dump_byte (dumpfile, format, "Final bits", bytebuff);
3970 if ((dumpfile != NULL) && (level == 2))
3972 dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
3973 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3978 } /* end combineSeparateSamples16bits */
3981 combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
3982 uint32 rows, uint16 spp, uint16 bps,
3983 FILE *dumpfile, int format, int level)
3985 int ready_bits = 0 /*, bytes_per_sample = 0 */;
3986 uint32 src_rowsize, dst_rowsize;
3987 uint32 bit_offset, src_offset;
3988 uint32 row, col, src_byte = 0, src_bit = 0;
3989 uint32 maskbits = 0, matchbits = 0;
3990 uint32 buff1 = 0, buff2 = 0;
3991 uint8 bytebuff1 = 0, bytebuff2 = 0;
3993 unsigned char *src = in[0];
3994 unsigned char *dst = out;
3997 if ((src == NULL) || (dst == NULL))
3999 TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
4003 /* bytes_per_sample = (bps + 7) / 8; */
4004 src_rowsize = ((bps * cols) + 7) / 8;
4005 dst_rowsize = ((bps * cols * spp) + 7) / 8;
4006 maskbits = (uint32)-1 >> ( 32 - bps);
4008 for (row = 0; row < rows; row++)
4012 dst = out + (row * dst_rowsize);
4013 src_offset = row * src_rowsize;
4014 for (col = 0; col < cols; col++)
4016 /* Compute src byte(s) and bits within byte(s) */
4017 bit_offset = col * bps;
4018 src_byte = bit_offset / 8;
4019 src_bit = bit_offset % 8;
4021 matchbits = maskbits << (32 - src_bit - bps);
4022 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4024 src = in[s] + src_offset + src_byte;
4026 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4028 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4029 buff1 = (buff1 & matchbits) << (src_bit);
4031 /* If we have a full buffer's worth, write it out */
4032 if (ready_bits >= 16)
4034 bytebuff1 = (buff2 >> 24);
4036 bytebuff2 = (buff2 >> 16);
4040 /* shift in new bits */
4041 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
4042 strcpy (action, "Flush");
4045 { /* add another bps bits to the buffer */
4046 bytebuff1 = bytebuff2 = 0;
4047 buff2 = (buff2 | (buff1 >> ready_bits));
4048 strcpy (action, "Update");
4052 if ((dumpfile != NULL) && (level == 3))
4054 dump_info (dumpfile, format, "",
4055 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4056 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4057 dump_long (dumpfile, format, "Match bits ", matchbits);
4058 dump_data (dumpfile, format, "Src bits ", src, 4);
4059 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4060 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4061 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4062 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4063 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
4068 /* catch any trailing bits at the end of the line */
4069 while (ready_bits > 0)
4071 bytebuff1 = (buff2 >> 24);
4074 buff2 = (buff2 << 8);
4075 bytebuff2 = bytebuff1;
4079 if ((dumpfile != NULL) && (level == 3))
4081 dump_info (dumpfile, format, "",
4082 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4083 row + 1, col + 1, src_byte, src_bit, dst - out);
4085 dump_long (dumpfile, format, "Match bits ", matchbits);
4086 dump_data (dumpfile, format, "Src bits ", src, 4);
4087 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4088 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4089 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4090 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4091 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4094 if ((dumpfile != NULL) && (level == 2))
4096 dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
4097 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4102 } /* end combineSeparateSamples24bits */
4105 combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4106 uint32 rows, uint16 spp, uint16 bps,
4107 FILE *dumpfile, int format, int level)
4109 int ready_bits = 0 /*, bytes_per_sample = 0, shift_width = 0 */;
4110 uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4111 uint32 src_byte = 0, src_bit = 0;
4113 uint32 longbuff1 = 0, longbuff2 = 0;
4114 uint64 maskbits = 0, matchbits = 0;
4115 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4116 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4118 unsigned char *src = in[0];
4119 unsigned char *dst = out;
4122 if ((src == NULL) || (dst == NULL))
4124 TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
4128 /* bytes_per_sample = (bps + 7) / 8; */
4129 src_rowsize = ((bps * cols) + 7) / 8;
4130 dst_rowsize = ((bps * cols * spp) + 7) / 8;
4131 maskbits = (uint64)-1 >> ( 64 - bps);
4132 /* shift_width = ((bps + 7) / 8) + 1; */
4134 for (row = 0; row < rows; row++)
4138 dst = out + (row * dst_rowsize);
4139 src_offset = row * src_rowsize;
4140 for (col = 0; col < cols; col++)
4142 /* Compute src byte(s) and bits within byte(s) */
4143 bit_offset = col * bps;
4144 src_byte = bit_offset / 8;
4145 src_bit = bit_offset % 8;
4147 matchbits = maskbits << (64 - src_bit - bps);
4148 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4150 src = in[s] + src_offset + src_byte;
4153 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4154 longbuff2 = longbuff1;
4158 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4159 longbuff2 = longbuff1;
4161 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4162 buff1 = (buff3 & matchbits) << (src_bit);
4164 /* If we have a full buffer's worth, write it out */
4165 if (ready_bits >= 32)
4167 bytebuff1 = (buff2 >> 56);
4169 bytebuff2 = (buff2 >> 48);
4171 bytebuff3 = (buff2 >> 40);
4173 bytebuff4 = (buff2 >> 32);
4177 /* shift in new bits */
4178 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4179 strcpy (action, "Flush");
4182 { /* add another bps bits to the buffer */
4183 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4184 buff2 = (buff2 | (buff1 >> ready_bits));
4185 strcpy (action, "Update");
4189 if ((dumpfile != NULL) && (level == 3))
4191 dump_info (dumpfile, format, "",
4192 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4193 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4194 dump_wide (dumpfile, format, "Match bits ", matchbits);
4195 dump_data (dumpfile, format, "Src bits ", src, 8);
4196 dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4197 dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4198 dump_info (dumpfile, format, "", "Ready bits: %d, %s", ready_bits, action);
4202 while (ready_bits > 0)
4204 bytebuff1 = (buff2 >> 56);
4206 buff2 = (buff2 << 8);
4210 if ((dumpfile != NULL) && (level == 3))
4212 dump_info (dumpfile, format, "",
4213 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4214 row + 1, col + 1, src_byte, src_bit, dst - out);
4216 dump_long (dumpfile, format, "Match bits ", matchbits);
4217 dump_data (dumpfile, format, "Src bits ", src, 4);
4218 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4219 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4220 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4221 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4222 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4225 if ((dumpfile != NULL) && (level == 2))
4227 dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
4228 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4233 } /* end combineSeparateSamples32bits */
4236 combineSeparateTileSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
4237 uint32 cols, uint32 rows, uint32 imagewidth,
4238 uint32 tw, uint16 spp, uint16 bps,
4239 FILE *dumpfile, int format, int level)
4241 int i, bytes_per_sample;
4242 uint32 row, col, col_offset, src_rowsize, dst_rowsize, src_offset;
4249 if ((src == NULL) || (dst == NULL))
4251 TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
4255 bytes_per_sample = (bps + 7) / 8;
4256 src_rowsize = ((bps * tw) + 7) / 8;
4257 dst_rowsize = imagewidth * bytes_per_sample * spp;
4258 for (row = 0; row < rows; row++)
4260 if ((dumpfile != NULL) && (level == 2))
4262 for (s = 0; s < spp; s++)
4264 dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Input data, Sample %d", s);
4265 dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
4268 dst = out + (row * dst_rowsize);
4269 src_offset = row * src_rowsize;
4271 TIFFError("","Tile row %4d, Src offset %6d Dst offset %6d",
4272 row, src_offset, dst - out);
4274 for (col = 0; col < cols; col++)
4276 col_offset = src_offset + (col * (bps / 8));
4277 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4279 src = srcbuffs[s] + col_offset;
4280 for (i = 0; i < bytes_per_sample; i++)
4281 *(dst + i) = *(src + i);
4282 dst += bytes_per_sample;
4286 if ((dumpfile != NULL) && (level == 2))
4288 dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Output data, combined samples");
4289 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4294 } /* end combineSeparateTileSamplesBytes */
4297 combineSeparateTileSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
4298 uint32 rows, uint32 imagewidth,
4299 uint32 tw, uint16 spp, uint16 bps,
4300 FILE *dumpfile, int format, int level)
4303 uint32 src_rowsize, dst_rowsize, src_offset;
4305 uint32 row, col, src_byte = 0, src_bit = 0;
4306 uint8 maskbits = 0, matchbits = 0;
4307 uint8 buff1 = 0, buff2 = 0;
4309 unsigned char *src = in[0];
4310 unsigned char *dst = out;
4313 if ((src == NULL) || (dst == NULL))
4315 TIFFError("combineSeparateTileSamples8bits","Invalid input or output buffer");
4319 src_rowsize = ((bps * tw) + 7) / 8;
4320 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4321 maskbits = (uint8)-1 >> ( 8 - bps);
4323 for (row = 0; row < rows; row++)
4327 dst = out + (row * dst_rowsize);
4328 src_offset = row * src_rowsize;
4329 for (col = 0; col < cols; col++)
4331 /* Compute src byte(s) and bits within byte(s) */
4332 bit_offset = col * bps;
4333 src_byte = bit_offset / 8;
4334 src_bit = bit_offset % 8;
4336 matchbits = maskbits << (8 - src_bit - bps);
4337 /* load up next sample from each plane */
4338 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4340 src = in[s] + src_offset + src_byte;
4341 buff1 = ((*src) & matchbits) << (src_bit);
4343 /* If we have a full buffer's worth, write it out */
4344 if (ready_bits >= 8)
4349 strcpy (action, "Flush");
4353 buff2 = (buff2 | (buff1 >> ready_bits));
4354 strcpy (action, "Update");
4358 if ((dumpfile != NULL) && (level == 3))
4360 dump_info (dumpfile, format, "",
4361 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4362 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4363 dump_byte (dumpfile, format, "Match bits", matchbits);
4364 dump_byte (dumpfile, format, "Src bits", *src);
4365 dump_byte (dumpfile, format, "Buff1 bits", buff1);
4366 dump_byte (dumpfile, format, "Buff2 bits", buff2);
4367 dump_info (dumpfile, format, "","%s", action);
4374 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
4376 if ((dumpfile != NULL) && (level == 3))
4378 dump_info (dumpfile, format, "",
4379 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4380 row + 1, col + 1, src_byte, src_bit, dst - out);
4381 dump_byte (dumpfile, format, "Final bits", buff1);
4385 if ((dumpfile != NULL) && (level >= 2))
4387 dump_info (dumpfile, format, "combineSeparateTileSamples8bits","Output data");
4388 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4393 } /* end combineSeparateTileSamples8bits */
4396 combineSeparateTileSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
4397 uint32 rows, uint32 imagewidth,
4398 uint32 tw, uint16 spp, uint16 bps,
4399 FILE *dumpfile, int format, int level)
4402 uint32 src_rowsize, dst_rowsize;
4403 uint32 bit_offset, src_offset;
4404 uint32 row, col, src_byte = 0, src_bit = 0;
4405 uint16 maskbits = 0, matchbits = 0;
4406 uint16 buff1 = 0, buff2 = 0;
4409 unsigned char *src = in[0];
4410 unsigned char *dst = out;
4413 if ((src == NULL) || (dst == NULL))
4415 TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
4419 src_rowsize = ((bps * tw) + 7) / 8;
4420 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4421 maskbits = (uint16)-1 >> (16 - bps);
4423 for (row = 0; row < rows; row++)
4427 dst = out + (row * dst_rowsize);
4428 src_offset = row * src_rowsize;
4429 for (col = 0; col < cols; col++)
4431 /* Compute src byte(s) and bits within byte(s) */
4432 bit_offset = col * bps;
4433 src_byte = bit_offset / 8;
4434 src_bit = bit_offset % 8;
4436 matchbits = maskbits << (16 - src_bit - bps);
4437 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4439 src = in[s] + src_offset + src_byte;
4441 buff1 = (src[0] << 8) | src[1];
4443 buff1 = (src[1] << 8) | src[0];
4444 buff1 = (buff1 & matchbits) << (src_bit);
4446 /* If we have a full buffer's worth, write it out */
4447 if (ready_bits >= 8)
4449 bytebuff = (buff2 >> 8);
4452 /* shift in new bits */
4453 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
4454 strcpy (action, "Flush");
4457 { /* add another bps bits to the buffer */
4459 buff2 = (buff2 | (buff1 >> ready_bits));
4460 strcpy (action, "Update");
4464 if ((dumpfile != NULL) && (level == 3))
4466 dump_info (dumpfile, format, "",
4467 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4468 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4470 dump_short (dumpfile, format, "Match bits", matchbits);
4471 dump_data (dumpfile, format, "Src bits", src, 2);
4472 dump_short (dumpfile, format, "Buff1 bits", buff1);
4473 dump_short (dumpfile, format, "Buff2 bits", buff2);
4474 dump_byte (dumpfile, format, "Write byte", bytebuff);
4475 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
4480 /* catch any trailing bits at the end of the line */
4483 bytebuff = (buff2 >> 8);
4485 if ((dumpfile != NULL) && (level == 3))
4487 dump_info (dumpfile, format, "",
4488 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4489 row + 1, col + 1, src_byte, src_bit, dst - out);
4490 dump_byte (dumpfile, format, "Final bits", bytebuff);
4494 if ((dumpfile != NULL) && (level == 2))
4496 dump_info (dumpfile, format, "combineSeparateTileSamples16bits","Output data");
4497 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4502 } /* end combineSeparateTileSamples16bits */
4505 combineSeparateTileSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
4506 uint32 rows, uint32 imagewidth,
4507 uint32 tw, uint16 spp, uint16 bps,
4508 FILE *dumpfile, int format, int level)
4511 uint32 src_rowsize, dst_rowsize;
4512 uint32 bit_offset, src_offset;
4513 uint32 row, col, src_byte = 0, src_bit = 0;
4514 uint32 maskbits = 0, matchbits = 0;
4515 uint32 buff1 = 0, buff2 = 0;
4516 uint8 bytebuff1 = 0, bytebuff2 = 0;
4518 unsigned char *src = in[0];
4519 unsigned char *dst = out;
4522 if ((src == NULL) || (dst == NULL))
4524 TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
4528 src_rowsize = ((bps * tw) + 7) / 8;
4529 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4530 maskbits = (uint32)-1 >> ( 32 - bps);
4532 for (row = 0; row < rows; row++)
4536 dst = out + (row * dst_rowsize);
4537 src_offset = row * src_rowsize;
4538 for (col = 0; col < cols; col++)
4540 /* Compute src byte(s) and bits within byte(s) */
4541 bit_offset = col * bps;
4542 src_byte = bit_offset / 8;
4543 src_bit = bit_offset % 8;
4545 matchbits = maskbits << (32 - src_bit - bps);
4546 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4548 src = in[s] + src_offset + src_byte;
4550 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4552 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4553 buff1 = (buff1 & matchbits) << (src_bit);
4555 /* If we have a full buffer's worth, write it out */
4556 if (ready_bits >= 16)
4558 bytebuff1 = (buff2 >> 24);
4560 bytebuff2 = (buff2 >> 16);
4564 /* shift in new bits */
4565 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
4566 strcpy (action, "Flush");
4569 { /* add another bps bits to the buffer */
4570 bytebuff1 = bytebuff2 = 0;
4571 buff2 = (buff2 | (buff1 >> ready_bits));
4572 strcpy (action, "Update");
4576 if ((dumpfile != NULL) && (level == 3))
4578 dump_info (dumpfile, format, "",
4579 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4580 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4581 dump_long (dumpfile, format, "Match bits ", matchbits);
4582 dump_data (dumpfile, format, "Src bits ", src, 4);
4583 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4584 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4585 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4586 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4587 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
4592 /* catch any trailing bits at the end of the line */
4593 while (ready_bits > 0)
4595 bytebuff1 = (buff2 >> 24);
4598 buff2 = (buff2 << 8);
4599 bytebuff2 = bytebuff1;
4603 if ((dumpfile != NULL) && (level == 3))
4605 dump_info (dumpfile, format, "",
4606 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4607 row + 1, col + 1, src_byte, src_bit, dst - out);
4609 dump_long (dumpfile, format, "Match bits ", matchbits);
4610 dump_data (dumpfile, format, "Src bits ", src, 4);
4611 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4612 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4613 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4614 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4615 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4618 if ((dumpfile != NULL) && (level == 2))
4620 dump_info (dumpfile, format, "combineSeparateTileSamples24bits","Output data");
4621 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4626 } /* end combineSeparateTileSamples24bits */
4629 combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4630 uint32 rows, uint32 imagewidth,
4631 uint32 tw, uint16 spp, uint16 bps,
4632 FILE *dumpfile, int format, int level)
4634 int ready_bits = 0 /*, shift_width = 0 */;
4635 uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4636 uint32 src_byte = 0, src_bit = 0;
4638 uint32 longbuff1 = 0, longbuff2 = 0;
4639 uint64 maskbits = 0, matchbits = 0;
4640 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4641 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4643 unsigned char *src = in[0];
4644 unsigned char *dst = out;
4647 if ((src == NULL) || (dst == NULL))
4649 TIFFError("combineSeparateTileSamples32bits","Invalid input or output buffer");
4653 src_rowsize = ((bps * tw) + 7) / 8;
4654 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4655 maskbits = (uint64)-1 >> ( 64 - bps);
4656 /* shift_width = ((bps + 7) / 8) + 1; */
4658 for (row = 0; row < rows; row++)
4662 dst = out + (row * dst_rowsize);
4663 src_offset = row * src_rowsize;
4664 for (col = 0; col < cols; col++)
4666 /* Compute src byte(s) and bits within byte(s) */
4667 bit_offset = col * bps;
4668 src_byte = bit_offset / 8;
4669 src_bit = bit_offset % 8;
4671 matchbits = maskbits << (64 - src_bit - bps);
4672 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4674 src = in[s] + src_offset + src_byte;
4677 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4678 longbuff2 = longbuff1;
4682 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4683 longbuff2 = longbuff1;
4686 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4687 buff1 = (buff3 & matchbits) << (src_bit);
4689 /* If we have a full buffer's worth, write it out */
4690 if (ready_bits >= 32)
4692 bytebuff1 = (buff2 >> 56);
4694 bytebuff2 = (buff2 >> 48);
4696 bytebuff3 = (buff2 >> 40);
4698 bytebuff4 = (buff2 >> 32);
4702 /* shift in new bits */
4703 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4704 strcpy (action, "Flush");
4707 { /* add another bps bits to the buffer */
4708 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4709 buff2 = (buff2 | (buff1 >> ready_bits));
4710 strcpy (action, "Update");
4714 if ((dumpfile != NULL) && (level == 3))
4716 dump_info (dumpfile, format, "",
4717 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4718 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4719 dump_wide (dumpfile, format, "Match bits ", matchbits);
4720 dump_data (dumpfile, format, "Src bits ", src, 8);
4721 dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4722 dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4723 dump_info (dumpfile, format, "", "Ready bits: %d, %s", ready_bits, action);
4727 while (ready_bits > 0)
4729 bytebuff1 = (buff2 >> 56);
4731 buff2 = (buff2 << 8);
4735 if ((dumpfile != NULL) && (level == 3))
4737 dump_info (dumpfile, format, "",
4738 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4739 row + 1, col + 1, src_byte, src_bit, dst - out);
4741 dump_long (dumpfile, format, "Match bits ", matchbits);
4742 dump_data (dumpfile, format, "Src bits ", src, 4);
4743 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4744 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4745 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4746 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4747 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4750 if ((dumpfile != NULL) && (level == 2))
4752 dump_info (dumpfile, format, "combineSeparateTileSamples32bits","Output data");
4753 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4758 } /* end combineSeparateTileSamples32bits */
4761 static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
4762 uint32 width, uint16 spp,
4763 struct dump_opts *dump)
4765 int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
4767 int32 bytes_read = 0;
4768 uint16 bps = 0, planar;
4770 uint32 strips_per_sample;
4771 uint32 src_rowsize, dst_rowsize, rows_processed, rps;
4772 uint32 rows_this_strip = 0;
4775 tsize_t scanlinesize = TIFFScanlineSize(in);
4776 tsize_t stripsize = TIFFStripSize(in);
4777 unsigned char *srcbuffs[MAX_SAMPLES];
4778 unsigned char *buff = NULL;
4779 unsigned char *dst = NULL;
4783 TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
4787 memset (srcbuffs, '\0', sizeof(srcbuffs));
4788 TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
4789 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
4790 TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
4794 bytes_per_sample = (bps + 7) / 8;
4795 bytes_per_pixel = ((bps * spp) + 7) / 8;
4796 if (bytes_per_pixel < (bytes_per_sample + 1))
4797 shift_width = bytes_per_pixel;
4799 shift_width = bytes_per_sample + 1;
4801 src_rowsize = ((bps * width) + 7) / 8;
4802 dst_rowsize = ((bps * width * spp) + 7) / 8;
4805 if ((dump->infile != NULL) && (dump->level == 3))
4807 dump_info (dump->infile, dump->format, "",
4808 "Image width %d, length %d, Scanline size, %4d bytes",
4809 width, length, scanlinesize);
4810 dump_info (dump->infile, dump->format, "",
4811 "Bits per sample %d, Samples per pixel %d, Shift width %d",
4812 bps, spp, shift_width);
4815 /* Libtiff seems to assume/require that data for separate planes are
4816 * written one complete plane after another and not interleaved in any way.
4817 * Multiple scanlines and possibly strips of the same plane must be
4818 * written before data for any other plane.
4820 nstrips = TIFFNumberOfStrips(in);
4821 strips_per_sample = nstrips /spp;
4823 /* Add 3 padding bytes for combineSeparateSamples32bits */
4824 if( (size_t) stripsize > 0xFFFFFFFFU - 3U )
4826 TIFFError("readSeparateStripsIntoBuffer", "Integer overflow when calculating buffer size.");
4830 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4833 buff = _TIFFmalloc(stripsize + 3);
4836 TIFFError ("readSeparateStripsIntoBuffer",
4837 "Unable to allocate strip read buffer for sample %d", s);
4838 for (i = 0; i < s; i++)
4839 _TIFFfree (srcbuffs[i]);
4842 buff[stripsize] = 0;
4843 buff[stripsize+1] = 0;
4844 buff[stripsize+2] = 0;
4849 for (j = 0; (j < strips_per_sample) && (result == 1); j++)
4851 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4854 strip = (s * strips_per_sample) + j;
4855 bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
4856 rows_this_strip = bytes_read / src_rowsize;
4857 if (bytes_read < 0 && !ignore)
4859 TIFFError(TIFFFileName(in),
4860 "Error, can't read strip %lu for sample %d",
4861 (unsigned long) strip, s + 1);
4866 TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d",
4867 strip, bytes_read, rows_this_strip, shift_width);
4871 if (rps > rows_this_strip)
4872 rps = rows_this_strip;
4873 dst = obuf + (dst_rowsize * rows_processed);
4876 if (combineSeparateSamplesBytes (srcbuffs, dst, width, rps,
4877 spp, bps, dump->infile,
4878 dump->format, dump->level))
4886 switch (shift_width)
4888 case 1: if (combineSeparateSamples8bits (srcbuffs, dst, width, rps,
4889 spp, bps, dump->infile,
4890 dump->format, dump->level))
4896 case 2: if (combineSeparateSamples16bits (srcbuffs, dst, width, rps,
4897 spp, bps, dump->infile,
4898 dump->format, dump->level))
4904 case 3: if (combineSeparateSamples24bits (srcbuffs, dst, width, rps,
4905 spp, bps, dump->infile,
4906 dump->format, dump->level))
4916 case 8: if (combineSeparateSamples32bits (srcbuffs, dst, width, rps,
4917 spp, bps, dump->infile,
4918 dump->format, dump->level))
4924 default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
4930 if ((rows_processed + rps) > length)
4932 rows_processed = length;
4933 rps = length - rows_processed;
4936 rows_processed += rps;
4939 /* free any buffers allocated for each plane or scanline and
4940 * any temporary buffers
4942 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4950 } /* end readSeparateStripsIntoBuffer */
4953 get_page_geometry (char *name, struct pagedef *page)
4958 for (ptr = name; *ptr; ptr++)
4959 *ptr = (char)tolower((int)*ptr);
4961 for (n = 0; n < MAX_PAPERNAMES; n++)
4963 if (strcmp(name, PaperTable[n].name) == 0)
4965 page->width = PaperTable[n].width;
4966 page->length = PaperTable[n].length;
4967 strncpy (page->name, PaperTable[n].name, 15);
4968 page->name[15] = '\0';
4978 initPageSetup (struct pagedef *page, struct pageseg *pagelist,
4979 struct buffinfo seg_buffs[])
4983 strcpy (page->name, "");
4984 page->mode = PAGE_MODE_NONE;
4985 page->res_unit = RESUNIT_NONE;
4990 page->hmargin = 0.0;
4991 page->vmargin = 0.0;
4994 page->orient = ORIENTATION_NONE;
4996 for (i = 0; i < MAX_SECTIONS; i++)
4998 pagelist[i].x1 = (uint32)0;
4999 pagelist[i].x2 = (uint32)0;
5000 pagelist[i].y1 = (uint32)0;
5001 pagelist[i].y2 = (uint32)0;
5002 pagelist[i].buffsize = (uint32)0;
5003 pagelist[i].position = 0;
5004 pagelist[i].total = 0;
5007 for (i = 0; i < MAX_OUTBUFFS; i++)
5009 seg_buffs[i].size = 0;
5010 seg_buffs[i].buffer = NULL;
5015 initImageData (struct image_data *image)
5021 image->res_unit = RESUNIT_NONE;
5025 image->photometric = 0;
5026 image->orientation = 0;
5027 image->compression = COMPRESSION_NONE;
5028 image->adjustments = 0;
5032 initCropMasks (struct crop_mask *cps)
5036 cps->crop_mode = CROP_NONE;
5037 cps->res_unit = RESUNIT_NONE;
5038 cps->edge_ref = EDGE_TOP;
5041 for (i = 0; i < 4; i++)
5042 cps->margins[i] = 0.0;
5043 cps->bufftotal = (uint32)0;
5044 cps->combined_width = (uint32)0;
5045 cps->combined_length = (uint32)0;
5046 cps->rotation = (uint16)0;
5047 cps->photometric = INVERT_DATA_AND_TAG;
5048 cps->mirror = (uint16)0;
5049 cps->invert = (uint16)0;
5050 cps->zones = (uint32)0;
5051 cps->regions = (uint32)0;
5052 for (i = 0; i < MAX_REGIONS; i++)
5054 cps->corners[i].X1 = 0.0;
5055 cps->corners[i].X2 = 0.0;
5056 cps->corners[i].Y1 = 0.0;
5057 cps->corners[i].Y2 = 0.0;
5058 cps->regionlist[i].x1 = 0;
5059 cps->regionlist[i].x2 = 0;
5060 cps->regionlist[i].y1 = 0;
5061 cps->regionlist[i].y2 = 0;
5062 cps->regionlist[i].width = 0;
5063 cps->regionlist[i].length = 0;
5064 cps->regionlist[i].buffsize = 0;
5065 cps->regionlist[i].buffptr = NULL;
5066 cps->zonelist[i].position = 0;
5067 cps->zonelist[i].total = 0;
5069 cps->exp_mode = ONE_FILE_COMPOSITE;
5070 cps->img_mode = COMPOSITE_IMAGES;
5073 static void initDumpOptions(struct dump_opts *dump)
5076 dump->format = DUMP_NONE;
5078 sprintf (dump->mode, "w");
5079 memset (dump->infilename, '\0', PATH_MAX + 1);
5080 memset (dump->outfilename, '\0',PATH_MAX + 1);
5081 dump->infile = NULL;
5082 dump->outfile = NULL;
5085 /* Compute pixel offsets into the image for margins and fixed regions */
5087 computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
5092 /* Values for these offsets are in pixels from start of image, not bytes,
5093 * and are indexed from zero to width - 1 or length - 1 */
5094 uint32 tmargin, bmargin, lmargin, rmargin;
5095 uint32 startx, endx; /* offsets of first and last columns to extract */
5096 uint32 starty, endy; /* offsets of first and last row to extract */
5097 uint32 width, length, crop_width, crop_length;
5098 uint32 i, max_width, max_length, zwidth, zlength, buffsize;
5099 uint32 x1, x2, y1, y2;
5101 if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
5108 if (((image->xres == 0) || (image->yres == 0)) &&
5109 (crop->res_unit != RESUNIT_NONE) &&
5110 ((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
5111 (crop->crop_mode & CROP_LENGTH) || (crop->crop_mode & CROP_WIDTH)))
5113 TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
5114 TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
5121 /* Translate user units to image units */
5123 switch (crop->res_unit) {
5124 case RESUNIT_CENTIMETER:
5125 if (image->res_unit == RESUNIT_INCH)
5129 if (image->res_unit == RESUNIT_CENTIMETER)
5132 case RESUNIT_NONE: /* Dimensions in pixels */
5137 if (crop->crop_mode & CROP_REGIONS)
5139 max_width = max_length = 0;
5140 for (i = 0; i < crop->regions; i++)
5142 if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
5144 x1 = (uint32) (crop->corners[i].X1 * scale * xres);
5145 x2 = (uint32) (crop->corners[i].X2 * scale * xres);
5146 y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
5147 y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
5151 x1 = (uint32) (crop->corners[i].X1);
5152 x2 = (uint32) (crop->corners[i].X2);
5153 y1 = (uint32) (crop->corners[i].Y1);
5154 y2 = (uint32) (crop->corners[i].Y2);
5157 crop->regionlist[i].x1 = 0;
5159 crop->regionlist[i].x1 = (uint32) (x1 - 1);
5161 if (x2 > image->width - 1)
5162 crop->regionlist[i].x2 = image->width - 1;
5164 crop->regionlist[i].x2 = (uint32) (x2 - 1);
5165 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5168 crop->regionlist[i].y1 = 0;
5170 crop->regionlist[i].y1 = (uint32) (y1 - 1);
5172 if (y2 > image->length - 1)
5173 crop->regionlist[i].y2 = image->length - 1;
5175 crop->regionlist[i].y2 = (uint32) (y2 - 1);
5177 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5179 if (zwidth > max_width)
5181 if (zlength > max_length)
5182 max_length = zlength;
5185 (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
5187 crop->regionlist[i].buffsize = buffsize;
5188 crop->bufftotal += buffsize;
5189 if (crop->img_mode == COMPOSITE_IMAGES)
5191 switch (crop->edge_ref)
5195 crop->combined_length = zlength;
5196 crop->combined_width += zwidth;
5199 case EDGE_TOP: /* width from left, length from top */
5201 crop->combined_width = zwidth;
5202 crop->combined_length += zlength;
5210 /* Convert crop margins into offsets into image
5211 * Margins are expressed as pixel rows and columns, not bytes
5213 if (crop->crop_mode & CROP_MARGINS)
5215 if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5216 { /* User has specified pixels as reference unit */
5217 tmargin = (uint32)(crop->margins[0]);
5218 lmargin = (uint32)(crop->margins[1]);
5219 bmargin = (uint32)(crop->margins[2]);
5220 rmargin = (uint32)(crop->margins[3]);
5223 { /* inches or centimeters specified */
5224 tmargin = (uint32)(crop->margins[0] * scale * yres);
5225 lmargin = (uint32)(crop->margins[1] * scale * xres);
5226 bmargin = (uint32)(crop->margins[2] * scale * yres);
5227 rmargin = (uint32)(crop->margins[3] * scale * xres);
5230 if ((lmargin + rmargin) > image->width)
5232 TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
5233 lmargin = (uint32) 0;
5234 rmargin = (uint32) 0;
5237 if ((tmargin + bmargin) > image->length)
5239 TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length");
5240 tmargin = (uint32) 0;
5241 bmargin = (uint32) 0;
5246 { /* no margins requested */
5247 tmargin = (uint32) 0;
5248 lmargin = (uint32) 0;
5249 bmargin = (uint32) 0;
5250 rmargin = (uint32) 0;
5253 /* Width, height, and margins are expressed as pixel offsets into image */
5254 if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5256 if (crop->crop_mode & CROP_WIDTH)
5257 width = (uint32)crop->width;
5259 width = image->width - lmargin - rmargin;
5261 if (crop->crop_mode & CROP_LENGTH)
5262 length = (uint32)crop->length;
5264 length = image->length - tmargin - bmargin;
5268 if (crop->crop_mode & CROP_WIDTH)
5269 width = (uint32)(crop->width * scale * image->xres);
5271 width = image->width - lmargin - rmargin;
5273 if (crop->crop_mode & CROP_LENGTH)
5274 length = (uint32)(crop->length * scale * image->yres);
5276 length = image->length - tmargin - bmargin;
5279 off->tmargin = tmargin;
5280 off->bmargin = bmargin;
5281 off->lmargin = lmargin;
5282 off->rmargin = rmargin;
5284 /* Calculate regions defined by margins, width, and length.
5285 * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
5286 * since they are used to compute offsets into buffers */
5287 switch (crop->edge_ref) {
5290 if ((startx + width) >= (image->width - rmargin))
5291 endx = image->width - rmargin - 1;
5293 endx = startx + width - 1;
5295 endy = image->length - bmargin - 1;
5296 if ((endy - length) <= tmargin)
5299 starty = endy - length + 1;
5302 endx = image->width - rmargin - 1;
5303 if ((endx - width) <= lmargin)
5306 startx = endx - width + 1;
5309 if ((starty + length) >= (image->length - bmargin))
5310 endy = image->length - bmargin - 1;
5312 endy = starty + length - 1;
5314 case EDGE_TOP: /* width from left, length from top */
5318 if ((startx + width) >= (image->width - rmargin))
5319 endx = image->width - rmargin - 1;
5321 endx = startx + width - 1;
5324 if ((starty + length) >= (image->length - bmargin))
5325 endy = image->length - bmargin - 1;
5327 endy = starty + length - 1;
5330 off->startx = startx;
5331 off->starty = starty;
5335 crop_width = endx - startx + 1;
5336 crop_length = endy - starty + 1;
5338 if (crop_width <= 0)
5340 TIFFError("computeInputPixelOffsets",
5341 "Invalid left/right margins and /or image crop width requested");
5344 if (crop_width > image->width)
5345 crop_width = image->width;
5347 if (crop_length <= 0)
5349 TIFFError("computeInputPixelOffsets",
5350 "Invalid top/bottom margins and /or image crop length requested");
5353 if (crop_length > image->length)
5354 crop_length = image->length;
5356 off->crop_width = crop_width;
5357 off->crop_length = crop_length;
5360 } /* end computeInputPixelOffsets */
5363 * Translate crop options into pixel offsets for one or more regions of the image.
5364 * Options are applied in this order: margins, specific width and length, zones,
5365 * but all are optional. Margins are relative to each edge. Width, length and
5366 * zones are relative to the specified reference edge. Zones are expressed as
5367 * X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
5368 * 2:3 would indicate the middle third of the region qualified by margins and
5369 * any explicit width and length specified. Regions are specified by coordinates
5370 * of the top left and lower right corners with range 1 to width or height.
5374 getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
5376 struct offset offsets;
5379 uint32 seg, total, need_buff = 0;
5381 uint32 zwidth, zlength;
5383 memset(&offsets, '\0', sizeof(struct offset));
5384 crop->bufftotal = 0;
5385 crop->combined_width = (uint32)0;
5386 crop->combined_length = (uint32)0;
5387 crop->selections = 0;
5389 /* Compute pixel offsets if margins or fixed width or length specified */
5390 if ((crop->crop_mode & CROP_MARGINS) ||
5391 (crop->crop_mode & CROP_REGIONS) ||
5392 (crop->crop_mode & CROP_LENGTH) ||
5393 (crop->crop_mode & CROP_WIDTH))
5395 if (computeInputPixelOffsets(crop, image, &offsets))
5397 TIFFError ("getCropOffsets", "Unable to compute crop margins");
5401 crop->selections = crop->regions;
5402 /* Regions are only calculated from top and left edges with no margins */
5403 if (crop->crop_mode & CROP_REGIONS)
5407 { /* cropped area is the full image */
5408 offsets.tmargin = 0;
5409 offsets.lmargin = 0;
5410 offsets.bmargin = 0;
5411 offsets.rmargin = 0;
5412 offsets.crop_width = image->width;
5413 offsets.crop_length = image->length;
5415 offsets.endx = image->width - 1;
5417 offsets.endy = image->length - 1;
5421 if (dump->outfile != NULL)
5423 dump_info (dump->outfile, dump->format, "", "Margins: Top: %d Left: %d Bottom: %d Right: %d",
5424 offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin);
5425 dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width: %6d Length: %6d",
5426 offsets.crop_width, offsets.crop_length);
5429 if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
5431 if (need_buff == FALSE) /* No margins or fixed width or length areas */
5433 crop->selections = 0;
5434 crop->combined_width = image->width;
5435 crop->combined_length = image->length;
5440 /* Use one region for margins and fixed width or length areas
5441 * even though it was not formally declared as a region.
5443 crop->selections = 1;
5445 crop->zonelist[0].total = 1;
5446 crop->zonelist[0].position = 1;
5450 crop->selections = crop->zones;
5452 for (i = 0; i < crop->zones; i++)
5454 seg = crop->zonelist[i].position;
5455 total = crop->zonelist[i].total;
5457 switch (crop->edge_ref)
5459 case EDGE_LEFT: /* zones from left to right, length from top */
5460 zlength = offsets.crop_length;
5461 crop->regionlist[i].y1 = offsets.starty;
5462 crop->regionlist[i].y2 = offsets.endy;
5464 crop->regionlist[i].x1 = offsets.startx +
5465 (uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
5466 test = (int32)offsets.startx +
5467 (int32)(offsets.crop_width * 1.0 * seg / total);
5469 crop->regionlist[i].x2 = 0;
5472 if (test > (int32)(image->width - 1))
5473 crop->regionlist[i].x2 = image->width - 1;
5475 crop->regionlist[i].x2 = test - 1;
5477 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5479 /* This is passed to extractCropZone or extractCompositeZones */
5480 crop->combined_length = (uint32)zlength;
5481 if (crop->exp_mode == COMPOSITE_IMAGES)
5482 crop->combined_width += (uint32)zwidth;
5484 crop->combined_width = (uint32)zwidth;
5486 case EDGE_BOTTOM: /* width from left, zones from bottom to top */
5487 zwidth = offsets.crop_width;
5488 crop->regionlist[i].x1 = offsets.startx;
5489 crop->regionlist[i].x2 = offsets.endx;
5491 test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
5493 crop->regionlist[i].y1 = 0;
5495 crop->regionlist[i].y1 = test + 1;
5497 test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total);
5499 crop->regionlist[i].y2 = 0;
5502 if (test > (int32)(image->length - 1))
5503 crop->regionlist[i].y2 = image->length - 1;
5505 crop->regionlist[i].y2 = test;
5507 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5509 /* This is passed to extractCropZone or extractCompositeZones */
5510 if (crop->exp_mode == COMPOSITE_IMAGES)
5511 crop->combined_length += (uint32)zlength;
5513 crop->combined_length = (uint32)zlength;
5514 crop->combined_width = (uint32)zwidth;
5516 case EDGE_RIGHT: /* zones from right to left, length from top */
5517 zlength = offsets.crop_length;
5518 crop->regionlist[i].y1 = offsets.starty;
5519 crop->regionlist[i].y2 = offsets.endy;
5521 crop->regionlist[i].x1 = offsets.startx +
5522 (uint32)(offsets.crop_width * (total - seg) * 1.0 / total);
5523 test = offsets.startx +
5524 (offsets.crop_width * (total - seg + 1) * 1.0 / total);
5526 crop->regionlist[i].x2 = 0;
5529 if (test > (int32)(image->width - 1))
5530 crop->regionlist[i].x2 = image->width - 1;
5532 crop->regionlist[i].x2 = test - 1;
5534 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5536 /* This is passed to extractCropZone or extractCompositeZones */
5537 crop->combined_length = (uint32)zlength;
5538 if (crop->exp_mode == COMPOSITE_IMAGES)
5539 crop->combined_width += (uint32)zwidth;
5541 crop->combined_width = (uint32)zwidth;
5543 case EDGE_TOP: /* width from left, zones from top to bottom */
5545 zwidth = offsets.crop_width;
5546 crop->regionlist[i].x1 = offsets.startx;
5547 crop->regionlist[i].x2 = offsets.endx;
5549 crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
5550 test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
5552 crop->regionlist[i].y2 = 0;
5555 if (test > (int32)(image->length - 1))
5556 crop->regionlist[i].y2 = image->length - 1;
5558 crop->regionlist[i].y2 = test - 1;
5560 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5562 /* This is passed to extractCropZone or extractCompositeZones */
5563 if (crop->exp_mode == COMPOSITE_IMAGES)
5564 crop->combined_length += (uint32)zlength;
5566 crop->combined_length = (uint32)zlength;
5567 crop->combined_width = (uint32)zwidth;
5569 } /* end switch statement */
5572 ((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
5573 crop->regionlist[i].width = (uint32) zwidth;
5574 crop->regionlist[i].length = (uint32) zlength;
5575 crop->regionlist[i].buffsize = buffsize;
5576 crop->bufftotal += buffsize;
5579 if (dump->outfile != NULL)
5580 dump_info (dump->outfile, dump->format, "", "Zone %d, width: %4d, length: %4d, x1: %4d x2: %4d y1: %4d y2: %4d",
5581 i + 1, (uint32)zwidth, (uint32)zlength,
5582 crop->regionlist[i].x1, crop->regionlist[i].x2,
5583 crop->regionlist[i].y1, crop->regionlist[i].y2);
5587 } /* end getCropOffsets */
5591 computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
5592 struct pagedef *page, struct pageseg *sections,
5593 struct dump_opts* dump)
5596 double pwidth, plength; /* Output page width and length in user units*/
5597 uint32 iwidth, ilength; /* Input image width and length in pixels*/
5598 uint32 owidth, olength; /* Output image width and length in pixels*/
5599 uint32 orows, ocols; /* rows and cols for output */
5600 uint32 hmargin, vmargin; /* Horizontal and vertical margins */
5601 uint32 x1, x2, y1, y2, line_bytes;
5602 /* unsigned int orientation; */
5606 if (page->res_unit == RESUNIT_NONE)
5607 page->res_unit = image->res_unit;
5609 switch (image->res_unit) {
5610 case RESUNIT_CENTIMETER:
5611 if (page->res_unit == RESUNIT_INCH)
5615 if (page->res_unit == RESUNIT_CENTIMETER)
5618 case RESUNIT_NONE: /* Dimensions in pixels */
5623 /* get width, height, resolutions of input image selection */
5624 if (crop->combined_width > 0)
5625 iwidth = crop->combined_width;
5627 iwidth = image->width;
5628 if (crop->combined_length > 0)
5629 ilength = crop->combined_length;
5631 ilength = image->length;
5633 if (page->hres <= 1.0)
5634 page->hres = image->xres;
5635 if (page->vres <= 1.0)
5636 page->vres = image->yres;
5638 if ((page->hres < 1.0) || (page->vres < 1.0))
5640 TIFFError("computeOutputPixelOffsets",
5641 "Invalid horizontal or vertical resolution specified or read from input image");
5645 /* If no page sizes are being specified, we just use the input image size to
5646 * calculate maximum margins that can be taken from image.
5648 if (page->width <= 0)
5651 pwidth = page->width;
5653 if (page->length <= 0)
5656 plength = page->length;
5660 TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
5661 "Hmargin: %3.2f, Vmargin: %3.2f",
5662 page->name, page->vres, page->hres,
5663 page->hmargin, page->vmargin);
5664 TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f",
5665 page->res_unit, scale, pwidth, plength);
5668 /* compute margins at specified unit and resolution */
5669 if (page->mode & PAGE_MODE_MARGINS)
5671 if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
5672 { /* inches or centimeters specified */
5673 hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
5674 vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
5677 { /* Otherwise user has specified pixels as reference unit */
5678 hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
5679 vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
5682 if ((hmargin * 2.0) > (pwidth * page->hres))
5684 TIFFError("computeOutputPixelOffsets",
5685 "Combined left and right margins exceed page width");
5686 hmargin = (uint32) 0;
5689 if ((vmargin * 2.0) > (plength * page->vres))
5691 TIFFError("computeOutputPixelOffsets",
5692 "Combined top and bottom margins exceed page length");
5693 vmargin = (uint32) 0;
5703 if (page->mode & PAGE_MODE_ROWSCOLS )
5705 /* Maybe someday but not for now */
5706 if (page->mode & PAGE_MODE_MARGINS)
5707 TIFFError("computeOutputPixelOffsets",
5708 "Output margins cannot be specified with rows and columns");
5710 owidth = TIFFhowmany(iwidth, page->cols);
5711 olength = TIFFhowmany(ilength, page->rows);
5715 if (page->mode & PAGE_MODE_PAPERSIZE )
5717 owidth = (uint32)((pwidth * page->hres) - (hmargin * 2));
5718 olength = (uint32)((plength * page->vres) - (vmargin * 2));
5722 owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
5723 olength = (uint32)(ilength - (vmargin * 2 * page->vres));
5727 if (owidth > iwidth)
5729 if (olength > ilength)
5732 /* Compute the number of pages required for Portrait or Landscape */
5733 switch (page->orient)
5735 case ORIENTATION_NONE:
5736 case ORIENTATION_PORTRAIT:
5737 ocols = TIFFhowmany(iwidth, owidth);
5738 orows = TIFFhowmany(ilength, olength);
5739 /* orientation = ORIENTATION_PORTRAIT; */
5742 case ORIENTATION_LANDSCAPE:
5743 ocols = TIFFhowmany(iwidth, olength);
5744 orows = TIFFhowmany(ilength, owidth);
5748 /* orientation = ORIENTATION_LANDSCAPE; */
5751 case ORIENTATION_AUTO:
5753 x1 = TIFFhowmany(iwidth, owidth);
5754 x2 = TIFFhowmany(ilength, olength);
5755 y1 = TIFFhowmany(iwidth, olength);
5756 y2 = TIFFhowmany(ilength, owidth);
5758 if ( (x1 * x2) < (y1 * y2))
5762 /* orientation = ORIENTATION_PORTRAIT; */
5771 /* orientation = ORIENTATION_LANDSCAPE; */
5780 /* If user did not specify rows and cols, set them from calcuation */
5786 line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
5788 if ((page->rows * page->cols) > MAX_SECTIONS)
5790 TIFFError("computeOutputPixelOffsets",
5791 "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
5795 /* build the list of offsets for each output section */
5796 for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
5798 y1 = (uint32)(olength * i);
5799 y2 = (uint32)(olength * (i + 1) - 1);
5802 for (j = 0; j < ocols; j++, k++)
5804 x1 = (uint32)(owidth * j);
5805 x2 = (uint32)(owidth * (j + 1) - 1);
5808 sections[k].x1 = x1;
5809 sections[k].x2 = x2;
5810 sections[k].y1 = y1;
5811 sections[k].y2 = y2;
5812 sections[k].buffsize = line_bytes * olength;
5813 sections[k].position = k + 1;
5814 sections[k].total = orows * ocols;
5818 } /* end computeOutputPixelOffsets */
5821 loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned char **read_ptr)
5824 float xres = 0.0, yres = 0.0;
5825 uint32 nstrips = 0, ntiles = 0;
5827 uint16 bps = 0, spp = 0, res_unit = 0;
5828 uint16 orientation = 0;
5829 uint16 input_compression = 0, input_photometric = 0;
5830 uint16 subsampling_horiz, subsampling_vert;
5831 uint32 width = 0, length = 0;
5832 uint32 stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
5833 uint32 tw = 0, tl = 0; /* Tile width and length */
5834 uint32 tile_rowsize = 0;
5835 unsigned char *read_buff = NULL;
5836 unsigned char *new_buff = NULL;
5838 static uint32 prev_readsize = 0;
5840 TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
5841 TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
5842 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
5843 TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
5844 if (! TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric))
5845 TIFFError("loadImage","Image lacks Photometric interpreation tag");
5846 if (! TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width))
5847 TIFFError("loadimage","Image lacks image width tag");
5848 if(! TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length))
5849 TIFFError("loadimage","Image lacks image length tag");
5850 TIFFGetFieldDefaulted(in, TIFFTAG_XRESOLUTION, &xres);
5851 TIFFGetFieldDefaulted(in, TIFFTAG_YRESOLUTION, &yres);
5852 if (!TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit))
5853 res_unit = RESUNIT_INCH;
5854 if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression))
5855 input_compression = COMPRESSION_NONE;
5858 char compressionid[16];
5860 switch (input_compression)
5862 case COMPRESSION_NONE: /* 1 dump mode */
5863 strcpy (compressionid, "None/dump");
5865 case COMPRESSION_CCITTRLE: /* 2 CCITT modified Huffman RLE */
5866 strcpy (compressionid, "Huffman RLE");
5868 case COMPRESSION_CCITTFAX3: /* 3 CCITT Group 3 fax encoding */
5869 strcpy (compressionid, "Group3 Fax");
5871 case COMPRESSION_CCITTFAX4: /* 4 CCITT Group 4 fax encoding */
5872 strcpy (compressionid, "Group4 Fax");
5874 case COMPRESSION_LZW: /* 5 Lempel-Ziv & Welch */
5875 strcpy (compressionid, "LZW");
5877 case COMPRESSION_OJPEG: /* 6 !6.0 JPEG */
5878 strcpy (compressionid, "Old Jpeg");
5880 case COMPRESSION_JPEG: /* 7 %JPEG DCT compression */
5881 strcpy (compressionid, "New Jpeg");
5883 case COMPRESSION_NEXT: /* 32766 NeXT 2-bit RLE */
5884 strcpy (compressionid, "Next RLE");
5886 case COMPRESSION_CCITTRLEW: /* 32771 #1 w/ word alignment */
5887 strcpy (compressionid, "CITTRLEW");
5889 case COMPRESSION_PACKBITS: /* 32773 Macintosh RLE */
5890 strcpy (compressionid, "Mac Packbits");
5892 case COMPRESSION_THUNDERSCAN: /* 32809 ThunderScan RLE */
5893 strcpy (compressionid, "Thunderscan");
5895 case COMPRESSION_IT8CTPAD: /* 32895 IT8 CT w/padding */
5896 strcpy (compressionid, "IT8 padded");
5898 case COMPRESSION_IT8LW: /* 32896 IT8 Linework RLE */
5899 strcpy (compressionid, "IT8 RLE");
5901 case COMPRESSION_IT8MP: /* 32897 IT8 Monochrome picture */
5902 strcpy (compressionid, "IT8 mono");
5904 case COMPRESSION_IT8BL: /* 32898 IT8 Binary line art */
5905 strcpy (compressionid, "IT8 lineart");
5907 case COMPRESSION_PIXARFILM: /* 32908 Pixar companded 10bit LZW */
5908 strcpy (compressionid, "Pixar 10 bit");
5910 case COMPRESSION_PIXARLOG: /* 32909 Pixar companded 11bit ZIP */
5911 strcpy (compressionid, "Pixar 11bit");
5913 case COMPRESSION_DEFLATE: /* 32946 Deflate compression */
5914 strcpy (compressionid, "Deflate");
5916 case COMPRESSION_ADOBE_DEFLATE: /* 8 Deflate compression */
5917 strcpy (compressionid, "Adobe deflate");
5920 strcpy (compressionid, "None/unknown");
5923 TIFFError("loadImage", "Input compression %s", compressionid);
5926 scanlinesize = TIFFScanlineSize(in);
5929 image->planar = planar;
5930 image->width = width;
5931 image->length = length;
5934 image->res_unit = res_unit;
5935 image->compression = input_compression;
5936 image->photometric = input_photometric;
5938 char photometricid[12];
5940 switch (input_photometric)
5942 case PHOTOMETRIC_MINISWHITE:
5943 strcpy (photometricid, "MinIsWhite");
5945 case PHOTOMETRIC_MINISBLACK:
5946 strcpy (photometricid, "MinIsBlack");
5948 case PHOTOMETRIC_RGB:
5949 strcpy (photometricid, "RGB");
5951 case PHOTOMETRIC_PALETTE:
5952 strcpy (photometricid, "Palette");
5954 case PHOTOMETRIC_MASK:
5955 strcpy (photometricid, "Mask");
5957 case PHOTOMETRIC_SEPARATED:
5958 strcpy (photometricid, "Separated");
5960 case PHOTOMETRIC_YCBCR:
5961 strcpy (photometricid, "YCBCR");
5963 case PHOTOMETRIC_CIELAB:
5964 strcpy (photometricid, "CIELab");
5966 case PHOTOMETRIC_ICCLAB:
5967 strcpy (photometricid, "ICCLab");
5969 case PHOTOMETRIC_ITULAB:
5970 strcpy (photometricid, "ITULab");
5972 case PHOTOMETRIC_LOGL:
5973 strcpy (photometricid, "LogL");
5975 case PHOTOMETRIC_LOGLUV:
5976 strcpy (photometricid, "LOGLuv");
5979 strcpy (photometricid, "Unknown");
5982 TIFFError("loadImage", "Input photometric interpretation %s", photometricid);
5985 image->orientation = orientation;
5986 switch (orientation)
5989 case ORIENTATION_TOPLEFT:
5990 image->adjustments = 0;
5992 case ORIENTATION_TOPRIGHT:
5993 image->adjustments = MIRROR_HORIZ;
5995 case ORIENTATION_BOTRIGHT:
5996 image->adjustments = ROTATECW_180;
5998 case ORIENTATION_BOTLEFT:
5999 image->adjustments = MIRROR_VERT;
6001 case ORIENTATION_LEFTTOP:
6002 image->adjustments = MIRROR_VERT | ROTATECW_90;
6004 case ORIENTATION_RIGHTTOP:
6005 image->adjustments = ROTATECW_90;
6007 case ORIENTATION_RIGHTBOT:
6008 image->adjustments = MIRROR_VERT | ROTATECW_270;
6010 case ORIENTATION_LEFTBOT:
6011 image->adjustments = ROTATECW_270;
6014 image->adjustments = 0;
6015 image->orientation = ORIENTATION_TOPLEFT;
6018 if ((bps == 0) || (spp == 0))
6020 TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
6025 if (TIFFIsTiled(in))
6028 tlsize = TIFFTileSize(in);
6029 ntiles = TIFFNumberOfTiles(in);
6030 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
6031 TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
6033 tile_rowsize = TIFFTileRowSize(in);
6034 if (ntiles == 0 || tlsize == 0 || tile_rowsize == 0)
6036 TIFFError("loadImage", "File appears to be tiled, but the number of tiles, tile size, or tile rowsize is zero.");
6039 buffsize = tlsize * ntiles;
6040 if (tlsize != (buffsize / ntiles))
6042 TIFFError("loadImage", "Integer overflow when calculating buffer size");
6046 if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
6048 buffsize = ntiles * tl * tile_rowsize;
6049 if (ntiles != (buffsize / tl / tile_rowsize))
6051 TIFFError("loadImage", "Integer overflow when calculating buffer size");
6056 TIFFError("loadImage",
6057 "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
6058 tlsize, (unsigned long)buffsize);
6062 if (dump->infile != NULL)
6063 dump_info (dump->infile, dump->format, "",
6064 "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
6065 tlsize, ntiles, tile_rowsize);
6069 uint32 buffsize_check;
6071 TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
6072 stsize = TIFFStripSize(in);
6073 nstrips = TIFFNumberOfStrips(in);
6074 if (nstrips == 0 || stsize == 0)
6076 TIFFError("loadImage", "File appears to be striped, but the number of stipes or stripe size is zero.");
6080 buffsize = stsize * nstrips;
6081 if (stsize != (buffsize / nstrips))
6083 TIFFError("loadImage", "Integer overflow when calculating buffer size");
6086 buffsize_check = ((length * width * spp * bps) + 7);
6087 if (length != ((buffsize_check - 7) / width / spp / bps))
6089 TIFFError("loadImage", "Integer overflow detected.");
6092 if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
6094 buffsize = ((length * width * spp * bps) + 7) / 8;
6096 TIFFError("loadImage",
6097 "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
6098 stsize, (unsigned long)buffsize);
6102 if (dump->infile != NULL)
6103 dump_info (dump->infile, dump->format, "",
6104 "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
6105 stsize, nstrips, rowsperstrip, scanlinesize);
6108 if (input_compression == COMPRESSION_JPEG)
6109 { /* Force conversion to RGB */
6110 jpegcolormode = JPEGCOLORMODE_RGB;
6111 TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
6113 /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
6115 { /* Otherwise, can't handle subsampled input */
6116 if (input_photometric == PHOTOMETRIC_YCBCR)
6118 TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
6119 &subsampling_horiz, &subsampling_vert);
6120 if (subsampling_horiz != 1 || subsampling_vert != 1)
6122 TIFFError("loadImage",
6123 "Can't copy/convert subsampled image with subsampling %d horiz %d vert",
6124 subsampling_horiz, subsampling_vert);
6130 read_buff = *read_ptr;
6131 /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */
6132 /* outside buffer */
6135 if( buffsize > 0xFFFFFFFFU - 3 )
6137 TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6140 read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
6144 if (prev_readsize < buffsize)
6146 if( buffsize > 0xFFFFFFFFU - 3 )
6148 TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6151 new_buff = _TIFFrealloc(read_buff, buffsize+3);
6155 read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
6158 read_buff = new_buff;
6163 TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6167 read_buff[buffsize] = 0;
6168 read_buff[buffsize+1] = 0;
6169 read_buff[buffsize+2] = 0;
6171 prev_readsize = buffsize;
6172 *read_ptr = read_buff;
6174 /* N.B. The read functions used copy separate plane data into a buffer as interleaved
6175 * samples rather than separate planes so the same logic works to extract regions
6176 * regardless of the way the data are organized in the input file.
6180 if (planar == PLANARCONFIG_CONTIG)
6182 if (!(readContigStripsIntoBuffer(in, read_buff)))
6184 TIFFError("loadImage", "Unable to read contiguous strips into buffer");
6190 if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
6192 TIFFError("loadImage", "Unable to read separate strips into buffer");
6199 if (planar == PLANARCONFIG_CONTIG)
6201 if (!(readContigTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6203 TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
6209 if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6211 TIFFError("loadImage", "Unable to read separate tiles into buffer");
6216 default: TIFFError("loadImage", "Unsupported image file format");
6220 if ((dump->infile != NULL) && (dump->level == 2))
6222 dump_info (dump->infile, dump->format, "loadImage",
6223 "Image width %d, length %d, Raw image data, %4d bytes",
6224 width, length, buffsize);
6225 dump_info (dump->infile, dump->format, "",
6226 "Bits per sample %d, Samples per pixel %d", bps, spp);
6228 for (i = 0; i < length; i++)
6229 dump_buffer(dump->infile, dump->format, 1, scanlinesize,
6230 i, read_buff + (i * scanlinesize));
6233 } /* end loadImage */
6235 static int correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
6237 uint16 mirror, rotation;
6238 unsigned char *work_buff;
6240 work_buff = *work_buff_ptr;
6241 if ((image == NULL) || (work_buff == NULL))
6243 TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
6247 if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
6249 mirror = (uint16)(image->adjustments & MIRROR_BOTH);
6250 if (mirrorImage(image->spp, image->bps, mirror,
6251 image->width, image->length, work_buff))
6253 TIFFError ("correct_orientation", "Unable to mirror image");
6258 if (image->adjustments & ROTATE_ANY)
6260 if (image->adjustments & ROTATECW_90)
6261 rotation = (uint16) 90;
6263 if (image->adjustments & ROTATECW_180)
6264 rotation = (uint16) 180;
6266 if (image->adjustments & ROTATECW_270)
6267 rotation = (uint16) 270;
6270 TIFFError ("correct_orientation", "Invalid rotation value: %d",
6271 image->adjustments & ROTATE_ANY);
6275 if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
6277 TIFFError ("correct_orientation", "Unable to rotate image");
6280 image->orientation = ORIENTATION_TOPLEFT;
6284 } /* end correct_orientation */
6287 /* Extract multiple zones from an image and combine into a single composite image */
6289 extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
6290 unsigned char *read_buff, unsigned char *crop_buff)
6292 int shift_width, bytes_per_sample, bytes_per_pixel;
6293 uint32 i, trailing_bits, prev_trailing_bits;
6294 uint32 row, first_row, last_row, first_col, last_col;
6295 uint32 src_rowsize, dst_rowsize, src_offset, dst_offset;
6296 uint32 crop_width, crop_length, img_width /*, img_length */;
6297 uint32 prev_length, prev_width, composite_width;
6300 tsample_t count, sample = 0; /* Update to extract one or more samples */
6302 img_width = image->width;
6303 /* img_length = image->length; */
6308 bytes_per_sample = (bps + 7) / 8;
6309 bytes_per_pixel = ((bps * spp) + 7) / 8;
6314 if (bytes_per_pixel < (bytes_per_sample + 1))
6315 shift_width = bytes_per_pixel;
6317 shift_width = bytes_per_sample + 1;
6322 /* These are setup for adding additional sections */
6323 prev_width = prev_length = 0;
6324 prev_trailing_bits = trailing_bits = 0;
6325 composite_width = crop->combined_width;
6326 crop->combined_width = 0;
6327 crop->combined_length = 0;
6329 for (i = 0; i < crop->selections; i++)
6331 /* rows, columns, width, length are expressed in pixels */
6332 first_row = crop->regionlist[i].y1;
6333 last_row = crop->regionlist[i].y2;
6334 first_col = crop->regionlist[i].x1;
6335 last_col = crop->regionlist[i].x2;
6337 crop_width = last_col - first_col + 1;
6338 crop_length = last_row - first_row + 1;
6340 /* These should not be needed for composite images */
6341 crop->regionlist[i].width = crop_width;
6342 crop->regionlist[i].length = crop_length;
6343 crop->regionlist[i].buffptr = crop_buff;
6345 src_rowsize = ((img_width * bps * spp) + 7) / 8;
6346 dst_rowsize = (((crop_width * bps * count) + 7) / 8);
6348 switch (crop->edge_ref)
6353 if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
6355 TIFFError ("extractCompositeRegions",
6356 "Only equal width regions can be combined for -E top or bottom");
6360 crop->combined_width = crop_width;
6361 crop->combined_length += crop_length;
6363 for (row = first_row; row <= last_row; row++)
6365 src_offset = row * src_rowsize;
6366 dst_offset = (row - first_row) * dst_rowsize;
6367 src = read_buff + src_offset;
6368 dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
6369 switch (shift_width)
6371 case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6372 spp, bps, count, first_col,
6375 TIFFError("extractCompositeRegions",
6376 "Unable to extract row %d", row);
6380 case 1: if (bps == 1)
6382 if (extractContigSamplesShifted8bits (src, dst, img_width,
6383 sample, spp, bps, count,
6384 first_col, last_col + 1,
6385 prev_trailing_bits))
6387 TIFFError("extractCompositeRegions",
6388 "Unable to extract row %d", row);
6394 if (extractContigSamplesShifted16bits (src, dst, img_width,
6395 sample, spp, bps, count,
6396 first_col, last_col + 1,
6397 prev_trailing_bits))
6399 TIFFError("extractCompositeRegions",
6400 "Unable to extract row %d", row);
6404 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6405 sample, spp, bps, count,
6406 first_col, last_col + 1,
6407 prev_trailing_bits))
6409 TIFFError("extractCompositeRegions",
6410 "Unable to extract row %d", row);
6416 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6417 sample, spp, bps, count,
6418 first_col, last_col + 1,
6419 prev_trailing_bits))
6421 TIFFError("extractCompositeRegions",
6422 "Unable to extract row %d", row);
6426 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6430 prev_length += crop_length;
6432 case EDGE_LEFT: /* splice the pieces of each row together, side by side */
6434 if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
6436 TIFFError ("extractCompositeRegions",
6437 "Only equal length regions can be combined for -E left or right");
6440 crop->combined_width += crop_width;
6441 crop->combined_length = crop_length;
6442 dst_rowsize = (((composite_width * bps * count) + 7) / 8);
6443 trailing_bits = (crop_width * bps * count) % 8;
6444 for (row = first_row; row <= last_row; row++)
6446 src_offset = row * src_rowsize;
6447 dst_offset = (row - first_row) * dst_rowsize;
6448 src = read_buff + src_offset;
6449 dst = crop_buff + dst_offset + prev_width;
6451 switch (shift_width)
6453 case 0: if (extractContigSamplesBytes (src, dst, img_width,
6454 sample, spp, bps, count,
6455 first_col, last_col + 1))
6457 TIFFError("extractCompositeRegions",
6458 "Unable to extract row %d", row);
6462 case 1: if (bps == 1)
6464 if (extractContigSamplesShifted8bits (src, dst, img_width,
6465 sample, spp, bps, count,
6466 first_col, last_col + 1,
6467 prev_trailing_bits))
6469 TIFFError("extractCompositeRegions",
6470 "Unable to extract row %d", row);
6476 if (extractContigSamplesShifted16bits (src, dst, img_width,
6477 sample, spp, bps, count,
6478 first_col, last_col + 1,
6479 prev_trailing_bits))
6481 TIFFError("extractCompositeRegions",
6482 "Unable to extract row %d", row);
6486 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6487 sample, spp, bps, count,
6488 first_col, last_col + 1,
6489 prev_trailing_bits))
6491 TIFFError("extractCompositeRegions",
6492 "Unable to extract row %d", row);
6498 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6499 sample, spp, bps, count,
6500 first_col, last_col + 1,
6501 prev_trailing_bits))
6503 TIFFError("extractCompositeRegions",
6504 "Unable to extract row %d", row);
6508 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6512 prev_width += (crop_width * bps * count) / 8;
6513 prev_trailing_bits += trailing_bits;
6514 if (prev_trailing_bits > 7)
6515 prev_trailing_bits-= 8;
6519 if (crop->combined_width != composite_width)
6520 TIFFError("combineSeparateRegions","Combined width does not match composite width");
6523 } /* end extractCompositeRegions */
6525 /* Copy a single region of input buffer to an output buffer.
6526 * The read functions used copy separate plane data into a buffer
6527 * as interleaved samples rather than separate planes so the same
6528 * logic works to extract regions regardless of the way the data
6529 * are organized in the input file. This function can be used to
6530 * extract one or more samples from the input image by updating the
6531 * parameters for starting sample and number of samples to copy in the
6532 * fifth and eighth arguments of the call to extractContigSamples.
6533 * They would be passed as new elements of the crop_mask struct.
6537 extractSeparateRegion(struct image_data *image, struct crop_mask *crop,
6538 unsigned char *read_buff, unsigned char *crop_buff,
6541 int shift_width, prev_trailing_bits = 0;
6542 uint32 bytes_per_sample, bytes_per_pixel;
6543 uint32 src_rowsize, dst_rowsize;
6544 uint32 row, first_row, last_row, first_col, last_col;
6545 uint32 src_offset, dst_offset;
6546 uint32 crop_width, crop_length, img_width /*, img_length */;
6549 tsample_t count, sample = 0; /* Update to extract more or more samples */
6551 img_width = image->width;
6552 /* img_length = image->length; */
6557 bytes_per_sample = (bps + 7) / 8;
6558 bytes_per_pixel = ((bps * spp) + 7) / 8;
6560 shift_width = 0; /* Byte aligned data only */
6563 if (bytes_per_pixel < (bytes_per_sample + 1))
6564 shift_width = bytes_per_pixel;
6566 shift_width = bytes_per_sample + 1;
6569 /* rows, columns, width, length are expressed in pixels */
6570 first_row = crop->regionlist[region].y1;
6571 last_row = crop->regionlist[region].y2;
6572 first_col = crop->regionlist[region].x1;
6573 last_col = crop->regionlist[region].x2;
6575 crop_width = last_col - first_col + 1;
6576 crop_length = last_row - first_row + 1;
6578 crop->regionlist[region].width = crop_width;
6579 crop->regionlist[region].length = crop_length;
6580 crop->regionlist[region].buffptr = crop_buff;
6584 src_rowsize = ((img_width * bps * spp) + 7) / 8;
6585 dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
6587 for (row = first_row; row <= last_row; row++)
6589 src_offset = row * src_rowsize;
6590 dst_offset = (row - first_row) * dst_rowsize;
6591 src = read_buff + src_offset;
6592 dst = crop_buff + dst_offset;
6594 switch (shift_width)
6596 case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6597 spp, bps, count, first_col,
6600 TIFFError("extractSeparateRegion",
6601 "Unable to extract row %d", row);
6605 case 1: if (bps == 1)
6607 if (extractContigSamplesShifted8bits (src, dst, img_width,
6608 sample, spp, bps, count,
6609 first_col, last_col + 1,
6610 prev_trailing_bits))
6612 TIFFError("extractSeparateRegion",
6613 "Unable to extract row %d", row);
6619 if (extractContigSamplesShifted16bits (src, dst, img_width,
6620 sample, spp, bps, count,
6621 first_col, last_col + 1,
6622 prev_trailing_bits))
6624 TIFFError("extractSeparateRegion",
6625 "Unable to extract row %d", row);
6629 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6630 sample, spp, bps, count,
6631 first_col, last_col + 1,
6632 prev_trailing_bits))
6634 TIFFError("extractSeparateRegion",
6635 "Unable to extract row %d", row);
6641 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6642 sample, spp, bps, count,
6643 first_col, last_col + 1,
6644 prev_trailing_bits))
6646 TIFFError("extractSeparateRegion",
6647 "Unable to extract row %d", row);
6651 default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
6657 } /* end extractSeparateRegion */
6660 extractImageSection(struct image_data *image, struct pageseg *section,
6661 unsigned char *src_buff, unsigned char *sect_buff)
6663 unsigned char bytebuff1, bytebuff2;
6665 /* unsigned char *src, *dst; */
6668 uint32 img_width, img_rowsize;
6672 uint32 j, shift1, shift2, trailing_bits;
6673 uint32 row, first_row, last_row, first_col, last_col;
6674 uint32 src_offset, dst_offset, row_offset, col_offset;
6675 uint32 offset1, offset2, full_bytes;
6684 unsigned char bitset;
6685 static char *bitarray = NULL;
6688 img_width = image->width;
6690 img_length = image->length;
6696 /* src = src_buff; */
6697 /* dst = sect_buff; */
6703 if (bitarray == NULL)
6705 if ((bitarray = (char *)malloc(img_width)) == NULL)
6707 TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
6713 /* rows, columns, width, length are expressed in pixels */
6714 first_row = section->y1;
6715 last_row = section->y2;
6716 first_col = section->x1;
6717 last_col = section->x2;
6719 sect_width = last_col - first_col + 1;
6721 sect_length = last_row - first_row + 1;
6723 img_rowsize = ((img_width * bps + 7) / 8) * spp;
6724 full_bytes = (sect_width * spp * bps) / 8; /* number of COMPLETE bytes per row in section */
6725 trailing_bits = (sect_width * bps) % 8;
6728 TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
6729 first_row, last_row, first_col, last_col);
6730 TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
6731 img_width, img_length, bps, spp);
6732 TIFFError ("", "Sect width: %d, Sect length: %d, full bytes: %d trailing bits %d\n",
6733 sect_width, sect_length, full_bytes, trailing_bits);
6738 col_offset = first_col * spp * bps / 8;
6739 for (row = first_row; row <= last_row; row++)
6741 /* row_offset = row * img_width * spp * bps / 8; */
6742 row_offset = row * img_rowsize;
6743 src_offset = row_offset + col_offset;
6746 TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset, dst_offset);
6748 _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
6749 dst_offset += full_bytes;
6754 shift1 = spp * ((first_col * bps) % 8);
6755 shift2 = spp * ((last_col * bps) % 8);
6756 for (row = first_row; row <= last_row; row++)
6758 /* pull out the first byte */
6759 row_offset = row * img_rowsize;
6760 offset1 = row_offset + (first_col * bps / 8);
6761 offset2 = row_offset + (last_col * bps / 8);
6764 for (j = 0, k = 7; j < 8; j++, k--)
6766 bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
6767 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6769 sprintf(&bitarray[8], " ");
6770 sprintf(&bitarray[9], " ");
6771 for (j = 10, k = 7; j < 18; j++, k--)
6773 bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
6774 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6776 bitarray[18] = '\0';
6777 TIFFError ("", "Row: %3d Offset1: %d, Shift1: %d, Offset2: %d, Shift2: %d\n",
6778 row, offset1, shift1, offset2, shift2);
6781 bytebuff1 = bytebuff2 = 0;
6782 if (shift1 == 0) /* the region is byte and sample aligned */
6784 _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
6787 TIFFError ("", " Aligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset);
6788 sprintf(&bitarray[18], "\n");
6789 sprintf(&bitarray[19], "\t");
6790 for (j = 20, k = 7; j < 28; j++, k--)
6792 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6793 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6798 dst_offset += full_bytes;
6800 if (trailing_bits != 0)
6802 bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
6803 sect_buff[dst_offset] = bytebuff2;
6805 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n",
6806 offset2, dst_offset);
6807 for (j = 30, k = 7; j < 38; j++, k--)
6809 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6810 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6812 bitarray[38] = '\0';
6813 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6818 else /* each destination byte will have to be built from two source bytes*/
6821 TIFFError ("", " Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset);
6823 for (j = 0; j <= full_bytes; j++)
6825 bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
6826 bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
6827 sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
6830 sprintf(&bitarray[18], "\n");
6831 sprintf(&bitarray[19], "\t");
6832 for (j = 20, k = 7; j < 28; j++, k--)
6834 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6835 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6840 dst_offset += full_bytes;
6842 if (trailing_bits != 0)
6845 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset);
6847 if (shift2 > shift1)
6849 bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
6850 bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
6851 sect_buff[dst_offset] = bytebuff2;
6853 TIFFError ("", " Shift2 > Shift1\n");
6858 if (shift2 < shift1)
6860 bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
6861 sect_buff[dst_offset] &= bytebuff2;
6863 TIFFError ("", " Shift2 < Shift1\n");
6868 TIFFError ("", " Shift2 == Shift1\n");
6873 sprintf(&bitarray[28], " ");
6874 sprintf(&bitarray[29], " ");
6875 for (j = 30, k = 7; j < 38; j++, k--)
6877 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6878 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6880 bitarray[38] = '\0';
6881 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6889 } /* end extractImageSection */
6892 writeSelections(TIFF *in, TIFF **out, struct crop_mask *crop,
6893 struct image_data *image, struct dump_opts *dump,
6894 struct buffinfo seg_buffs[], char *mp, char *filename,
6895 unsigned int *page, unsigned int total_pages)
6899 unsigned char *crop_buff = NULL;
6901 /* Where we open a new file depends on the export mode */
6902 switch (crop->exp_mode)
6904 case ONE_FILE_COMPOSITE: /* Regions combined into single image */
6906 crop_buff = seg_buffs[0].buffer;
6907 if (update_output_file (out, mp, autoindex, filename, page))
6909 page_count = total_pages;
6910 if (writeCroppedImage(in, *out, image, dump,
6911 crop->combined_width,
6912 crop->combined_length,
6913 crop_buff, *page, total_pages))
6915 TIFFError("writeRegions", "Unable to write new image");
6919 case ONE_FILE_SEPARATED: /* Regions as separated images */
6921 if (update_output_file (out, mp, autoindex, filename, page))
6923 page_count = crop->selections * total_pages;
6924 for (i = 0; i < crop->selections; i++)
6926 crop_buff = seg_buffs[i].buffer;
6927 if (writeCroppedImage(in, *out, image, dump,
6928 crop->regionlist[i].width,
6929 crop->regionlist[i].length,
6930 crop_buff, *page, page_count))
6932 TIFFError("writeRegions", "Unable to write new image");
6937 case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
6939 if (update_output_file (out, mp, autoindex, filename, page))
6942 crop_buff = seg_buffs[0].buffer;
6943 if (writeCroppedImage(in, *out, image, dump,
6944 crop->combined_width,
6945 crop->combined_length,
6946 crop_buff, *page, total_pages))
6948 TIFFError("writeRegions", "Unable to write new image");
6952 case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
6954 page_count = crop->selections;
6955 if (update_output_file (out, mp, autoindex, filename, page))
6958 for (i = 0; i < crop->selections; i++)
6960 crop_buff = seg_buffs[i].buffer;
6961 /* Write the current region to the current file */
6962 if (writeCroppedImage(in, *out, image, dump,
6963 crop->regionlist[i].width,
6964 crop->regionlist[i].length,
6965 crop_buff, *page, page_count))
6967 TIFFError("writeRegions", "Unable to write new image");
6972 case FILE_PER_SELECTION:
6975 for (i = 0; i < crop->selections; i++)
6977 if (update_output_file (out, mp, autoindex, filename, page))
6980 crop_buff = seg_buffs[i].buffer;
6981 /* Write the current region to the current file */
6982 if (writeCroppedImage(in, *out, image, dump,
6983 crop->regionlist[i].width,
6984 crop->regionlist[i].length,
6985 crop_buff, *page, page_count))
6987 TIFFError("writeRegions", "Unable to write new image");
6992 default: return (1);
6996 } /* end writeRegions */
6999 writeImageSections(TIFF *in, TIFF *out, struct image_data *image,
7000 struct pagedef *page, struct pageseg *sections,
7001 struct dump_opts * dump, unsigned char *src_buff,
7002 unsigned char **sect_buff_ptr)
7005 uint32 i, k, width, length, sectsize;
7006 unsigned char *sect_buff = *sect_buff_ptr;
7011 k = page->cols * page->rows;
7012 if ((k < 1) || (k > MAX_SECTIONS))
7014 TIFFError("writeImageSections",
7015 "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
7019 for (i = 0; i < k; i++)
7021 width = sections[i].x2 - sections[i].x1 + 1;
7022 length = sections[i].y2 - sections[i].y1 + 1;
7024 ceil((width * image->bps + 7) / (double)8) * image->spp * length;
7025 /* allocate a buffer if we don't have one already */
7026 if (createImageSection(sectsize, sect_buff_ptr))
7028 TIFFError("writeImageSections", "Unable to allocate section buffer");
7031 sect_buff = *sect_buff_ptr;
7033 if (extractImageSection (image, §ions[i], src_buff, sect_buff))
7035 TIFFError("writeImageSections", "Unable to extract image sections");
7039 /* call the write routine here instead of outside the loop */
7040 if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
7042 TIFFError("writeImageSections", "Unable to write image section");
7048 } /* end writeImageSections */
7050 /* Code in this function is heavily indebted to code in tiffcp
7051 * with modifications by Richard Nolde to handle orientation correctly.
7052 * It will have to be updated significantly if support is added to
7053 * extract one or more samples from original image since the
7054 * original code assumes we are always copying all samples.
7057 writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
7058 struct dump_opts *dump, uint32 width, uint32 length,
7059 double hres, double vres,
7060 unsigned char *sect_buff)
7063 uint16 input_compression, input_photometric;
7064 uint16 input_planar;
7067 /* Calling this seems to reset the compression mode on the TIFF *in file.
7068 TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
7070 input_compression = image->compression;
7071 input_photometric = image->photometric;
7075 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
7076 TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
7077 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
7078 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
7081 TIFFError("writeSingleSection", "Input compression: %s",
7082 (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
7083 ((input_compression == COMPRESSION_JPEG) ? "New Jpeg" : "Non Jpeg"));
7085 /* This is the global variable compression which is set
7086 * if the user has specified a command line option for
7087 * a compression option. Should be passed around in one
7088 * of the parameters instead of as a global. If no user
7089 * option specified it will still be (uint16) -1. */
7090 if (compression != (uint16)-1)
7091 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
7093 { /* OJPEG is no longer supported for writing so upgrade to JPEG */
7094 if (input_compression == COMPRESSION_OJPEG)
7096 compression = COMPRESSION_JPEG;
7097 jpegcolormode = JPEGCOLORMODE_RAW;
7098 TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
7100 else /* Use the compression from the input file */
7101 CopyField(TIFFTAG_COMPRESSION, compression);
7104 if (compression == COMPRESSION_JPEG)
7106 if ((input_photometric == PHOTOMETRIC_PALETTE) || /* color map indexed */
7107 (input_photometric == PHOTOMETRIC_MASK)) /* holdout mask */
7109 TIFFError ("writeSingleSection",
7110 "JPEG compression cannot be used with %s image data",
7111 (input_photometric == PHOTOMETRIC_PALETTE) ?
7112 "palette" : "mask");
7115 if ((input_photometric == PHOTOMETRIC_RGB) &&
7116 (jpegcolormode == JPEGCOLORMODE_RGB))
7117 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
7119 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
7123 if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
7124 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7125 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7127 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
7131 TIFFError("writeSingleSection", "Input photometric: %s",
7132 (input_photometric == PHOTOMETRIC_RGB) ? "RGB" :
7133 ((input_photometric == PHOTOMETRIC_YCBCR) ? "YCbCr" : "Not RGB or YCbCr"));
7136 if (((input_photometric == PHOTOMETRIC_LOGL) ||
7137 (input_photometric == PHOTOMETRIC_LOGLUV)) &&
7138 ((compression != COMPRESSION_SGILOG) &&
7139 (compression != COMPRESSION_SGILOG24)))
7141 TIFFError("writeSingleSection",
7142 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
7147 TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
7149 CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
7151 /* The loadimage function reads input orientation and sets
7152 * image->orientation. The correct_image_orientation function
7153 * applies the required rotation and mirror operations to
7154 * present the data in TOPLEFT orientation and updates
7155 * image->orientation if any transforms are performed,
7156 * as per EXIF standard.
7158 TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
7161 * Choose tiles/strip for the output image according to
7162 * the command line arguments (-tiles, -strips) and the
7163 * structure of the input image.
7166 outtiled = TIFFIsTiled(in);
7169 * Setup output file's tile width&height. If either
7170 * is not specified, use either the value from the
7171 * input image or, if nothing is defined, use the
7174 if (tilewidth == (uint32) 0)
7175 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7176 if (tilelength == (uint32) 0)
7177 TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7179 if (tilewidth == 0 || tilelength == 0)
7180 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7181 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7182 TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7183 TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7186 * RowsPerStrip is left unspecified: use either the
7187 * value from the input image or, if nothing is defined,
7188 * use the library default.
7190 if (rowsperstrip == (uint32) 0)
7192 if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7193 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7194 if (compression != COMPRESSION_JPEG)
7196 if (rowsperstrip > length)
7197 rowsperstrip = length;
7201 if (rowsperstrip == (uint32) -1)
7202 rowsperstrip = length;
7203 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7206 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7207 if (config != (uint16) -1)
7208 TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7210 CopyField(TIFFTAG_PLANARCONFIG, config);
7212 CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7213 CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7215 /* SMinSampleValue & SMaxSampleValue */
7216 switch (compression) {
7217 /* These are references to GLOBAL variables set by defaults
7218 * and /or the compression flag
7220 case COMPRESSION_JPEG:
7221 if (((bps % 8) == 0) || ((bps % 12) == 0))
7223 TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7224 TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7228 TIFFError("writeSingleSection",
7229 "JPEG compression requires 8 or 12 bits per sample");
7233 case COMPRESSION_LZW:
7234 case COMPRESSION_ADOBE_DEFLATE:
7235 case COMPRESSION_DEFLATE:
7236 if (predictor != (uint16)-1)
7237 TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7239 CopyField(TIFFTAG_PREDICTOR, predictor);
7241 case COMPRESSION_CCITTFAX3:
7242 case COMPRESSION_CCITTFAX4:
7243 if (compression == COMPRESSION_CCITTFAX3) {
7244 if (g3opts != (uint32) -1)
7245 TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7247 CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7249 CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7251 CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7252 CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7253 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7254 CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7255 CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7256 CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7261 if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7262 TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7265 const char* inknames;
7266 if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7267 TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7268 if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7269 int inknameslen = strlen(inknames) + 1;
7270 const char* cp = inknames;
7272 cp = strchr(cp, '\0');
7275 inknameslen += (strlen(cp) + 1);
7279 TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7284 unsigned short pg0, pg1;
7285 if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7286 if (pageNum < 0) /* only one input file */
7287 TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
7289 TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
7293 for (p = tags; p < &tags[NTAGS]; p++)
7294 CopyTag(p->tag, p->count, p->type);
7296 /* Update these since they are overwritten from input res by loop above */
7297 TIFFSetField(out, TIFFTAG_XRESOLUTION, (float)hres);
7298 TIFFSetField(out, TIFFTAG_YRESOLUTION, (float)vres);
7300 /* Compute the tile or strip dimensions and write to disk */
7303 if (config == PLANARCONFIG_CONTIG)
7304 writeBufferToContigTiles (out, sect_buff, length, width, spp, dump);
7306 writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
7310 if (config == PLANARCONFIG_CONTIG)
7311 writeBufferToContigStrips (out, sect_buff, length);
7313 writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
7316 if (!TIFFWriteDirectory(out))
7323 } /* end writeSingleSection */
7326 /* Create a buffer to write one section at a time */
7328 createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
7330 unsigned char *sect_buff = NULL;
7331 unsigned char *new_buff = NULL;
7332 static uint32 prev_sectsize = 0;
7334 sect_buff = *sect_buff_ptr;
7338 sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7339 *sect_buff_ptr = sect_buff;
7340 _TIFFmemset(sect_buff, 0, sectsize);
7344 if (prev_sectsize < sectsize)
7346 new_buff = _TIFFrealloc(sect_buff, sectsize);
7350 sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7353 sect_buff = new_buff;
7355 _TIFFmemset(sect_buff, 0, sectsize);
7361 TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
7364 prev_sectsize = sectsize;
7365 *sect_buff_ptr = sect_buff;
7368 } /* end createImageSection */
7371 /* Process selections defined by regions, zones, margins, or fixed sized areas */
7373 processCropSelections(struct image_data *image, struct crop_mask *crop,
7374 unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
7377 uint32 width, length, total_width, total_length;
7379 unsigned char *crop_buff = NULL;
7380 unsigned char *read_buff = NULL;
7381 unsigned char *next_buff = NULL;
7382 tsize_t prev_cropsize = 0;
7384 read_buff = *read_buff_ptr;
7386 if (crop->img_mode == COMPOSITE_IMAGES)
7388 cropsize = crop->bufftotal;
7389 crop_buff = seg_buffs[0].buffer;
7391 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7394 prev_cropsize = seg_buffs[0].size;
7395 if (prev_cropsize < cropsize)
7397 next_buff = _TIFFrealloc(crop_buff, cropsize);
7400 _TIFFfree (crop_buff);
7401 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7404 crop_buff = next_buff;
7410 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7414 _TIFFmemset(crop_buff, 0, cropsize);
7415 seg_buffs[0].buffer = crop_buff;
7416 seg_buffs[0].size = cropsize;
7418 /* Checks for matching width or length as required */
7419 if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
7422 if (crop->crop_mode & CROP_INVERT)
7424 switch (crop->photometric)
7426 /* Just change the interpretation */
7427 case PHOTOMETRIC_MINISWHITE:
7428 case PHOTOMETRIC_MINISBLACK:
7429 image->photometric = crop->photometric;
7431 case INVERT_DATA_ONLY:
7432 case INVERT_DATA_AND_TAG:
7433 if (invertImage(image->photometric, image->spp, image->bps,
7434 crop->combined_width, crop->combined_length, crop_buff))
7436 TIFFError("processCropSelections",
7437 "Failed to invert colorspace for composite regions");
7440 if (crop->photometric == INVERT_DATA_AND_TAG)
7442 switch (image->photometric)
7444 case PHOTOMETRIC_MINISWHITE:
7445 image->photometric = PHOTOMETRIC_MINISBLACK;
7447 case PHOTOMETRIC_MINISBLACK:
7448 image->photometric = PHOTOMETRIC_MINISWHITE;
7459 /* Mirror and Rotate will not work with multiple regions unless they are the same width */
7460 if (crop->crop_mode & CROP_MIRROR)
7462 if (mirrorImage(image->spp, image->bps, crop->mirror,
7463 crop->combined_width, crop->combined_length, crop_buff))
7465 TIFFError("processCropSelections", "Failed to mirror composite regions %s",
7466 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7471 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7473 if (rotateImage(crop->rotation, image, &crop->combined_width,
7474 &crop->combined_length, &crop_buff))
7476 TIFFError("processCropSelections",
7477 "Failed to rotate composite regions by %d degrees", crop->rotation);
7480 seg_buffs[0].buffer = crop_buff;
7481 seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
7482 * image->spp) * crop->combined_length;
7485 else /* Separated Images */
7487 total_width = total_length = 0;
7488 for (i = 0; i < crop->selections; i++)
7490 cropsize = crop->bufftotal;
7491 crop_buff = seg_buffs[i].buffer;
7493 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7496 prev_cropsize = seg_buffs[0].size;
7497 if (prev_cropsize < cropsize)
7499 next_buff = _TIFFrealloc(crop_buff, cropsize);
7502 _TIFFfree (crop_buff);
7503 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7506 crop_buff = next_buff;
7512 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7516 _TIFFmemset(crop_buff, 0, cropsize);
7517 seg_buffs[i].buffer = crop_buff;
7518 seg_buffs[i].size = cropsize;
7520 if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
7522 TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
7526 width = crop->regionlist[i].width;
7527 length = crop->regionlist[i].length;
7529 if (crop->crop_mode & CROP_INVERT)
7531 switch (crop->photometric)
7533 /* Just change the interpretation */
7534 case PHOTOMETRIC_MINISWHITE:
7535 case PHOTOMETRIC_MINISBLACK:
7536 image->photometric = crop->photometric;
7538 case INVERT_DATA_ONLY:
7539 case INVERT_DATA_AND_TAG:
7540 if (invertImage(image->photometric, image->spp, image->bps,
7541 width, length, crop_buff))
7543 TIFFError("processCropSelections",
7544 "Failed to invert colorspace for region");
7547 if (crop->photometric == INVERT_DATA_AND_TAG)
7549 switch (image->photometric)
7551 case PHOTOMETRIC_MINISWHITE:
7552 image->photometric = PHOTOMETRIC_MINISBLACK;
7554 case PHOTOMETRIC_MINISBLACK:
7555 image->photometric = PHOTOMETRIC_MINISWHITE;
7566 if (crop->crop_mode & CROP_MIRROR)
7568 if (mirrorImage(image->spp, image->bps, crop->mirror,
7569 width, length, crop_buff))
7571 TIFFError("processCropSelections", "Failed to mirror crop region %s",
7572 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7577 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7579 if (rotateImage(crop->rotation, image, &crop->regionlist[i].width,
7580 &crop->regionlist[i].length, &crop_buff))
7582 TIFFError("processCropSelections",
7583 "Failed to rotate crop region by %d degrees", crop->rotation);
7586 total_width += crop->regionlist[i].width;
7587 total_length += crop->regionlist[i].length;
7588 crop->combined_width = total_width;
7589 crop->combined_length = total_length;
7590 seg_buffs[i].buffer = crop_buff;
7591 seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
7592 * image->spp) * crop->regionlist[i].length;
7597 } /* end processCropSelections */
7599 /* Copy the crop section of the data from the current image into a buffer
7600 * and adjust the IFD values to reflect the new size. If no cropping is
7601 * required, use the origial read buffer as the crop buffer.
7603 * There is quite a bit of redundancy between this routine and the more
7604 * specialized processCropSelections, but this provides
7605 * the most optimized path when no Zones or Regions are required.
7608 createCroppedImage(struct image_data *image, struct crop_mask *crop,
7609 unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
7612 unsigned char *read_buff = NULL;
7613 unsigned char *crop_buff = NULL;
7614 unsigned char *new_buff = NULL;
7615 static tsize_t prev_cropsize = 0;
7617 read_buff = *read_buff_ptr;
7619 /* process full image, no crop buffer needed */
7620 crop_buff = read_buff;
7621 *crop_buff_ptr = read_buff;
7622 crop->combined_width = image->width;
7623 crop->combined_length = image->length;
7625 cropsize = crop->bufftotal;
7626 crop_buff = *crop_buff_ptr;
7629 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7630 *crop_buff_ptr = crop_buff;
7631 _TIFFmemset(crop_buff, 0, cropsize);
7632 prev_cropsize = cropsize;
7636 if (prev_cropsize < cropsize)
7638 new_buff = _TIFFrealloc(crop_buff, cropsize);
7642 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7645 crop_buff = new_buff;
7646 _TIFFmemset(crop_buff, 0, cropsize);
7652 TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
7655 *crop_buff_ptr = crop_buff;
7657 if (crop->crop_mode & CROP_INVERT)
7659 switch (crop->photometric)
7661 /* Just change the interpretation */
7662 case PHOTOMETRIC_MINISWHITE:
7663 case PHOTOMETRIC_MINISBLACK:
7664 image->photometric = crop->photometric;
7666 case INVERT_DATA_ONLY:
7667 case INVERT_DATA_AND_TAG:
7668 if (invertImage(image->photometric, image->spp, image->bps,
7669 crop->combined_width, crop->combined_length, crop_buff))
7671 TIFFError("createCroppedImage",
7672 "Failed to invert colorspace for image or cropped selection");
7675 if (crop->photometric == INVERT_DATA_AND_TAG)
7677 switch (image->photometric)
7679 case PHOTOMETRIC_MINISWHITE:
7680 image->photometric = PHOTOMETRIC_MINISBLACK;
7682 case PHOTOMETRIC_MINISBLACK:
7683 image->photometric = PHOTOMETRIC_MINISWHITE;
7694 if (crop->crop_mode & CROP_MIRROR)
7696 if (mirrorImage(image->spp, image->bps, crop->mirror,
7697 crop->combined_width, crop->combined_length, crop_buff))
7699 TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s",
7700 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7705 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7707 if (rotateImage(crop->rotation, image, &crop->combined_width,
7708 &crop->combined_length, crop_buff_ptr))
7710 TIFFError("createCroppedImage",
7711 "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
7716 if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
7717 *read_buff_ptr = NULL; /* so we don't try to free it later */
7720 } /* end createCroppedImage */
7723 /* Code in this function is heavily indebted to code in tiffcp
7724 * with modifications by Richard Nolde to handle orientation correctly.
7725 * It will have to be updated significantly if support is added to
7726 * extract one or more samples from original image since the
7727 * original code assumes we are always copying all samples.
7728 * Use of global variables for config, compression and others
7729 * should be replaced by addition to the crop_mask struct (which
7730 * will be renamed to proc_opts indicating that is controls
7731 * user supplied processing options, not just cropping) and
7732 * then passed in as an argument.
7735 writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image,
7736 struct dump_opts *dump, uint32 width, uint32 length,
7737 unsigned char *crop_buff, int pagenum, int total_pages)
7740 uint16 input_compression, input_photometric;
7741 uint16 input_planar;
7744 input_compression = image->compression;
7745 input_photometric = image->photometric;
7749 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
7750 TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
7751 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
7752 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
7755 TIFFError("writeCroppedImage", "Input compression: %s",
7756 (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
7757 ((input_compression == COMPRESSION_JPEG) ? "New Jpeg" : "Non Jpeg"));
7760 if (compression != (uint16)-1)
7761 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
7764 if (input_compression == COMPRESSION_OJPEG)
7766 compression = COMPRESSION_JPEG;
7767 jpegcolormode = JPEGCOLORMODE_RAW;
7768 TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
7771 CopyField(TIFFTAG_COMPRESSION, compression);
7774 if (compression == COMPRESSION_JPEG)
7776 if ((input_photometric == PHOTOMETRIC_PALETTE) || /* color map indexed */
7777 (input_photometric == PHOTOMETRIC_MASK)) /* $holdout mask */
7779 TIFFError ("writeCroppedImage",
7780 "JPEG compression cannot be used with %s image data",
7781 (input_photometric == PHOTOMETRIC_PALETTE) ?
7782 "palette" : "mask");
7785 if ((input_photometric == PHOTOMETRIC_RGB) &&
7786 (jpegcolormode == JPEGCOLORMODE_RGB))
7787 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
7789 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
7793 if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
7795 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7796 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7800 if (input_compression == COMPRESSION_SGILOG ||
7801 input_compression == COMPRESSION_SGILOG24)
7803 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7804 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7807 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
7811 if (((input_photometric == PHOTOMETRIC_LOGL) ||
7812 (input_photometric == PHOTOMETRIC_LOGLUV)) &&
7813 ((compression != COMPRESSION_SGILOG) &&
7814 (compression != COMPRESSION_SGILOG24)))
7816 TIFFError("writeCroppedImage",
7817 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
7822 TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
7824 CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
7826 /* The loadimage function reads input orientation and sets
7827 * image->orientation. The correct_image_orientation function
7828 * applies the required rotation and mirror operations to
7829 * present the data in TOPLEFT orientation and updates
7830 * image->orientation if any transforms are performed,
7831 * as per EXIF standard.
7833 TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
7836 * Choose tiles/strip for the output image according to
7837 * the command line arguments (-tiles, -strips) and the
7838 * structure of the input image.
7841 outtiled = TIFFIsTiled(in);
7844 * Setup output file's tile width&height. If either
7845 * is not specified, use either the value from the
7846 * input image or, if nothing is defined, use the
7849 if (tilewidth == (uint32) 0)
7850 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7851 if (tilelength == (uint32) 0)
7852 TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7854 if (tilewidth == 0 || tilelength == 0)
7855 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7856 TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7857 TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7860 * RowsPerStrip is left unspecified: use either the
7861 * value from the input image or, if nothing is defined,
7862 * use the library default.
7864 if (rowsperstrip == (uint32) 0)
7866 if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7867 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7868 if (compression != COMPRESSION_JPEG)
7870 if (rowsperstrip > length)
7871 rowsperstrip = length;
7875 if (rowsperstrip == (uint32) -1)
7876 rowsperstrip = length;
7877 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7880 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7881 if (config != (uint16) -1)
7882 TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7884 CopyField(TIFFTAG_PLANARCONFIG, config);
7886 CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7887 CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7889 /* SMinSampleValue & SMaxSampleValue */
7890 switch (compression) {
7891 case COMPRESSION_JPEG:
7892 if (((bps % 8) == 0) || ((bps % 12) == 0))
7894 TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7895 TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7899 TIFFError("writeCroppedImage",
7900 "JPEG compression requires 8 or 12 bits per sample");
7904 case COMPRESSION_LZW:
7905 case COMPRESSION_ADOBE_DEFLATE:
7906 case COMPRESSION_DEFLATE:
7907 if (predictor != (uint16)-1)
7908 TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7910 CopyField(TIFFTAG_PREDICTOR, predictor);
7912 case COMPRESSION_CCITTFAX3:
7913 case COMPRESSION_CCITTFAX4:
7916 TIFFError("writeCroppedImage",
7917 "Group 3/4 compression is not usable with bps > 1");
7920 if (compression == COMPRESSION_CCITTFAX3) {
7921 if (g3opts != (uint32) -1)
7922 TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7924 CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7926 CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7928 CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7929 CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7930 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7931 CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7932 CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7933 CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7935 case COMPRESSION_NONE:
7941 if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7942 TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7945 const char* inknames;
7946 if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7947 TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7948 if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7949 int inknameslen = strlen(inknames) + 1;
7950 const char* cp = inknames;
7952 cp = strchr(cp, '\0');
7955 inknameslen += (strlen(cp) + 1);
7959 TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7964 unsigned short pg0, pg1;
7965 if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7966 TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
7970 for (p = tags; p < &tags[NTAGS]; p++)
7971 CopyTag(p->tag, p->count, p->type);
7973 /* Compute the tile or strip dimensions and write to disk */
7976 if (config == PLANARCONFIG_CONTIG)
7978 if (writeBufferToContigTiles (out, crop_buff, length, width, spp, dump))
7979 TIFFError("","Unable to write contiguous tile data for page %d", pagenum);
7983 if (writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump))
7984 TIFFError("","Unable to write separate tile data for page %d", pagenum);
7989 if (config == PLANARCONFIG_CONTIG)
7991 if (writeBufferToContigStrips (out, crop_buff, length))
7992 TIFFError("","Unable to write contiguous strip data for page %d", pagenum);
7996 if (writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump))
7997 TIFFError("","Unable to write separate strip data for page %d", pagenum);
8001 if (!TIFFWriteDirectory(out))
8003 TIFFError("","Failed to write IFD for page number %d", pagenum);
8008 } /* end writeCroppedImage */
8011 rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8012 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8015 uint32 src_byte = 0, src_bit = 0;
8016 uint32 row, rowsize = 0, bit_offset = 0;
8017 uint8 matchbits = 0, maskbits = 0;
8018 uint8 buff1 = 0, buff2 = 0;
8022 if ((src == NULL) || (dst == NULL))
8024 TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
8028 rowsize = ((bps * spp * width) + 7) / 8;
8030 maskbits = (uint8)-1 >> ( 8 - bps);
8033 for (row = 0; row < length ; row++)
8035 bit_offset = col * bps * spp;
8036 for (sample = 0; sample < spp; sample++)
8040 src_byte = bit_offset / 8;
8041 src_bit = bit_offset % 8;
8045 src_byte = (bit_offset + (sample * bps)) / 8;
8046 src_bit = (bit_offset + (sample * bps)) % 8;
8051 case 90: next = src + src_byte - (row * rowsize);
8053 case 270: next = src + src_byte + (row * rowsize);
8055 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8058 matchbits = maskbits << (8 - src_bit - bps);
8059 buff1 = ((*next) & matchbits) << (src_bit);
8061 /* If we have a full buffer's worth, write it out */
8062 if (ready_bits >= 8)
8070 buff2 = (buff2 | (buff1 >> ready_bits));
8078 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
8083 } /* end rotateContigSamples8bits */
8087 rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8088 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8091 uint32 row, rowsize, bit_offset;
8092 uint32 src_byte = 0, src_bit = 0;
8093 uint16 matchbits = 0, maskbits = 0;
8094 uint16 buff1 = 0, buff2 = 0;
8099 if ((src == NULL) || (dst == NULL))
8101 TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
8105 rowsize = ((bps * spp * width) + 7) / 8;
8107 maskbits = (uint16)-1 >> (16 - bps);
8109 for (row = 0; row < length; row++)
8111 bit_offset = col * bps * spp;
8112 for (sample = 0; sample < spp; sample++)
8116 src_byte = bit_offset / 8;
8117 src_bit = bit_offset % 8;
8121 src_byte = (bit_offset + (sample * bps)) / 8;
8122 src_bit = (bit_offset + (sample * bps)) % 8;
8127 case 90: next = src + src_byte - (row * rowsize);
8129 case 270: next = src + src_byte + (row * rowsize);
8131 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8134 matchbits = maskbits << (16 - src_bit - bps);
8136 buff1 = (next[0] << 8) | next[1];
8138 buff1 = (next[1] << 8) | next[0];
8140 buff1 = (buff1 & matchbits) << (src_bit);
8142 /* If we have a full buffer's worth, write it out */
8143 if (ready_bits >= 8)
8145 bytebuff = (buff2 >> 8);
8148 /* shift in new bits */
8149 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
8152 { /* add another bps bits to the buffer */
8154 buff2 = (buff2 | (buff1 >> ready_bits));
8162 bytebuff = (buff2 >> 8);
8167 } /* end rotateContigSamples16bits */
8170 rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8171 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8174 uint32 row, rowsize, bit_offset;
8175 uint32 src_byte = 0, src_bit = 0;
8176 uint32 matchbits = 0, maskbits = 0;
8177 uint32 buff1 = 0, buff2 = 0;
8178 uint8 bytebuff1 = 0, bytebuff2 = 0;
8183 if ((src == NULL) || (dst == NULL))
8185 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8189 rowsize = ((bps * spp * width) + 7) / 8;
8191 maskbits = (uint32)-1 >> (32 - bps);
8193 for (row = 0; row < length; row++)
8195 bit_offset = col * bps * spp;
8196 for (sample = 0; sample < spp; sample++)
8200 src_byte = bit_offset / 8;
8201 src_bit = bit_offset % 8;
8205 src_byte = (bit_offset + (sample * bps)) / 8;
8206 src_bit = (bit_offset + (sample * bps)) % 8;
8211 case 90: next = src + src_byte - (row * rowsize);
8213 case 270: next = src + src_byte + (row * rowsize);
8215 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8218 matchbits = maskbits << (32 - src_bit - bps);
8220 buff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8222 buff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8223 buff1 = (buff1 & matchbits) << (src_bit);
8225 /* If we have a full buffer's worth, write it out */
8226 if (ready_bits >= 16)
8228 bytebuff1 = (buff2 >> 24);
8230 bytebuff2 = (buff2 >> 16);
8234 /* shift in new bits */
8235 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8238 { /* add another bps bits to the buffer */
8239 bytebuff1 = bytebuff2 = 0;
8240 buff2 = (buff2 | (buff1 >> ready_bits));
8246 /* catch any trailing bits at the end of the line */
8247 while (ready_bits > 0)
8249 bytebuff1 = (buff2 >> 24);
8252 buff2 = (buff2 << 8);
8253 bytebuff2 = bytebuff1;
8258 } /* end rotateContigSamples24bits */
8261 rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8262 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8264 int ready_bits = 0 /*, shift_width = 0 */;
8265 /* int bytes_per_sample, bytes_per_pixel; */
8266 uint32 row, rowsize, bit_offset;
8267 uint32 src_byte, src_bit;
8268 uint32 longbuff1 = 0, longbuff2 = 0;
8269 uint64 maskbits = 0, matchbits = 0;
8270 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8271 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8276 if ((src == NULL) || (dst == NULL))
8278 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8282 /* bytes_per_sample = (bps + 7) / 8; */
8283 /* bytes_per_pixel = ((bps * spp) + 7) / 8; */
8284 /* if (bytes_per_pixel < (bytes_per_sample + 1)) */
8285 /* shift_width = bytes_per_pixel; */
8287 /* shift_width = bytes_per_sample + 1; */
8289 rowsize = ((bps * spp * width) + 7) / 8;
8291 maskbits = (uint64)-1 >> (64 - bps);
8293 for (row = 0; row < length; row++)
8295 bit_offset = col * bps * spp;
8296 for (sample = 0; sample < spp; sample++)
8300 src_byte = bit_offset / 8;
8301 src_bit = bit_offset % 8;
8305 src_byte = (bit_offset + (sample * bps)) / 8;
8306 src_bit = (bit_offset + (sample * bps)) % 8;
8311 case 90: next = src + src_byte - (row * rowsize);
8313 case 270: next = src + src_byte + (row * rowsize);
8315 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8318 matchbits = maskbits << (64 - src_bit - bps);
8321 longbuff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8322 longbuff2 = longbuff1;
8326 longbuff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8327 longbuff2 = longbuff1;
8330 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8331 buff1 = (buff3 & matchbits) << (src_bit);
8333 if (ready_bits < 32)
8334 { /* add another bps bits to the buffer */
8335 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8336 buff2 = (buff2 | (buff1 >> ready_bits));
8338 else /* If we have a full buffer's worth, write it out */
8340 bytebuff1 = (buff2 >> 56);
8342 bytebuff2 = (buff2 >> 48);
8344 bytebuff3 = (buff2 >> 40);
8346 bytebuff4 = (buff2 >> 32);
8350 /* shift in new bits */
8351 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8356 while (ready_bits > 0)
8358 bytebuff1 = (buff2 >> 56);
8360 buff2 = (buff2 << 8);
8365 } /* end rotateContigSamples32bits */
8368 /* Rotate an image by a multiple of 90 degrees clockwise */
8370 rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
8371 uint32 *img_length, unsigned char **ibuff_ptr)
8374 uint32 bytes_per_pixel, bytes_per_sample;
8375 uint32 row, rowsize, src_offset, dst_offset;
8376 uint32 i, col, width, length;
8377 uint32 colsize, buffsize, col_offset, pix_offset;
8378 unsigned char *ibuff;
8383 unsigned char *rbuff = NULL;
8386 length = *img_length;
8390 rowsize = ((bps * spp * width) + 7) / 8;
8391 colsize = ((bps * spp * length) + 7) / 8;
8392 if ((colsize * width) > (rowsize * length))
8393 buffsize = (colsize + 1) * width;
8395 buffsize = (rowsize + 1) * length;
8397 bytes_per_sample = (bps + 7) / 8;
8398 bytes_per_pixel = ((bps * spp) + 7) / 8;
8399 if (bytes_per_pixel < (bytes_per_sample + 1))
8400 shift_width = bytes_per_pixel;
8402 shift_width = bytes_per_sample + 1;
8407 case 360: return (0);
8411 default: TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
8415 if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
8417 TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
8420 _TIFFmemset(rbuff, '\0', buffsize);
8425 case 180: if ((bps % 8) == 0) /* byte aligned data */
8428 pix_offset = (spp * bps) / 8;
8429 for (row = 0; row < length; row++)
8431 dst_offset = (length - row - 1) * rowsize;
8432 for (col = 0; col < width; col++)
8434 col_offset = (width - col - 1) * pix_offset;
8435 dst = rbuff + dst_offset + col_offset;
8437 for (i = 0; i < bytes_per_pixel; i++)
8443 { /* non 8 bit per sample data */
8444 for (row = 0; row < length; row++)
8446 src_offset = row * rowsize;
8447 dst_offset = (length - row - 1) * rowsize;
8448 src = ibuff + src_offset;
8449 dst = rbuff + dst_offset;
8450 switch (shift_width)
8452 case 1: if (bps == 1)
8454 if (reverseSamples8bits(spp, bps, width, src, dst))
8461 if (reverseSamples16bits(spp, bps, width, src, dst))
8467 case 2: if (reverseSamples24bits(spp, bps, width, src, dst))
8475 case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
8481 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8488 *(ibuff_ptr) = rbuff;
8491 case 90: if ((bps % 8) == 0) /* byte aligned data */
8493 for (col = 0; col < width; col++)
8495 src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
8496 dst_offset = col * colsize;
8497 src = ibuff + src_offset;
8498 dst = rbuff + dst_offset;
8499 for (row = length; row > 0; row--)
8501 for (i = 0; i < bytes_per_pixel; i++)
8502 *dst++ = *(src + i);
8508 { /* non 8 bit per sample data */
8509 for (col = 0; col < width; col++)
8511 src_offset = (length - 1) * rowsize;
8512 dst_offset = col * colsize;
8513 src = ibuff + src_offset;
8514 dst = rbuff + dst_offset;
8515 switch (shift_width)
8517 case 1: if (bps == 1)
8519 if (rotateContigSamples8bits(rotation, spp, bps, width,
8520 length, col, src, dst))
8527 if (rotateContigSamples16bits(rotation, spp, bps, width,
8528 length, col, src, dst))
8534 case 2: if (rotateContigSamples24bits(rotation, spp, bps, width,
8535 length, col, src, dst))
8543 case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
8544 length, col, src, dst))
8550 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8557 *(ibuff_ptr) = rbuff;
8559 *img_width = length;
8560 *img_length = width;
8561 image->width = length;
8562 image->length = width;
8563 res_temp = image->xres;
8564 image->xres = image->yres;
8565 image->yres = res_temp;
8568 case 270: if ((bps % 8) == 0) /* byte aligned data */
8570 for (col = 0; col < width; col++)
8572 src_offset = col * bytes_per_pixel;
8573 dst_offset = (width - col - 1) * colsize;
8574 src = ibuff + src_offset;
8575 dst = rbuff + dst_offset;
8576 for (row = length; row > 0; row--)
8578 for (i = 0; i < bytes_per_pixel; i++)
8579 *dst++ = *(src + i);
8585 { /* non 8 bit per sample data */
8586 for (col = 0; col < width; col++)
8589 dst_offset = (width - col - 1) * colsize;
8590 src = ibuff + src_offset;
8591 dst = rbuff + dst_offset;
8592 switch (shift_width)
8594 case 1: if (bps == 1)
8596 if (rotateContigSamples8bits(rotation, spp, bps, width,
8597 length, col, src, dst))
8604 if (rotateContigSamples16bits(rotation, spp, bps, width,
8605 length, col, src, dst))
8611 case 2: if (rotateContigSamples24bits(rotation, spp, bps, width,
8612 length, col, src, dst))
8620 case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
8621 length, col, src, dst))
8627 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8634 *(ibuff_ptr) = rbuff;
8636 *img_width = length;
8637 *img_length = width;
8638 image->width = length;
8639 image->length = width;
8640 res_temp = image->xres;
8641 image->xres = image->yres;
8642 image->yres = res_temp;
8649 } /* end rotateImage */
8652 reverseSamples8bits (uint16 spp, uint16 bps, uint32 width,
8653 uint8 *ibuff, uint8 *obuff)
8657 uint32 src_byte, src_bit;
8658 uint32 bit_offset = 0;
8659 uint8 match_bits = 0, mask_bits = 0;
8660 uint8 buff1 = 0, buff2 = 0;
8665 if ((ibuff == NULL) || (obuff == NULL))
8667 TIFFError("reverseSamples8bits","Invalid image or work buffer");
8672 mask_bits = (uint8)-1 >> ( 8 - bps);
8674 for (col = width; col > 0; col--)
8676 /* Compute src byte(s) and bits within byte(s) */
8677 bit_offset = (col - 1) * bps * spp;
8678 for (sample = 0; sample < spp; sample++)
8682 src_byte = bit_offset / 8;
8683 src_bit = bit_offset % 8;
8687 src_byte = (bit_offset + (sample * bps)) / 8;
8688 src_bit = (bit_offset + (sample * bps)) % 8;
8691 src = ibuff + src_byte;
8692 match_bits = mask_bits << (8 - src_bit - bps);
8693 buff1 = ((*src) & match_bits) << (src_bit);
8696 buff2 = (buff2 | (buff1 >> ready_bits));
8697 else /* If we have a full buffer's worth, write it out */
8708 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
8713 } /* end reverseSamples8bits */
8717 reverseSamples16bits (uint16 spp, uint16 bps, uint32 width,
8718 uint8 *ibuff, uint8 *obuff)
8722 uint32 src_byte = 0, high_bit = 0;
8723 uint32 bit_offset = 0;
8724 uint16 match_bits = 0, mask_bits = 0;
8725 uint16 buff1 = 0, buff2 = 0;
8731 if ((ibuff == NULL) || (obuff == NULL))
8733 TIFFError("reverseSample16bits","Invalid image or work buffer");
8738 mask_bits = (uint16)-1 >> (16 - bps);
8740 for (col = width; col > 0; col--)
8742 /* Compute src byte(s) and bits within byte(s) */
8743 bit_offset = (col - 1) * bps * spp;
8744 for (sample = 0; sample < spp; sample++)
8748 src_byte = bit_offset / 8;
8749 high_bit = bit_offset % 8;
8753 src_byte = (bit_offset + (sample * bps)) / 8;
8754 high_bit = (bit_offset + (sample * bps)) % 8;
8757 src = ibuff + src_byte;
8758 match_bits = mask_bits << (16 - high_bit - bps);
8760 buff1 = (src[0] << 8) | src[1];
8762 buff1 = (src[1] << 8) | src[0];
8763 buff1 = (buff1 & match_bits) << (high_bit);
8766 { /* add another bps bits to the buffer */
8768 buff2 = (buff2 | (buff1 >> ready_bits));
8770 else /* If we have a full buffer's worth, write it out */
8772 bytebuff = (buff2 >> 8);
8775 /* shift in new bits */
8776 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
8784 bytebuff = (buff2 >> 8);
8789 } /* end reverseSamples16bits */
8792 reverseSamples24bits (uint16 spp, uint16 bps, uint32 width,
8793 uint8 *ibuff, uint8 *obuff)
8797 uint32 src_byte = 0, high_bit = 0;
8798 uint32 bit_offset = 0;
8799 uint32 match_bits = 0, mask_bits = 0;
8800 uint32 buff1 = 0, buff2 = 0;
8801 uint8 bytebuff1 = 0, bytebuff2 = 0;
8806 if ((ibuff == NULL) || (obuff == NULL))
8808 TIFFError("reverseSamples24bits","Invalid image or work buffer");
8813 mask_bits = (uint32)-1 >> (32 - bps);
8815 for (col = width; col > 0; col--)
8817 /* Compute src byte(s) and bits within byte(s) */
8818 bit_offset = (col - 1) * bps * spp;
8819 for (sample = 0; sample < spp; sample++)
8823 src_byte = bit_offset / 8;
8824 high_bit = bit_offset % 8;
8828 src_byte = (bit_offset + (sample * bps)) / 8;
8829 high_bit = (bit_offset + (sample * bps)) % 8;
8832 src = ibuff + src_byte;
8833 match_bits = mask_bits << (32 - high_bit - bps);
8835 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8837 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8838 buff1 = (buff1 & match_bits) << (high_bit);
8840 if (ready_bits < 16)
8841 { /* add another bps bits to the buffer */
8842 bytebuff1 = bytebuff2 = 0;
8843 buff2 = (buff2 | (buff1 >> ready_bits));
8845 else /* If we have a full buffer's worth, write it out */
8847 bytebuff1 = (buff2 >> 24);
8849 bytebuff2 = (buff2 >> 16);
8853 /* shift in new bits */
8854 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8860 /* catch any trailing bits at the end of the line */
8861 while (ready_bits > 0)
8863 bytebuff1 = (buff2 >> 24);
8866 buff2 = (buff2 << 8);
8867 bytebuff2 = bytebuff1;
8872 } /* end reverseSamples24bits */
8876 reverseSamples32bits (uint16 spp, uint16 bps, uint32 width,
8877 uint8 *ibuff, uint8 *obuff)
8879 int ready_bits = 0 /*, shift_width = 0 */;
8880 /* int bytes_per_sample, bytes_per_pixel; */
8882 uint32 src_byte = 0, high_bit = 0;
8884 uint32 longbuff1 = 0, longbuff2 = 0;
8885 uint64 mask_bits = 0, match_bits = 0;
8886 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8887 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8892 if ((ibuff == NULL) || (obuff == NULL))
8894 TIFFError("reverseSamples32bits","Invalid image or work buffer");
8899 mask_bits = (uint64)-1 >> (64 - bps);
8902 /* bytes_per_sample = (bps + 7) / 8; */
8903 /* bytes_per_pixel = ((bps * spp) + 7) / 8; */
8904 /* if (bytes_per_pixel < (bytes_per_sample + 1)) */
8905 /* shift_width = bytes_per_pixel; */
8907 /* shift_width = bytes_per_sample + 1; */
8909 for (col = width; col > 0; col--)
8911 /* Compute src byte(s) and bits within byte(s) */
8912 bit_offset = (col - 1) * bps * spp;
8913 for (sample = 0; sample < spp; sample++)
8917 src_byte = bit_offset / 8;
8918 high_bit = bit_offset % 8;
8922 src_byte = (bit_offset + (sample * bps)) / 8;
8923 high_bit = (bit_offset + (sample * bps)) % 8;
8926 src = ibuff + src_byte;
8927 match_bits = mask_bits << (64 - high_bit - bps);
8930 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8931 longbuff2 = longbuff1;
8935 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8936 longbuff2 = longbuff1;
8938 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8939 buff1 = (buff3 & match_bits) << (high_bit);
8941 if (ready_bits < 32)
8942 { /* add another bps bits to the buffer */
8943 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8944 buff2 = (buff2 | (buff1 >> ready_bits));
8946 else /* If we have a full buffer's worth, write it out */
8948 bytebuff1 = (buff2 >> 56);
8950 bytebuff2 = (buff2 >> 48);
8952 bytebuff3 = (buff2 >> 40);
8954 bytebuff4 = (buff2 >> 32);
8958 /* shift in new bits */
8959 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8964 while (ready_bits > 0)
8966 bytebuff1 = (buff2 >> 56);
8968 buff2 = (buff2 << 8);
8973 } /* end reverseSamples32bits */
8976 reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width,
8977 uint8 *src, uint8 *dst)
8980 uint32 col, bytes_per_pixel, col_offset;
8982 unsigned char swapbuff[32];
8984 if ((src == NULL) || (dst == NULL))
8986 TIFFError("reverseSamplesBytes","Invalid input or output buffer");
8990 bytes_per_pixel = ((bps * spp) + 7) / 8;
8991 if( bytes_per_pixel > sizeof(swapbuff) )
8993 TIFFError("reverseSamplesBytes","bytes_per_pixel too large");
8998 case 8: /* Use memcpy for multiple bytes per sample data */
9001 case 2: for (col = 0; col < (width / 2); col++)
9003 col_offset = col * bytes_per_pixel;
9004 _TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
9005 _TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
9006 _TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
9009 case 1: /* Use byte copy only for single byte per sample data */
9010 for (col = 0; col < (width / 2); col++)
9012 for (i = 0; i < spp; i++)
9015 *src++ = *(dst - spp + i);
9016 *(dst - spp + i) = bytebuff1;
9021 default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
9025 } /* end reverseSamplesBytes */
9028 /* Mirror an image horizontally or vertically */
9030 mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
9033 uint32 bytes_per_pixel, bytes_per_sample;
9034 uint32 row, rowsize, row_offset;
9035 unsigned char *line_buff = NULL;
9040 rowsize = ((width * bps * spp) + 7) / 8;
9045 line_buff = (unsigned char *)_TIFFmalloc(rowsize);
9046 if (line_buff == NULL)
9048 TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
9052 dst = ibuff + (rowsize * (length - 1));
9053 for (row = 0; row < length / 2; row++)
9055 _TIFFmemcpy(line_buff, src, rowsize);
9056 _TIFFmemcpy(src, dst, rowsize);
9057 _TIFFmemcpy(dst, line_buff, rowsize);
9062 _TIFFfree(line_buff);
9063 if (mirror == MIRROR_VERT)
9067 if ((bps % 8) == 0) /* byte aligned data */
9069 for (row = 0; row < length; row++)
9071 row_offset = row * rowsize;
9072 src = ibuff + row_offset;
9073 dst = ibuff + row_offset + rowsize;
9074 if (reverseSamplesBytes(spp, bps, width, src, dst))
9081 { /* non 8 bit per sample data */
9082 if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
9084 TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
9087 bytes_per_sample = (bps + 7) / 8;
9088 bytes_per_pixel = ((bps * spp) + 7) / 8;
9089 if (bytes_per_pixel < (bytes_per_sample + 1))
9090 shift_width = bytes_per_pixel;
9092 shift_width = bytes_per_sample + 1;
9094 for (row = 0; row < length; row++)
9096 row_offset = row * rowsize;
9097 src = ibuff + row_offset;
9098 _TIFFmemset (line_buff, '\0', rowsize);
9099 switch (shift_width)
9101 case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
9103 _TIFFfree(line_buff);
9106 _TIFFmemcpy (src, line_buff, rowsize);
9108 case 2: if (reverseSamples24bits(spp, bps, width, src, line_buff))
9110 _TIFFfree(line_buff);
9113 _TIFFmemcpy (src, line_buff, rowsize);
9117 case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
9119 _TIFFfree(line_buff);
9122 _TIFFmemcpy (src, line_buff, rowsize);
9124 default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
9125 _TIFFfree(line_buff);
9130 _TIFFfree(line_buff);
9134 default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
9142 /* Invert the light and dark values for a bilevel or grayscale image */
9144 invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
9153 TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
9157 if (photometric != PHOTOMETRIC_MINISWHITE && photometric != PHOTOMETRIC_MINISBLACK)
9159 TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
9166 TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
9172 case 32: src_uint32 = (uint32 *)src;
9173 for (row = 0; row < length; row++)
9174 for (col = 0; col < width; col++)
9176 *src_uint32 = ~(*src_uint32);
9180 case 16: src_uint16 = (uint16 *)src;
9181 for (row = 0; row < length; row++)
9182 for (col = 0; col < width; col++)
9184 *src_uint16 = ~(*src_uint16);
9191 case 1: for (row = 0; row < length; row++)
9192 for (col = 0; col < width; col += 8 / bps)
9198 default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
9205 /* vim: set ts=8 sts=8 sw=8 noet: */