1 /* $Id: tiffcrop.c,v 1.3.2.15 2010-12-14 02:03:55 faxguy Exp $ */
3 /* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
4 * the image data through additional options listed below
7 * Copyright (c) 1988-1997 Sam Leffler
8 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
9 * Additions (c) Richard Nolde 2006-2010
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee, provided
13 * that (i) the above copyright notices and this permission notice appear in
14 * all copies of the software and related documentation, and (ii) the names of
15 * Sam Leffler and Silicon Graphics may not be used in any advertising or
16 * publicity relating to the software without the specific, prior written
17 * permission of Sam Leffler and Silicon Graphics.
19 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
21 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS OR ANY OTHER COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL
25 * DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
26 * DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
27 * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
28 * OR PERFORMANCE OF THIS SOFTWARE.
30 * Some portions of the current code are derived from tiffcp, primarly in
31 * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though
32 * some of the original functions have been extended to support arbitrary bit
33 * depths. These functions are presented at the top of this file.
35 * Add support for the options below to extract sections of image(s)
36 * and to modify the whole image or selected portions of each image by
37 * rotations, mirroring, and colorscale/colormap inversion of selected
38 * types of TIFF images when appropriate. Some color model dependent
39 * functions are restricted to bilevel or 8 bit per sample data.
40 * See the man page for the full explanations.
43 * -h Display the syntax guide.
44 * -v Report the version and last build date for tiffcrop and libtiff.
45 * -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1
46 * Specify a series of coordinates to define rectangular
47 * regions by the top left and lower right corners.
48 * -e c|d|i|m|s export mode for images and selections from input images
49 * combined All images and selections are written to a single file (default)
50 * with multiple selections from one image combined into a single image
51 * divided All images and selections are written to a single file
52 * with each selection from one image written to a new image
53 * image Each input image is written to a new file (numeric filename sequence)
54 * with multiple selections from the image combined into one image
55 * multiple Each input image is written to a new file (numeric filename sequence)
56 * with each selection from the image written to a new image
57 * separated Individual selections from each image are written to separate files
58 * -U units [in, cm, px ] inches, centimeters or pixels
59 * -H # Set horizontal resolution of output images to #
60 * -V # Set vertical resolution of output images to #
61 * -J # Horizontal margin of output page to # expressed in current
62 * units when sectioning image into columns x rows
63 * using the -S cols:rows option.
64 * -K # Vertical margin of output page to # expressed in current
65 * units when sectioning image into columns x rows
66 * using the -S cols:rows option.
67 * -X # Horizontal dimension of region to extract expressed in current
69 * -Y # Vertical dimension of region to extract expressed in current
71 * -O orient Orientation for output image, portrait, landscape, auto
72 * -P page Page size for output image segments, eg letter, legal, tabloid,
74 * -S cols:rows Divide the image into equal sized segments using cols across
76 * -E t|l|r|b Edge to use as origin
77 * -m #,#,#,# Margins from edges for selection: top, left, bottom, right
79 * -Z #:#,#:# Zones of the image designated as zone X of Y,
80 * eg 1:3 would be first of three equal portions measured
82 * -N odd|even|#,#-#,#|last
83 * Select sequences and/or ranges of images within file
84 * to process. The words odd or even may be used to specify
85 * all odd or even numbered images the word last may be used
86 * in place of a number in the sequence to indicate the final
87 * image in the file without knowing how many images there are.
88 * -R # Rotate image or crop selection by 90,180,or 270 degrees
90 * -F h|v Flip (mirror) image or crop selection horizontally
92 * -I [black|white|data|both]
93 * Invert color space, eg dark to light for bilevel and grayscale images
94 * If argument is white or black, set the PHOTOMETRIC_INTERPRETATION
95 * tag to MinIsBlack or MinIsWhite without altering the image data
96 * If the argument is data or both, the image data are modified:
97 * both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
98 * data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
99 * -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
100 * Dump raw data for input and/or output images to individual files
101 * in raw (binary) format or text (ASCII) representing binary data
102 * as strings of 1s and 0s. The filename arguments are used as stems
103 * from which individual files are created for each image. Text format
104 * includes annotations for image parameters and scanline info. Level
105 * selects which functions dump data, with higher numbers selecting
106 * lower level, scanline level routines. Debug reports a limited set
107 * of messages to monitor progess without enabling dump logs.
110 static char tiffcrop_version_id[] = "2.4";
111 static char tiffcrop_rev_date[] = "12-13-2010";
113 #include "tif_config.h"
122 #include <sys/stat.h>
134 extern int getopt(int, char**, char*);
138 # include "libport.h"
144 # define unlink delete
148 #define PATH_MAX 1024
152 #define streq(a,b) (strcmp((a),(b)) == 0)
154 #define strneq(a,b,n) (strncmp((a),(b),(n)) == 0)
160 #define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
161 #define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
165 * Definitions and data structures required to support cropping and image
171 #define EDGE_BOTTOM 3
173 #define EDGE_CENTER 5
175 #define MIRROR_HORIZ 1
176 #define MIRROR_VERT 2
177 #define MIRROR_BOTH 3
178 #define ROTATECW_90 8
179 #define ROTATECW_180 16
180 #define ROTATECW_270 32
181 #define ROTATE_ANY ROTATECW_90 || ROTATECW_180 || ROTATECW_270
184 #define CROP_MARGINS 1
186 #define CROP_LENGTH 4
188 #define CROP_REGIONS 16
189 #define CROP_ROTATE 32
190 #define CROP_MIRROR 64
191 #define CROP_INVERT 128
193 /* Modes for writing out images and selections */
194 #define ONE_FILE_COMPOSITE 0 /* One file, sections combined sections */
195 #define ONE_FILE_SEPARATED 1 /* One file, sections to new IFDs */
196 #define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
197 #define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
198 #define FILE_PER_SELECTION 4 /* One file per selection */
200 #define COMPOSITE_IMAGES 0 /* Selections combined into one image */
201 #define SEPARATED_IMAGES 1 /* Selections saved to separate images */
206 #define MAX_REGIONS 8 /* number of regions to extract from a single page */
207 #define MAX_OUTBUFFS 8 /* must match larger of zones or regions */
208 #define MAX_SECTIONS 32 /* number of sections per page to write to output */
209 #define MAX_IMAGES 2048 /* number of images in descrete list, not in the file */
210 #define MAX_SAMPLES 8 /* maximum number of samples per pixel supported */
211 #define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
212 #define MAX_EXPORT_PAGES 999999 /* maximum number of export pages per file */
218 /* Offsets into buffer for margins and fixed width and length segments */
232 /* Description of a zone within the image. Position 1 of 3 zones would be
233 * the first third of the image. These are computed after margins and
234 * width/length requests are applied so that you can extract multiple
235 * zones from within a larger region for OCR or barcode recognition.
239 uint32 size; /* size of this buffer */
240 unsigned char *buffer; /* address of the allocated buffer */
244 int position; /* ordinal of segment to be extracted */
245 int total; /* total equal sized divisions of crop area */
249 uint32 x1; /* index of left edge */
250 uint32 x2; /* index of right edge */
251 uint32 y1; /* index of top edge */
252 uint32 y2; /* index of bottom edge */
253 int position; /* ordinal of segment to be extracted */
254 int total; /* total equal sized divisions of crop area */
255 uint32 buffsize; /* size of buffer needed to hold the cropped zone */
259 double X1; /* index of left edge in current units */
260 double X2; /* index of right edge in current units */
261 double Y1; /* index of top edge in current units */
262 double Y2; /* index of bottom edge in current units */
266 uint32 x1; /* pixel offset of left edge */
267 uint32 x2; /* pixel offset of right edge */
268 uint32 y1; /* pixel offset of top edge */
269 uint32 y2; /* picel offset of bottom edge */
270 uint32 width; /* width in pixels */
271 uint32 length; /* length in pixels */
272 uint32 buffsize; /* size of buffer needed to hold the cropped region */
273 unsigned char *buffptr; /* address of start of the region */
276 /* Cropping parameters from command line and image data
277 * Note: This should be renamed to proc_opts and expanded to include all current globals
278 * if possible, but each function that accesses global variables will have to be redone.
281 double width; /* Selection width for master crop region in requested units */
282 double length; /* Selection length for master crop region in requesed units */
283 double margins[4]; /* Top, left, bottom, right margins */
284 float xres; /* Horizontal resolution read from image*/
285 float yres; /* Vertical resolution read from image */
286 uint32 combined_width; /* Width of combined cropped zones */
287 uint32 combined_length; /* Length of combined cropped zones */
288 uint32 bufftotal; /* Size of buffer needed to hold all the cropped region */
289 uint16 img_mode; /* Composite or separate images created from zones or regions */
290 uint16 exp_mode; /* Export input images or selections to one or more files */
291 uint16 crop_mode; /* Crop options to be applied */
292 uint16 res_unit; /* Resolution unit for margins and selections */
293 uint16 edge_ref; /* Reference edge for sections extraction and combination */
294 uint16 rotation; /* Clockwise rotation of the extracted region or image */
295 uint16 mirror; /* Mirror extracted region or image horizontally or vertically */
296 uint16 invert; /* Invert the color map of image or region */
297 uint16 photometric; /* Status of photometric interpretation for inverted image */
298 uint16 selections; /* Number of regions or zones selected */
299 uint16 regions; /* Number of regions delimited by corner coordinates */
300 struct region regionlist[MAX_REGIONS]; /* Regions within page or master crop region */
301 uint16 zones; /* Number of zones delimited by Ordinal:Total requested */
302 struct zone zonelist[MAX_REGIONS]; /* Zones indices to define a region */
303 struct coordpairs corners[MAX_REGIONS]; /* Coordinates of upper left and lower right corner */
306 #define MAX_PAPERNAMES 49
307 #define MAX_PAPERNAME_LENGTH 15
308 #define DEFAULT_RESUNIT RESUNIT_INCH
309 #define DEFAULT_PAGE_HEIGHT 14.0
310 #define DEFAULT_PAGE_WIDTH 8.5
311 #define DEFAULT_RESOLUTION 300
312 #define DEFAULT_PAPER_SIZE "legal"
314 #define ORIENTATION_NONE 0
315 #define ORIENTATION_PORTRAIT 1
316 #define ORIENTATION_LANDSCAPE 2
317 #define ORIENTATION_SEASCAPE 4
318 #define ORIENTATION_AUTO 16
320 #define PAGE_MODE_NONE 0
321 #define PAGE_MODE_RESOLUTION 1
322 #define PAGE_MODE_PAPERSIZE 2
323 #define PAGE_MODE_MARGINS 4
324 #define PAGE_MODE_ROWSCOLS 8
326 #define INVERT_DATA_ONLY 10
327 #define INVERT_DATA_AND_TAG 11
330 char name[MAX_PAPERNAME_LENGTH];
336 /* European page sizes corrected from update sent by
337 * thomas . jarosch @ intra2net . com on 5/7/2010
338 * Paper Size Width Length Aspect Ratio */
339 struct paperdef PaperTable[MAX_PAPERNAMES] = {
340 {"default", 8.500, 14.000, 0.607},
341 {"pa4", 8.264, 11.000, 0.751},
342 {"letter", 8.500, 11.000, 0.773},
343 {"legal", 8.500, 14.000, 0.607},
344 {"half-letter", 8.500, 5.514, 1.542},
345 {"executive", 7.264, 10.528, 0.690},
346 {"tabloid", 11.000, 17.000, 0.647},
347 {"11x17", 11.000, 17.000, 0.647},
348 {"ledger", 17.000, 11.000, 1.545},
349 {"archa", 9.000, 12.000, 0.750},
350 {"archb", 12.000, 18.000, 0.667},
351 {"archc", 18.000, 24.000, 0.750},
352 {"archd", 24.000, 36.000, 0.667},
353 {"arche", 36.000, 48.000, 0.750},
354 {"csheet", 17.000, 22.000, 0.773},
355 {"dsheet", 22.000, 34.000, 0.647},
356 {"esheet", 34.000, 44.000, 0.773},
357 {"superb", 11.708, 17.042, 0.687},
358 {"commercial", 4.139, 9.528, 0.434},
359 {"monarch", 3.889, 7.528, 0.517},
360 {"envelope-dl", 4.333, 8.681, 0.499},
361 {"envelope-c5", 6.389, 9.028, 0.708},
362 {"europostcard", 4.139, 5.833, 0.710},
363 {"a0", 33.110, 46.811, 0.707},
364 {"a1", 23.386, 33.110, 0.706},
365 {"a2", 16.535, 23.386, 0.707},
366 {"a3", 11.693, 16.535, 0.707},
367 {"a4", 8.268, 11.693, 0.707},
368 {"a5", 5.827, 8.268, 0.705},
369 {"a6", 4.134, 5.827, 0.709},
370 {"a7", 2.913, 4.134, 0.705},
371 {"a8", 2.047, 2.913, 0.703},
372 {"a9", 1.457, 2.047, 0.712},
373 {"a10", 1.024, 1.457, 0.703},
374 {"b0", 39.370, 55.669, 0.707},
375 {"b1", 27.835, 39.370, 0.707},
376 {"b2", 19.685, 27.835, 0.707},
377 {"b3", 13.898, 19.685, 0.706},
378 {"b4", 9.843, 13.898, 0.708},
379 {"b5", 6.929, 9.843, 0.704},
380 {"b6", 4.921, 6.929, 0.710},
381 {"c0", 36.102, 51.063, 0.707},
382 {"c1", 25.512, 36.102, 0.707},
383 {"c2", 18.031, 25.512, 0.707},
384 {"c3", 12.756, 18.031, 0.707},
385 {"c4", 9.016, 12.756, 0.707},
386 {"c5", 6.378, 9.016, 0.707},
387 {"c6", 4.488, 6.378, 0.704},
388 {"", 0.000, 0.000, 1.000}
391 /* Structure to define input image parameters */
407 /* Structure to define the output image modifiers */
410 double width; /* width in pixels */
411 double length; /* length in pixels */
412 double hmargin; /* margins to subtract from width of sections */
413 double vmargin; /* margins to subtract from height of sections */
414 double hres; /* horizontal resolution for output */
415 double vres; /* vertical resolution for output */
416 uint32 mode; /* bitmask of modifiers to page format */
417 uint16 res_unit; /* resolution unit for output image */
418 unsigned int rows; /* number of section rows */
419 unsigned int cols; /* number of section cols */
420 unsigned int orient; /* portrait, landscape, seascape, auto */
428 char infilename[PATH_MAX + 1];
429 char outfilename[PATH_MAX + 1];
435 static int outtiled = -1;
436 static uint32 tilewidth = 0;
437 static uint32 tilelength = 0;
439 static uint16 config = 0;
440 static uint16 compression = 0;
441 static uint16 predictor = 0;
442 static uint16 fillorder = 0;
443 static uint32 rowsperstrip = 0;
444 static uint32 g3opts = 0;
445 static int ignore = FALSE; /* if true, ignore read errors */
446 static uint32 defg3opts = (uint32) -1;
447 static int quality = 100; /* JPEG quality */
448 /* static int jpegcolormode = -1; was JPEGCOLORMODE_RGB; */
449 static int jpegcolormode = JPEGCOLORMODE_RGB;
450 static uint16 defcompression = (uint16) -1;
451 static uint16 defpredictor = (uint16) -1;
452 static int pageNum = 0;
453 static int little_endian = 1;
455 /* Functions adapted from tiffcp with additions or significant modifications */
456 static int readContigStripsIntoBuffer (TIFF*, uint8*);
457 static int readSeparateStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
458 static int readContigTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
459 static int readSeparateTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
460 static int writeBufferToContigStrips (TIFF*, uint8*, uint32);
461 static int writeBufferToContigTiles (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
462 static int writeBufferToSeparateStrips (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
463 static int writeBufferToSeparateTiles (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
464 static int extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, tsample_t,
465 uint16, uint16, struct dump_opts *);
466 static int processCompressOptions(char*);
467 static void usage(void);
469 /* All other functions by Richard Nolde, not found in tiffcp */
470 static void initImageData (struct image_data *);
471 static void initCropMasks (struct crop_mask *);
472 static void initPageSetup (struct pagedef *, struct pageseg *, struct buffinfo []);
473 static void initDumpOptions(struct dump_opts *);
475 /* Command line and file naming functions */
476 void process_command_opts (int, char *[], char *, char *, uint32 *,
477 uint16 *, uint16 *, uint32 *, uint32 *, uint32 *,
478 struct crop_mask *, struct pagedef *,
480 unsigned int *, unsigned int *);
481 static int update_output_file (TIFF **, char *, int, char *, unsigned int *);
484 /* * High level functions for whole image manipulation */
485 static int get_page_geometry (char *, struct pagedef*);
486 static int computeInputPixelOffsets(struct crop_mask *, struct image_data *,
488 static int computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
489 struct pagedef *, struct pageseg *,
491 static int loadImage(TIFF *, struct image_data *, struct dump_opts *, unsigned char **);
492 static int correct_orientation(struct image_data *, unsigned char **);
493 static int getCropOffsets(struct image_data *, struct crop_mask *, struct dump_opts *);
494 static int processCropSelections(struct image_data *, struct crop_mask *,
495 unsigned char **, struct buffinfo []);
496 static int writeSelections(TIFF *, TIFF **, struct crop_mask *, struct image_data *,
497 struct dump_opts *, struct buffinfo [],
498 char *, char *, unsigned int*, unsigned int);
500 /* Section functions */
501 static int createImageSection(uint32, unsigned char **);
502 static int extractImageSection(struct image_data *, struct pageseg *,
503 unsigned char *, unsigned char *);
504 static int writeSingleSection(TIFF *, TIFF *, struct image_data *,
505 struct dump_opts *, uint32, uint32,
506 double, double, unsigned char *);
507 static int writeImageSections(TIFF *, TIFF *, struct image_data *,
508 struct pagedef *, struct pageseg *,
509 struct dump_opts *, unsigned char *,
511 /* Whole image functions */
512 static int createCroppedImage(struct image_data *, struct crop_mask *,
513 unsigned char **, unsigned char **);
514 static int writeCroppedImage(TIFF *, TIFF *, struct image_data *image,
515 struct dump_opts * dump,
516 uint32, uint32, unsigned char *, int, int);
518 /* Image manipulation functions */
519 static int rotateContigSamples8bits(uint16, uint16, uint16, uint32,
520 uint32, uint32, uint8 *, uint8 *);
521 static int rotateContigSamples16bits(uint16, uint16, uint16, uint32,
522 uint32, uint32, uint8 *, uint8 *);
523 static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
524 uint32, uint32, uint8 *, uint8 *);
525 static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
526 uint32, uint32, uint8 *, uint8 *);
527 static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
529 static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
531 static int invertImage(uint16, uint16, uint16, uint32, uint32,
534 /* Functions to reverse the sequence of samples in a scanline */
535 static int reverseSamples8bits (uint16, uint16, uint32, uint8 *, uint8 *);
536 static int reverseSamples16bits (uint16, uint16, uint32, uint8 *, uint8 *);
537 static int reverseSamples24bits (uint16, uint16, uint32, uint8 *, uint8 *);
538 static int reverseSamples32bits (uint16, uint16, uint32, uint8 *, uint8 *);
539 static int reverseSamplesBytes (uint16, uint16, uint32, uint8 *, uint8 *);
541 /* Functions for manipulating individual samples in an image */
542 static int extractSeparateRegion(struct image_data *, struct crop_mask *,
543 unsigned char *, unsigned char *, int);
544 static int extractCompositeRegions(struct image_data *, struct crop_mask *,
545 unsigned char *, unsigned char *);
546 static int extractContigSamples8bits (uint8 *, uint8 *, uint32,
547 tsample_t, uint16, uint16,
548 tsample_t, uint32, uint32);
549 static int extractContigSamples16bits (uint8 *, uint8 *, uint32,
550 tsample_t, uint16, uint16,
551 tsample_t, uint32, uint32);
552 static int extractContigSamples24bits (uint8 *, uint8 *, uint32,
553 tsample_t, uint16, uint16,
554 tsample_t, uint32, uint32);
555 static int extractContigSamples32bits (uint8 *, uint8 *, uint32,
556 tsample_t, uint16, uint16,
557 tsample_t, uint32, uint32);
558 static int extractContigSamplesBytes (uint8 *, uint8 *, uint32,
559 tsample_t, uint16, uint16,
560 tsample_t, uint32, uint32);
561 static int extractContigSamplesShifted8bits (uint8 *, uint8 *, uint32,
562 tsample_t, uint16, uint16,
563 tsample_t, uint32, uint32,
565 static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
566 tsample_t, uint16, uint16,
567 tsample_t, uint32, uint32,
569 static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
570 tsample_t, uint16, uint16,
571 tsample_t, uint32, uint32,
573 static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
574 tsample_t, uint16, uint16,
575 tsample_t, uint32, uint32,
577 static int extractContigSamplesToTileBuffer(uint8 *, uint8 *, uint32, uint32,
578 uint32, uint32, tsample_t, uint16,
579 uint16, uint16, struct dump_opts *);
581 /* Functions to combine separate planes into interleaved planes */
582 static int combineSeparateSamples8bits (uint8 *[], uint8 *, uint32, uint32,
583 uint16, uint16, FILE *, int, int);
584 static int combineSeparateSamples16bits (uint8 *[], uint8 *, uint32, uint32,
585 uint16, uint16, FILE *, int, int);
586 static int combineSeparateSamples24bits (uint8 *[], uint8 *, uint32, uint32,
587 uint16, uint16, FILE *, int, int);
588 static int combineSeparateSamples32bits (uint8 *[], uint8 *, uint32, uint32,
589 uint16, uint16, FILE *, int, int);
590 static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
591 uint32, uint32, tsample_t, uint16,
594 static int combineSeparateTileSamples8bits (uint8 *[], uint8 *, uint32, uint32,
595 uint32, uint32, uint16, uint16,
597 static int combineSeparateTileSamples16bits (uint8 *[], uint8 *, uint32, uint32,
598 uint32, uint32, uint16, uint16,
600 static int combineSeparateTileSamples24bits (uint8 *[], uint8 *, uint32, uint32,
601 uint32, uint32, uint16, uint16,
603 static int combineSeparateTileSamples32bits (uint8 *[], uint8 *, uint32, uint32,
604 uint32, uint32, uint16, uint16,
606 static int combineSeparateTileSamplesBytes (unsigned char *[], unsigned char *,
607 uint32, uint32, uint32, uint32,
608 tsample_t, uint16, FILE *, int, int);
610 /* Dump functions for debugging */
611 static void dump_info (FILE *, int, char *, char *, ...);
612 static int dump_data (FILE *, int, char *, unsigned char *, uint32);
613 static int dump_byte (FILE *, int, char *, unsigned char);
614 static int dump_short (FILE *, int, char *, uint16);
615 static int dump_long (FILE *, int, char *, uint32);
616 static int dump_wide (FILE *, int, char *, uint64);
617 static int dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *);
619 /* End function declarations */
620 /* Functions derived in whole or in part from tiffcp */
621 /* The following functions are taken largely intact from tiffcp */
623 static char* usage_info[] = {
624 "usage: tiffcrop [options] source1 ... sourceN destination",
625 "where options are:",
626 " -h Print this syntax listing",
627 " -v Print tiffcrop version identifier and last revision date",
629 " -a Append to output instead of overwriting",
630 " -d offset Set initial directory offset, counting first image as one, not zero",
631 " -p contig Pack samples contiguously (e.g. RGBRGB...)",
632 " -p separate Store samples separately (e.g. RRR...GGG...BBB...)",
633 " -s Write output in strips",
634 " -t Write output in tiles",
635 " -i Ignore read errors",
637 " -r # Make each strip have no more than # rows",
638 " -w # Set output tile width (pixels)",
639 " -l # Set output tile length (pixels)",
641 " -f lsb2msb Force lsb-to-msb FillOrder for output",
642 " -f msb2lsb Force msb-to-lsb FillOrder for output",
644 " -c lzw[:opts] Compress output with Lempel-Ziv & Welch encoding",
645 " -c zip[:opts] Compress output with deflate encoding",
646 " -c jpeg[:opts] Compress output with JPEG encoding",
647 " -c packbits Compress output with packbits encoding",
648 " -c g3[:opts] Compress output with CCITT Group 3 encoding",
649 " -c g4 Compress output with CCITT Group 4 encoding",
650 " -c none Use no compression algorithm on output",
653 " 1d Use default CCITT Group 3 1D-encoding",
654 " 2d Use optional CCITT Group 3 2D-encoding",
655 " fill Byte-align EOL codes",
656 "For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
659 " # Set compression quality level (0-100, default 100)",
660 " raw Output color image as raw YCbCr",
661 " rgb Output color image as RGB",
662 "For example, -c jpeg:rgb:50 to get JPEG-encoded RGB data with 50% comp. quality",
664 "LZW and deflate options:",
665 " # Set predictor value",
666 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
668 "Page and selection options:",
669 " -N odd|even|#,#-#,#|last sequences and ranges of images within file to process",
670 " The words odd or even may be used to specify all odd or even numbered images.",
671 " The word last may be used in place of a number in the sequence to indicate.",
672 " The final image in the file without knowing how many images there are.",
673 " Numbers are counted from one even though TIFF IFDs are counted from zero.",
675 " -E t|l|r|b edge to use as origin for width and length of crop region",
676 " -U units [in, cm, px ] inches, centimeters or pixels",
678 " -m #,#,#,# margins from edges for selection: top, left, bottom, right separated by commas",
679 " -X # horizontal dimension of region to extract expressed in current units",
680 " -Y # vertical dimension of region to extract expressed in current units",
681 " -Z #:#,#:# zones of the image designated as position X of Y,",
682 " eg 1:3 would be first of three equal portions measured from reference edge",
683 " -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
684 " regions of the image designated by upper left and lower right coordinates",
686 "Export grouping options:",
687 " -e c|d|i|m|s export mode for images and selections from input images.",
688 " When exporting a composite image from multiple zones or regions",
689 " (combined and image modes), the selections must have equal sizes",
690 " for the axis perpendicular to the edge specified with -E.",
691 " c|combined All images and selections are written to a single file (default).",
692 " with multiple selections from one image combined into a single image.",
693 " d|divided All images and selections are written to a single file",
694 " with each selection from one image written to a new image.",
695 " i|image Each input image is written to a new file (numeric filename sequence)",
696 " with multiple selections from the image combined into one image.",
697 " m|multiple Each input image is written to a new file (numeric filename sequence)",
698 " with each selection from the image written to a new image.",
699 " s|separated Individual selections from each image are written to separate files.",
702 " -H # Set horizontal resolution of output images to #",
703 " -V # Set vertical resolution of output images to #",
704 " -J # Set horizontal margin of output page to # expressed in current units",
705 " when sectioning image into columns x rows using the -S cols:rows option",
706 " -K # Set verticalal margin of output page to # expressed in current units",
707 " when sectioning image into columns x rows using the -S cols:rows option",
709 " -O orient orientation for output image, portrait, landscape, auto",
710 " -P page page size for output image segments, eg letter, legal, tabloid, etc",
711 " use #.#x#.# to specify a custom page size in the currently defined units",
712 " where #.# represents the width and length",
713 " -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
716 " flip (mirror) image or region horizontally, vertically, or both",
717 " -R # [90,180,or 270] degrees clockwise rotation of image or extracted region",
718 " -I [black|white|data|both]",
719 " invert color space, eg dark to light for bilevel and grayscale images",
720 " If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
721 " tag to MinIsBlack or MinIsWhite without altering the image data",
722 " If the argument is data or both, the image data are modified:",
723 " both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
724 " data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
726 "-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
727 " Debug/dump program progress and/or data to non-TIFF files.",
728 " Options include the following and must be joined as a comma",
729 " separate list. The use of this option is generally limited to",
730 " program debugging and development of future options.",
732 " debug:N Display limited program progress indicators where larger N",
733 " increase the level of detail. Note: Tiffcrop may be compiled with",
734 " -DDEVELMODE to enable additional very low level debug reporting.",
736 " Format:txt|raw Format any logged data as ASCII text or raw binary ",
737 " values. ASCII text dumps include strings of ones and zeroes",
738 " representing the binary values in the image data plus identifying headers.",
740 " level:N Specify the level of detail presented in the dump files.",
741 " This can vary from dumps of the entire input or output image data to dumps",
742 " of data processed by specific functions. Current range of levels is 1 to 3.",
744 " input:full-path-to-directory/input-dumpname",
746 " output:full-path-to-directory/output-dumpnaem",
748 " When dump files are being written, each image will be written to a separate",
749 " file with the name built by adding a numeric sequence value to the dumpname",
750 " and an extension of .txt for ASCII dumps or .bin for binary dumps.",
752 " The four debug/dump options are independent, though it makes little sense to",
753 " specify a dump file without specifying a detail level.",
758 /* This function could be modified to pass starting sample offset
759 * and number of samples as args to select fewer than spp
760 * from input image. These would then be passed to individual
761 * extractContigSampleXX routines.
763 static int readContigTilesIntoBuffer (TIFF* in, uint8* buf,
766 uint32 tw, uint32 tl,
767 tsample_t spp, uint16 bps)
770 tsample_t sample = 0;
771 tsample_t count = spp;
772 uint32 row, col, trow;
774 uint32 dst_rowsize, shift_width;
775 uint32 bytes_per_sample, bytes_per_pixel;
776 uint32 trailing_bits, prev_trailing_bits;
777 uint32 tile_rowsize = TIFFTileRowSize(in);
778 uint32 src_offset, dst_offset;
779 uint32 row_offset, col_offset;
780 uint8 *bufp = (uint8*) buf;
781 unsigned char *src = NULL;
782 unsigned char *dst = NULL;
783 tsize_t tbytes = 0, tile_buffsize = 0;
784 tsize_t tilesize = TIFFTileSize(in);
785 unsigned char *tilebuf = NULL;
787 bytes_per_sample = (bps + 7) / 8;
788 bytes_per_pixel = ((bps * spp) + 7) / 8;
794 if (bytes_per_pixel < (bytes_per_sample + 1))
795 shift_width = bytes_per_pixel;
797 shift_width = bytes_per_sample + 1;
800 tile_buffsize = tilesize;
802 if (tilesize < (tsize_t)(tl * tile_rowsize))
805 TIFFError("readContigTilesIntoBuffer",
806 "Tilesize %lu is too small, using alternate calculation %u",
807 tilesize, tl * tile_rowsize);
809 tile_buffsize = tl * tile_rowsize;
812 tilebuf = _TIFFmalloc(tile_buffsize);
816 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
817 for (row = 0; row < imagelength; row += tl)
819 nrow = (row + tl > imagelength) ? imagelength - row : tl;
820 for (col = 0; col < imagewidth; col += tw)
822 tbytes = TIFFReadTile(in, tilebuf, col, row, 0, 0);
823 if (tbytes < tilesize && !ignore)
825 TIFFError(TIFFFileName(in),
826 "Error, can't read tile at row %lu col %lu, Read %lu bytes of %lu",
827 (unsigned long) col, (unsigned long) row, (unsigned long)tbytes,
828 (unsigned long)tilesize);
834 row_offset = row * dst_rowsize;
835 col_offset = ((col * bps * spp) + 7)/ 8;
836 bufp = buf + row_offset + col_offset;
838 if (col + tw > imagewidth)
839 ncol = imagewidth - col;
843 /* Each tile scanline will start on a byte boundary but it
844 * has to be merged into the scanline for the entire
845 * image buffer and the previous segment may not have
846 * ended on a byte boundary
848 /* Optimization for common bit depths, all samples */
849 if (((bps % 8) == 0) && (count == spp))
851 for (trow = 0; trow < nrow; trow++)
853 src_offset = trow * tile_rowsize;
854 _TIFFmemcpy (bufp, tilebuf + src_offset, (ncol * spp * bps) / 8);
855 bufp += (imagewidth * bps * spp) / 8;
860 /* Bit depths not a multiple of 8 and/or extract fewer than spp samples */
861 prev_trailing_bits = trailing_bits = 0;
862 trailing_bits = (ncol * bps * spp) % 8;
864 /* for (trow = 0; tl < nrow; trow++) */
865 for (trow = 0; trow < nrow; trow++)
867 src_offset = trow * tile_rowsize;
868 src = tilebuf + src_offset;
869 dst_offset = (row + trow) * dst_rowsize;
870 dst = buf + dst_offset + col_offset;
873 case 0: if (extractContigSamplesBytes (src, dst, ncol, sample,
874 spp, bps, count, 0, ncol))
876 TIFFError("readContigTilesIntoBuffer",
877 "Unable to extract row %d from tile %lu",
878 row, (unsigned long)TIFFCurrentTile(in));
882 case 1: if (bps == 1)
884 if (extractContigSamplesShifted8bits (src, dst, ncol,
890 TIFFError("readContigTilesIntoBuffer",
891 "Unable to extract row %d from tile %lu",
892 row, (unsigned long)TIFFCurrentTile(in));
898 if (extractContigSamplesShifted16bits (src, dst, ncol,
904 TIFFError("readContigTilesIntoBuffer",
905 "Unable to extract row %d from tile %lu",
906 row, (unsigned long)TIFFCurrentTile(in));
910 case 2: if (extractContigSamplesShifted24bits (src, dst, ncol,
916 TIFFError("readContigTilesIntoBuffer",
917 "Unable to extract row %d from tile %lu",
918 row, (unsigned long)TIFFCurrentTile(in));
924 case 5: if (extractContigSamplesShifted32bits (src, dst, ncol,
930 TIFFError("readContigTilesIntoBuffer",
931 "Unable to extract row %d from tile %lu",
932 row, (unsigned long)TIFFCurrentTile(in));
936 default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %d", bps);
940 prev_trailing_bits += trailing_bits;
941 if (prev_trailing_bits > 7)
942 prev_trailing_bits-= 8;
951 static int readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf,
952 uint32 imagelength, uint32 imagewidth,
953 uint32 tw, uint32 tl,
954 uint16 spp, uint16 bps)
956 int i, status = 1, sample;
957 int shift_width, bytes_per_pixel;
958 uint16 bytes_per_sample;
959 uint32 row, col; /* Current row and col of image */
960 uint32 nrow, ncol; /* Number of rows and cols in current tile */
961 uint32 row_offset, col_offset; /* Output buffer offsets */
962 tsize_t tbytes = 0, tilesize = TIFFTileSize(in);
964 uint8* bufp = (uint8*)obuf;
965 unsigned char *srcbuffs[MAX_SAMPLES];
966 unsigned char *tbuff = NULL;
968 bytes_per_sample = (bps + 7) / 8;
970 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
972 srcbuffs[sample] = NULL;
973 tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
976 TIFFError ("readSeparateTilesIntoBuffer",
977 "Unable to allocate tile read buffer for sample %d", sample);
978 for (i = 0; i < sample; i++)
979 _TIFFfree (srcbuffs[i]);
982 srcbuffs[sample] = tbuff;
984 /* Each tile contains only the data for a single plane
985 * arranged in scanlines of tw * bytes_per_sample bytes.
987 for (row = 0; row < imagelength; row += tl)
989 nrow = (row + tl > imagelength) ? imagelength - row : tl;
990 for (col = 0; col < imagewidth; col += tw)
992 for (s = 0; s < spp; s++)
993 { /* Read each plane of a tile set into srcbuffs[s] */
994 tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
995 if (tbytes < 0 && !ignore)
997 TIFFError(TIFFFileName(in),
998 "Error, can't read tile for row %lu col %lu, "
1000 (unsigned long) col, (unsigned long) row,
1003 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1005 tbuff = srcbuffs[sample];
1012 /* Tiles on the right edge may be padded out to tw
1013 * which must be a multiple of 16.
1014 * Ncol represents the visible (non padding) portion.
1016 if (col + tw > imagewidth)
1017 ncol = imagewidth - col;
1021 row_offset = row * (((imagewidth * spp * bps) + 7) / 8);
1022 col_offset = ((col * spp * bps) + 7) / 8;
1023 bufp = obuf + row_offset + col_offset;
1027 if (combineSeparateTileSamplesBytes(srcbuffs, bufp, ncol, nrow, imagewidth,
1028 tw, spp, bps, NULL, 0, 0))
1036 bytes_per_pixel = ((bps * spp) + 7) / 8;
1037 if (bytes_per_pixel < (bytes_per_sample + 1))
1038 shift_width = bytes_per_pixel;
1040 shift_width = bytes_per_sample + 1;
1042 switch (shift_width)
1044 case 1: if (combineSeparateTileSamples8bits (srcbuffs, bufp, ncol, nrow,
1045 imagewidth, tw, spp, bps,
1052 case 2: if (combineSeparateTileSamples16bits (srcbuffs, bufp, ncol, nrow,
1053 imagewidth, tw, spp, bps,
1060 case 3: if (combineSeparateTileSamples24bits (srcbuffs, bufp, ncol, nrow,
1061 imagewidth, tw, spp, bps,
1072 case 8: if (combineSeparateTileSamples32bits (srcbuffs, bufp, ncol, nrow,
1073 imagewidth, tw, spp, bps,
1080 default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps);
1088 for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
1090 tbuff = srcbuffs[sample];
1098 static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength)
1100 uint32 row, nrows, rowsperstrip;
1104 TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1105 for (row = 0; row < imagelength; row += rowsperstrip)
1107 nrows = (row + rowsperstrip > imagelength) ?
1108 imagelength - row : rowsperstrip;
1109 stripsize = TIFFVStripSize(out, nrows);
1110 if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
1112 TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1121 /* Abandon plans to modify code so that plannar orientation separate images
1122 * do not have all samples for each channel written before all samples
1123 * for the next channel have been abandoned.
1124 * Libtiff internals seem to depend on all data for a given sample
1125 * being contiguous within a strip or tile when PLANAR_CONFIG is
1126 * separate. All strips or tiles of a given plane are written
1127 * before any strips or tiles of a different plane are stored.
1130 writeBufferToSeparateStrips (TIFF* out, uint8* buf,
1131 uint32 length, uint32 width, uint16 spp,
1132 struct dump_opts *dump)
1136 uint32 row, nrows, rowsize, rowsperstrip;
1137 uint32 bytes_per_sample;
1140 tsize_t stripsize = TIFFStripSize(out);
1141 tsize_t rowstripsize, scanlinesize = TIFFScanlineSize(out);
1142 tsize_t total_bytes = 0;
1145 (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1146 (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1147 bytes_per_sample = (bps + 7) / 8;
1148 rowsize = ((bps * spp * width) + 7) / 8; /* source has interleaved samples */
1149 rowstripsize = rowsperstrip * bytes_per_sample * (width + 1);
1151 obuf = _TIFFmalloc (rowstripsize);
1155 for (s = 0; s < spp; s++)
1157 for (row = 0; row < length; row += rowsperstrip)
1159 nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
1161 stripsize = TIFFVStripSize(out, nrows);
1162 src = buf + (row * rowsize);
1163 total_bytes += stripsize;
1164 memset (obuf, '\0', rowstripsize);
1165 if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
1170 if ((dump->outfile != NULL) && (dump->level == 1))
1172 dump_info(dump->outfile, dump->format,"",
1173 "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d",
1174 s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
1175 dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
1178 if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
1180 TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
1191 /* Extract all planes from contiguous buffer into a single tile buffer
1192 * to be written out as a tile.
1194 static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
1195 uint32 imagewidth, tsample_t spp,
1196 struct dump_opts* dump)
1200 uint32 row, col, nrow, ncol;
1201 uint32 src_rowsize, col_offset;
1202 uint32 tile_rowsize = TIFFTileRowSize(out);
1203 uint8* bufp = (uint8*) buf;
1204 tsize_t tile_buffsize = 0;
1205 tsize_t tilesize = TIFFTileSize(out);
1206 unsigned char *tilebuf = NULL;
1208 TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1209 TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1210 TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1212 tile_buffsize = tilesize;
1213 if (tilesize < (tsize_t)(tl * tile_rowsize))
1216 TIFFError("writeBufferToContigTiles",
1217 "Tilesize %lu is too small, using alternate calculation %u",
1218 tilesize, tl * tile_rowsize);
1220 tile_buffsize = tl * tile_rowsize;
1223 tilebuf = _TIFFmalloc(tile_buffsize);
1227 src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
1228 for (row = 0; row < imagelength; row += tl)
1230 nrow = (row + tl > imagelength) ? imagelength - row : tl;
1231 for (col = 0; col < imagewidth; col += tw)
1233 /* Calculate visible portion of tile. */
1234 if (col + tw > imagewidth)
1235 ncol = imagewidth - col;
1239 col_offset = (((col * bps * spp) + 7) / 8);
1240 bufp = buf + (row * src_rowsize) + col_offset;
1241 if (extractContigSamplesToTileBuffer(tilebuf, bufp, nrow, ncol, imagewidth,
1242 tw, 0, spp, spp, bps, dump) > 0)
1244 TIFFError("writeBufferToContigTiles",
1245 "Unable to extract data to tile for row %lu, col %lu",
1246 (unsigned long) row, (unsigned long)col);
1251 if (TIFFWriteTile(out, tilebuf, col, row, 0, 0) < 0)
1253 TIFFError("writeBufferToContigTiles",
1254 "Cannot write tile at %lu %lu",
1255 (unsigned long) col, (unsigned long) row);
1264 } /* end writeBufferToContigTiles */
1266 /* Extract each plane from contiguous buffer into a single tile buffer
1267 * to be written out as a tile.
1269 static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
1270 uint32 imagewidth, tsample_t spp,
1271 struct dump_opts * dump)
1273 tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1275 uint32 row, col, nrow, ncol;
1276 uint32 src_rowsize, col_offset;
1279 uint8* bufp = (uint8*) buf;
1284 TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1285 TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1286 TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1287 src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
1289 for (row = 0; row < imagelength; row += tl)
1291 nrow = (row + tl > imagelength) ? imagelength - row : tl;
1292 for (col = 0; col < imagewidth; col += tw)
1294 /* Calculate visible portion of tile. */
1295 if (col + tw > imagewidth)
1296 ncol = imagewidth - col;
1300 col_offset = (((col * bps * spp) + 7) / 8);
1301 bufp = buf + (row * src_rowsize) + col_offset;
1303 for (s = 0; s < spp; s++)
1305 if (extractContigSamplesToTileBuffer(obuf, bufp, nrow, ncol, imagewidth,
1306 tw, s, 1, spp, bps, dump) > 0)
1308 TIFFError("writeBufferToSeparateTiles",
1309 "Unable to extract data to tile for row %lu, col %lu sample %d",
1310 (unsigned long) row, (unsigned long)col, (int)s);
1315 if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0)
1317 TIFFError("writeBufferToseparateTiles",
1318 "Cannot write tile at %lu %lu sample %lu",
1319 (unsigned long) col, (unsigned long) row,
1330 } /* end writeBufferToSeparateTiles */
1333 processG3Options(char* cp)
1335 if( (cp = strchr(cp, ':')) ) {
1336 if (defg3opts == (uint32) -1)
1340 if (strneq(cp, "1d", 2))
1341 defg3opts &= ~GROUP3OPT_2DENCODING;
1342 else if (strneq(cp, "2d", 2))
1343 defg3opts |= GROUP3OPT_2DENCODING;
1344 else if (strneq(cp, "fill", 4))
1345 defg3opts |= GROUP3OPT_FILLBITS;
1348 } while( (cp = strchr(cp, ':')) );
1353 processCompressOptions(char* opt)
1357 if (strneq(opt, "none",4))
1359 defcompression = COMPRESSION_NONE;
1361 else if (streq(opt, "packbits"))
1363 defcompression = COMPRESSION_PACKBITS;
1365 else if (strneq(opt, "jpeg", 4))
1367 cp = strchr(opt, ':');
1368 defcompression = COMPRESSION_JPEG;
1372 if (isdigit((int)cp[1]))
1373 quality = atoi(cp + 1);
1374 else if (strneq(cp + 1, "raw", 3 ))
1375 jpegcolormode = JPEGCOLORMODE_RAW;
1376 else if (strneq(cp + 1, "rgb", 3 ))
1377 jpegcolormode = JPEGCOLORMODE_RGB;
1380 cp = strchr(cp + 1, ':');
1383 else if (strneq(opt, "g3", 2))
1385 processG3Options(opt);
1386 defcompression = COMPRESSION_CCITTFAX3;
1388 else if (streq(opt, "g4"))
1390 defcompression = COMPRESSION_CCITTFAX4;
1392 else if (strneq(opt, "lzw", 3))
1394 cp = strchr(opt, ':');
1396 defpredictor = atoi(cp+1);
1397 defcompression = COMPRESSION_LZW;
1399 else if (strneq(opt, "zip", 3))
1401 cp = strchr(opt, ':');
1403 defpredictor = atoi(cp+1);
1404 defcompression = COMPRESSION_ADOBE_DEFLATE;
1417 fprintf(stderr, "\n%s\n", TIFFGetVersion());
1418 for (i = 0; usage_info[i] != NULL; i++)
1419 fprintf(stderr, "%s\n", usage_info[i]);
1423 #define CopyField(tag, v) \
1424 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
1425 #define CopyField2(tag, v1, v2) \
1426 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
1427 #define CopyField3(tag, v1, v2, v3) \
1428 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
1429 #define CopyField4(tag, v1, v2, v3, v4) \
1430 if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
1433 cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
1439 CopyField(tag, shortv);
1440 } else if (count == 2) {
1441 uint16 shortv1, shortv2;
1442 CopyField2(tag, shortv1, shortv2);
1443 } else if (count == 4) {
1444 uint16 *tr, *tg, *tb, *ta;
1445 CopyField4(tag, tr, tg, tb, ta);
1446 } else if (count == (uint16) -1) {
1449 CopyField2(tag, shortv1, shortav);
1454 CopyField(tag, longv);
1460 CopyField(tag, floatv);
1461 } else if (count == (uint16) -1) {
1463 CopyField(tag, floatav);
1468 CopyField(tag, stringv);
1474 CopyField(tag, doublev);
1475 } else if (count == (uint16) -1) {
1477 CopyField(tag, doubleav);
1481 TIFFError(TIFFFileName(in),
1482 "Data type %d is not supported, tag %d skipped",
1487 static struct cpTag {
1492 { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
1493 { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
1494 { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
1495 { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
1496 { TIFFTAG_MAKE, 1, TIFF_ASCII },
1497 { TIFFTAG_MODEL, 1, TIFF_ASCII },
1498 { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
1499 { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
1500 { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
1501 { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
1502 { TIFFTAG_PAGENAME, 1, TIFF_ASCII },
1503 { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
1504 { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
1505 { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
1506 { TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
1507 { TIFFTAG_DATETIME, 1, TIFF_ASCII },
1508 { TIFFTAG_ARTIST, 1, TIFF_ASCII },
1509 { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
1510 { TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
1511 { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
1512 { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
1513 { TIFFTAG_INKSET, 1, TIFF_SHORT },
1514 { TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
1515 { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
1516 { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
1517 { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
1518 { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
1519 { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
1520 { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
1521 { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
1522 { TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
1523 { TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
1524 { TIFFTAG_STONITS, 1, TIFF_DOUBLE },
1526 #define NTAGS (sizeof (tags) / sizeof (tags[0]))
1528 #define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
1530 /* Functions written by Richard Nolde, with exceptions noted. */
1531 void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
1532 uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
1533 uint32 *deftilelength, uint32 *defrowsperstrip,
1534 struct crop_mask *crop_data, struct pagedef *page,
1535 struct dump_opts *dump,
1536 unsigned int *imagelist, unsigned int *image_count )
1538 int c, good_args = 0;
1539 char *opt_offset = NULL; /* Position in string of value sought */
1540 char *opt_ptr = NULL; /* Pointer to next token in option set */
1541 char *sep = NULL; /* Pointer to a token separator */
1542 unsigned int i, j, start, end;
1544 extern char* optarg;
1548 while ((c = getopt(argc, argv,
1549 "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)
1553 case 'a': mode[0] = 'a'; /* append to output */
1555 case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
1557 TIFFError ("Unknown compression option", "%s", optarg);
1558 TIFFError ("For valid options type", "tiffcrop -h");
1562 case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
1565 TIFFError ("","Directory offset must be greater than zero");
1566 TIFFError ("For valid options type", "tiffcrop -h");
1569 *dirnum = start - 1;
1571 case 'e': switch (tolower(optarg[0])) /* image export modes*/
1573 case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
1574 crop_data->img_mode = COMPOSITE_IMAGES;
1575 break; /* Composite */
1576 case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
1577 crop_data->img_mode = SEPARATED_IMAGES;
1578 break; /* Divided */
1579 case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
1580 crop_data->img_mode = COMPOSITE_IMAGES;
1582 case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
1583 crop_data->img_mode = SEPARATED_IMAGES;
1584 break; /* Multiple */
1585 case 's': crop_data->exp_mode = FILE_PER_SELECTION;
1586 crop_data->img_mode = SEPARATED_IMAGES;
1587 break; /* Sections */
1588 default: TIFFError ("Unknown export mode","%s", optarg);
1589 TIFFError ("For valid options type", "tiffcrop -h");
1593 case 'f': if (streq(optarg, "lsb2msb")) /* fill order */
1594 *deffillorder = FILLORDER_LSB2MSB;
1595 else if (streq(optarg, "msb2lsb"))
1596 *deffillorder = FILLORDER_MSB2LSB;
1599 TIFFError ("Unknown fill order", "%s", optarg);
1600 TIFFError ("For valid options type", "tiffcrop -h");
1606 case 'i': ignore = TRUE; /* ignore errors */
1608 case 'l': outtiled = TRUE; /* tile length */
1609 *deftilelength = atoi(optarg);
1611 case 'p': /* planar configuration */
1612 if (streq(optarg, "separate"))
1613 *defconfig = PLANARCONFIG_SEPARATE;
1614 else if (streq(optarg, "contig"))
1615 *defconfig = PLANARCONFIG_CONTIG;
1618 TIFFError ("Unkown planar configuration", "%s", optarg);
1619 TIFFError ("For valid options type", "tiffcrop -h");
1623 case 'r': /* rows/strip */
1624 *defrowsperstrip = atol(optarg);
1626 case 's': /* generate stripped output */
1629 case 't': /* generate tiled output */
1632 case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
1633 TIFFError ("Tiffcrop version", "%s, last updated: %s",
1634 tiffcrop_version_id, tiffcrop_rev_date);
1635 TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
1636 TIFFError (" ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
1637 TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
1640 case 'w': /* tile width */
1642 *deftilewidth = atoi(optarg);
1644 case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
1645 crop_data->crop_mode |= CROP_REGIONS;
1646 for (i = 0, opt_ptr = strtok (optarg, ":");
1647 ((opt_ptr != NULL) && (i < MAX_REGIONS));
1648 (opt_ptr = strtok (NULL, ":")), i++)
1650 crop_data->regions++;
1651 if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
1652 &crop_data->corners[i].X1, &crop_data->corners[i].Y1,
1653 &crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
1655 TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
1656 TIFFError ("For valid options type", "tiffcrop -h");
1660 /* check for remaining elements over MAX_REGIONS */
1661 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
1663 TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
1664 TIFFError ("For valid options type", "tiffcrop -h");
1668 /* options for file open modes */
1669 case 'B': *mp++ = 'b'; *mp = '\0';
1671 case 'L': *mp++ = 'l'; *mp = '\0';
1673 case 'M': *mp++ = 'm'; *mp = '\0';
1675 case 'C': *mp++ = 'c'; *mp = '\0';
1677 /* options for Debugging / data dump */
1678 case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
1680 (opt_ptr = strtok (NULL, ",")), i++)
1682 opt_offset = strpbrk(opt_ptr, ":=");
1683 if (opt_offset == NULL)
1685 TIFFError("Invalid dump option", "%s", optarg);
1686 TIFFError ("For valid options type", "tiffcrop -h");
1691 /* convert option to lowercase */
1692 end = strlen (opt_ptr);
1693 for (i = 0; i < end; i++)
1694 *(opt_ptr + i) = tolower(*(opt_ptr + i));
1695 /* Look for dump format specification */
1696 if (strncmp(opt_ptr, "for", 3) == 0)
1698 /* convert value to lowercase */
1699 end = strlen (opt_offset + 1);
1700 for (i = 1; i <= end; i++)
1701 *(opt_offset + i) = tolower(*(opt_offset + i));
1702 /* check dump format value */
1703 if (strncmp (opt_offset + 1, "txt", 3) == 0)
1705 dump->format = DUMP_TEXT;
1706 strcpy (dump->mode, "w");
1710 if (strncmp(opt_offset + 1, "raw", 3) == 0)
1712 dump->format = DUMP_RAW;
1713 strcpy (dump->mode, "wb");
1717 TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
1718 TIFFError ("For valid options type", "tiffcrop -h");
1724 { /* Look for dump level specification */
1725 if (strncmp (opt_ptr, "lev", 3) == 0)
1726 dump->level = atoi(opt_offset + 1);
1727 /* Look for input data dump file name */
1728 if (strncmp (opt_ptr, "in", 2) == 0)
1730 strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
1731 dump->infilename[PATH_MAX - 20] = '\0';
1733 /* Look for output data dump file name */
1734 if (strncmp (opt_ptr, "out", 3) == 0)
1736 strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
1737 dump->outfilename[PATH_MAX - 20] = '\0';
1739 if (strncmp (opt_ptr, "deb", 3) == 0)
1740 dump->debug = atoi(opt_offset + 1);
1743 if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
1745 if (dump->level == 1)
1746 TIFFError("","Defaulting to dump level 1, no data.");
1747 if (dump->format == DUMP_NONE)
1749 TIFFError("", "You must specify a dump format for dump files");
1750 TIFFError ("For valid options type", "tiffcrop -h");
1756 /* image manipulation routine options */
1757 case 'm': /* margins to exclude from selection, uppercase M was already used */
1758 /* order of values must be TOP, LEFT, BOTTOM, RIGHT */
1759 crop_data->crop_mode |= CROP_MARGINS;
1760 for (i = 0, opt_ptr = strtok (optarg, ",:");
1761 ((opt_ptr != NULL) && (i < 4));
1762 (opt_ptr = strtok (NULL, ",:")), i++)
1764 crop_data->margins[i] = atof(opt_ptr);
1767 case 'E': /* edge reference */
1768 switch (tolower(optarg[0]))
1770 case 't': crop_data->edge_ref = EDGE_TOP;
1772 case 'b': crop_data->edge_ref = EDGE_BOTTOM;
1774 case 'l': crop_data->edge_ref = EDGE_LEFT;
1776 case 'r': crop_data->edge_ref = EDGE_RIGHT;
1778 default: TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
1779 TIFFError ("For valid options type", "tiffcrop -h");
1783 case 'F': /* flip eg mirror image or cropped segment, M was already used */
1784 crop_data->crop_mode |= CROP_MIRROR;
1785 switch (tolower(optarg[0]))
1787 case 'h': crop_data->mirror = MIRROR_HORIZ;
1789 case 'v': crop_data->mirror = MIRROR_VERT;
1791 case 'b': crop_data->mirror = MIRROR_BOTH;
1793 default: TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
1794 TIFFError ("For valid options type", "tiffcrop -h");
1798 case 'H': /* set horizontal resolution to new value */
1799 page->hres = atof (optarg);
1800 page->mode |= PAGE_MODE_RESOLUTION;
1802 case 'I': /* invert the color space, eg black to white */
1803 crop_data->crop_mode |= CROP_INVERT;
1804 /* The PHOTOMETIC_INTERPRETATION tag may be updated */
1805 if (streq(optarg, "black"))
1807 crop_data->photometric = PHOTOMETRIC_MINISBLACK;
1810 if (streq(optarg, "white"))
1812 crop_data->photometric = PHOTOMETRIC_MINISWHITE;
1815 if (streq(optarg, "data"))
1817 crop_data->photometric = INVERT_DATA_ONLY;
1820 if (streq(optarg, "both"))
1822 crop_data->photometric = INVERT_DATA_AND_TAG;
1826 TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
1827 TIFFError ("For valid options type", "tiffcrop -h");
1830 case 'J': /* horizontal margin for sectioned ouput pages */
1831 page->hmargin = atof(optarg);
1832 page->mode |= PAGE_MODE_MARGINS;
1834 case 'K': /* vertical margin for sectioned ouput pages*/
1835 page->vmargin = atof(optarg);
1836 page->mode |= PAGE_MODE_MARGINS;
1838 case 'N': /* list of images to process */
1839 for (i = 0, opt_ptr = strtok (optarg, ",");
1840 ((opt_ptr != NULL) && (i < MAX_IMAGES));
1841 (opt_ptr = strtok (NULL, ",")))
1842 { /* We do not know how many images are in file yet
1843 * so we build a list to include the maximum allowed
1844 * and follow it until we hit the end of the file.
1845 * Image count is not accurate for odd, even, last
1846 * so page numbers won't be valid either.
1848 if (streq(opt_ptr, "odd"))
1850 for (j = 1; j <= MAX_IMAGES; j += 2)
1852 *image_count = (MAX_IMAGES - 1) / 2;
1857 if (streq(opt_ptr, "even"))
1859 for (j = 2; j <= MAX_IMAGES; j += 2)
1861 *image_count = MAX_IMAGES / 2;
1866 if (streq(opt_ptr, "last"))
1867 imagelist[i++] = MAX_IMAGES;
1868 else /* single value between commas */
1870 sep = strpbrk(opt_ptr, ":-");
1872 imagelist[i++] = atoi(opt_ptr);
1876 start = atoi (opt_ptr);
1877 if (!strcmp((sep + 1), "last"))
1880 end = atoi (sep + 1);
1881 for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
1890 case 'O': /* page orientation */
1891 switch (tolower(optarg[0]))
1893 case 'a': page->orient = ORIENTATION_AUTO;
1895 case 'p': page->orient = ORIENTATION_PORTRAIT;
1897 case 'l': page->orient = ORIENTATION_LANDSCAPE;
1899 default: TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
1900 TIFFError ("For valid options type", "tiffcrop -h");
1904 case 'P': /* page size selection */
1905 if (sscanf(optarg, "%lfx%lf", &page->width, &page->length) == 2)
1907 strcpy (page->name, "Custom");
1908 page->mode |= PAGE_MODE_PAPERSIZE;
1911 if (get_page_geometry (optarg, page))
1913 if (!strcmp(optarg, "list"))
1915 TIFFError("", "Name Width Length (in inches)");
1916 for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1917 TIFFError ("", "%-15.15s %5.2f %5.2f",
1918 PaperTable[i].name, PaperTable[i].width,
1919 PaperTable[i].length);
1923 TIFFError ("Invalid paper size", "%s", optarg);
1924 TIFFError ("", "Select one of:");
1925 TIFFError("", "Name Width Length (in inches)");
1926 for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1927 TIFFError ("", "%-15.15s %5.2f %5.2f",
1928 PaperTable[i].name, PaperTable[i].width,
1929 PaperTable[i].length);
1934 page->mode |= PAGE_MODE_PAPERSIZE;
1937 case 'R': /* rotate image or cropped segment */
1938 crop_data->crop_mode |= CROP_ROTATE;
1939 switch (strtoul(optarg, NULL, 0))
1941 case 90: crop_data->rotation = (uint16)90;
1943 case 180: crop_data->rotation = (uint16)180;
1945 case 270: crop_data->rotation = (uint16)270;
1947 default: TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
1948 TIFFError ("For valid options type", "tiffcrop -h");
1952 case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
1953 sep = strpbrk(optarg, ",:");
1957 page->cols = atoi(optarg);
1958 page->rows = atoi(sep +1);
1962 page->cols = atoi(optarg);
1963 page->rows = atoi(optarg);
1965 if ((page->cols * page->rows) > MAX_SECTIONS)
1967 TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
1970 page->mode |= PAGE_MODE_ROWSCOLS;
1972 case 'U': /* units for measurements and offsets */
1973 if (streq(optarg, "in"))
1975 crop_data->res_unit = RESUNIT_INCH;
1976 page->res_unit = RESUNIT_INCH;
1978 else if (streq(optarg, "cm"))
1980 crop_data->res_unit = RESUNIT_CENTIMETER;
1981 page->res_unit = RESUNIT_CENTIMETER;
1983 else if (streq(optarg, "px"))
1985 crop_data->res_unit = RESUNIT_NONE;
1986 page->res_unit = RESUNIT_NONE;
1990 TIFFError ("Illegal unit of measure","%s", optarg);
1991 TIFFError ("For valid options type", "tiffcrop -h");
1995 case 'V': /* set vertical resolution to new value */
1996 page->vres = atof (optarg);
1997 page->mode |= PAGE_MODE_RESOLUTION;
1999 case 'X': /* selection width */
2000 crop_data->crop_mode |= CROP_WIDTH;
2001 crop_data->width = atof(optarg);
2003 case 'Y': /* selection length */
2004 crop_data->crop_mode |= CROP_LENGTH;
2005 crop_data->length = atof(optarg);
2007 case 'Z': /* zones of an image X:Y read as zone X of Y */
2008 crop_data->crop_mode |= CROP_ZONES;
2009 for (i = 0, opt_ptr = strtok (optarg, ",");
2010 ((opt_ptr != NULL) && (i < MAX_REGIONS));
2011 (opt_ptr = strtok (NULL, ",")), i++)
2014 opt_offset = strchr(opt_ptr, ':');
2016 crop_data->zonelist[i].position = atoi(opt_ptr);
2017 crop_data->zonelist[i].total = atoi(opt_offset + 1);
2019 /* check for remaining elements over MAX_REGIONS */
2020 if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
2022 TIFFError("Zone list exceeds region limit", "%d", MAX_REGIONS);
2026 case '?': TIFFError ("For valid options type", "tiffcrop -h");
2031 } /* end process_command_opts */
2033 /* Start a new output file if one has not been previously opened or
2034 * autoindex is set to non-zero. Update page and file counters
2035 * so TIFFTAG PAGENUM will be correct in image.
2038 update_output_file (TIFF **tiffout, char *mode, int autoindex,
2039 char *outname, unsigned int *page)
2041 static int findex = 0; /* file sequence indicator */
2044 char export_ext[16];
2045 char exportname[PATH_MAX];
2047 if (autoindex && (*tiffout != NULL))
2049 /* Close any export file that was previously opened */
2050 TIFFClose (*tiffout);
2054 strcpy (export_ext, ".tiff");
2055 memset (exportname, '\0', PATH_MAX);
2057 /* Leave room for page number portion of the new filename */
2058 strncpy (exportname, outname, PATH_MAX - 16);
2059 if (*tiffout == NULL) /* This is a new export file */
2062 { /* create a new filename for each export */
2064 if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
2066 strncpy (export_ext, sep, 5);
2070 strncpy (export_ext, ".tiff", 5);
2071 export_ext[5] = '\0';
2073 /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
2074 if (findex > MAX_EXPORT_PAGES)
2076 TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES);
2080 sprintf (filenum, "-%03d%s", findex, export_ext);
2082 strncat (exportname, filenum, 15);
2084 exportname[PATH_MAX - 1] = '\0';
2086 *tiffout = TIFFOpen(exportname, mode);
2087 if (*tiffout == NULL)
2089 TIFFError("update_output_file", "Unable to open output file %s", exportname);
2100 } /* end update_output_file */
2104 main(int argc, char* argv[])
2107 uint16 defconfig = (uint16) -1;
2108 uint16 deffillorder = 0;
2109 uint32 deftilewidth = (uint32) 0;
2110 uint32 deftilelength = (uint32) 0;
2111 uint32 defrowsperstrip = (uint32) 0;
2119 /** RJN additions **/
2120 struct image_data image; /* Image parameters for one image */
2121 struct crop_mask crop; /* Cropping parameters for all images */
2122 struct pagedef page; /* Page definition for output pages */
2123 struct pageseg sections[MAX_SECTIONS]; /* Sections of one output page */
2124 struct buffinfo seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
2125 struct dump_opts dump; /* Data dump options */
2126 unsigned char *read_buff = NULL; /* Input image data buffer */
2127 unsigned char *crop_buff = NULL; /* Crop area buffer */
2128 unsigned char *sect_buff = NULL; /* Image section buffer */
2129 unsigned char *sect_src = NULL; /* Image section buffer pointer */
2130 unsigned int imagelist[MAX_IMAGES + 1]; /* individually specified images */
2131 unsigned int image_count = 0;
2132 unsigned int dump_images = 0;
2133 unsigned int next_image = 0;
2134 unsigned int next_page = 0;
2135 unsigned int total_pages = 0;
2136 unsigned int total_images = 0;
2137 unsigned int end_of_input = FALSE;
2139 char temp_filename[PATH_MAX + 1];
2141 little_endian = *((unsigned char *)&little_endian) & '1';
2143 initImageData(&image);
2144 initCropMasks(&crop);
2145 initPageSetup(&page, sections, seg_buffs);
2146 initDumpOptions(&dump);
2148 process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig,
2149 &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
2150 &crop, &page, &dump, imagelist, &image_count);
2152 if (argc - optind < 2)
2155 if ((argc - optind) == 2)
2159 /* read multiple input files and write to output file(s) */
2160 while (optind < argc - 1)
2162 in = TIFFOpen (argv[optind], "r");
2166 /* If only one input file is specified, we can use directory count */
2167 total_images = TIFFNumberOfDirectories(in);
2168 if (image_count == 0)
2171 total_pages = total_images; /* Only valid with single input file */
2175 dirnum = (tdir_t)(imagelist[next_image] - 1);
2178 /* Total pages only valid for enumerated list of pages not derived
2179 * using odd, even, or last keywords.
2181 if (image_count > total_images)
2182 image_count = total_images;
2184 total_pages = image_count;
2187 /* MAX_IMAGES is used for special case "last" in selection list */
2188 if (dirnum == (MAX_IMAGES - 1))
2189 dirnum = total_images - 1;
2191 if (dirnum > (total_images))
2193 TIFFError (TIFFFileName(in),
2194 "Invalid image number %d, File contains only %d images",
2195 (int)dirnum + 1, total_images);
2197 (void) TIFFClose(out);
2201 if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
2203 TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
2205 (void) TIFFClose(out);
2209 end_of_input = FALSE;
2210 while (end_of_input == FALSE)
2213 compression = defcompression;
2214 predictor = defpredictor;
2215 fillorder = deffillorder;
2216 rowsperstrip = defrowsperstrip;
2217 tilewidth = deftilewidth;
2218 tilelength = deftilelength;
2221 if (dump.format != DUMP_NONE)
2223 /* manage input and/or output dump files here */
2225 length = strlen(dump.infilename);
2228 if (dump.infile != NULL)
2229 fclose (dump.infile);
2231 /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes
2232 fewer than PATH_MAX */
2233 memset (temp_filename, '\0', PATH_MAX + 1);
2234 sprintf (temp_filename, "%s-read-%03d.%s", dump.infilename, dump_images,
2235 (dump.format == DUMP_TEXT) ? "txt" : "raw");
2236 if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
2238 TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2241 dump_info(dump.infile, dump.format, "Reading image","%d from %s",
2242 dump_images, TIFFFileName(in));
2244 length = strlen(dump.outfilename);
2247 if (dump.outfile != NULL)
2248 fclose (dump.outfile);
2250 /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes
2251 fewer than PATH_MAX */
2252 memset (temp_filename, '\0', PATH_MAX + 1);
2253 sprintf (temp_filename, "%s-write-%03d.%s", dump.outfilename, dump_images,
2254 (dump.format == DUMP_TEXT) ? "txt" : "raw");
2255 if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
2257 TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
2260 dump_info(dump.outfile, dump.format, "Writing image","%d from %s",
2261 dump_images, TIFFFileName(in));
2266 TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
2268 if (loadImage(in, &image, &dump, &read_buff))
2270 TIFFError("main", "Unable to load source image");
2274 /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
2276 if (image.adjustments != 0)
2278 if (correct_orientation(&image, &read_buff))
2279 TIFFError("main", "Unable to correct image orientation");
2282 if (getCropOffsets(&image, &crop, &dump))
2284 TIFFError("main", "Unable to define crop regions");
2288 if (crop.selections > 0)
2290 if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
2292 TIFFError("main", "Unable to process image selections");
2296 else /* Single image segment without zones or regions */
2298 if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
2300 TIFFError("main", "Unable to create output image");
2304 if (page.mode == PAGE_MODE_NONE)
2305 { /* Whole image or sections not based on output page size */
2306 if (crop.selections > 0)
2308 writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
2309 mp, argv[argc - 1], &next_page, total_pages);
2311 else /* One file all images and sections */
2313 if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
2316 if (writeCroppedImage(in, out, &image, &dump,crop.combined_width,
2317 crop.combined_length, crop_buff, next_page, total_pages))
2319 TIFFError("main", "Unable to write new image");
2326 /* If we used a crop buffer, our data is there, otherwise it is
2327 * in the read_buffer
2329 if (crop_buff != NULL)
2330 sect_src = crop_buff;
2332 sect_src = read_buff;
2333 /* Break input image into pages or rows and columns */
2334 if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
2336 TIFFError("main", "Unable to compute output section data");
2339 /* If there are multiple files on the command line, the final one is assumed
2340 * to be the output filename into which the images are written.
2342 if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
2345 if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, §_buff))
2347 TIFFError("main", "Unable to write image sections");
2352 /* No image list specified, just read the next image */
2353 if (image_count == 0)
2357 dirnum = (tdir_t)(imagelist[next_image] - 1);
2361 if (dirnum == MAX_IMAGES - 1)
2362 dirnum = TIFFNumberOfDirectories(in) - 1;
2364 if (!TIFFSetDirectory(in, (tdir_t)dirnum))
2365 end_of_input = TRUE;
2371 /* If we did not use the read buffer as the crop buffer */
2373 _TIFFfree(read_buff);
2376 _TIFFfree(crop_buff);
2379 _TIFFfree(sect_buff);
2381 /* Clean up any segment buffers used for zones or regions */
2382 for (seg = 0; seg < crop.selections; seg++)
2383 _TIFFfree (seg_buffs[seg].buffer);
2385 if (dump.format != DUMP_NONE)
2387 if (dump.infile != NULL)
2388 fclose (dump.infile);
2390 if (dump.outfile != NULL)
2392 dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
2393 fclose (dump.outfile);
2403 /* Debugging functions */
2404 static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
2408 char dump_array[10];
2409 unsigned char bitset;
2411 if (dumpfile == NULL)
2413 TIFFError ("", "Invalid FILE pointer for dump file");
2417 if (format == DUMP_TEXT)
2419 fprintf (dumpfile," %s ", dump_tag);
2420 for (i = 0; i < count; i++)
2422 for (j = 0, k = 7; j < 8; j++, k--)
2424 bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
2425 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2427 dump_array[8] = '\0';
2428 fprintf (dumpfile," %s", dump_array);
2430 fprintf (dumpfile,"\n");
2434 if ((fwrite (data, 1, count, dumpfile)) != count)
2436 TIFFError ("", "Unable to write binary data to dump file");
2444 static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
2447 char dump_array[10];
2448 unsigned char bitset;
2450 if (dumpfile == NULL)
2452 TIFFError ("", "Invalid FILE pointer for dump file");
2456 if (format == DUMP_TEXT)
2458 fprintf (dumpfile," %s ", dump_tag);
2459 for (j = 0, k = 7; j < 8; j++, k--)
2461 bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2462 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2464 dump_array[8] = '\0';
2465 fprintf (dumpfile," %s\n", dump_array);
2469 if ((fwrite (&data, 1, 1, dumpfile)) != 1)
2471 TIFFError ("", "Unable to write binary data to dump file");
2479 static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
2482 char dump_array[20];
2483 unsigned char bitset;
2485 if (dumpfile == NULL)
2487 TIFFError ("", "Invalid FILE pointer for dump file");
2491 if (format == DUMP_TEXT)
2493 fprintf (dumpfile," %s ", dump_tag);
2494 for (j = 0, k = 15; k >= 0; j++, k--)
2496 bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2497 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2499 sprintf(&dump_array[++j], " ");
2501 dump_array[17] = '\0';
2502 fprintf (dumpfile," %s\n", dump_array);
2506 if ((fwrite (&data, 2, 1, dumpfile)) != 2)
2508 TIFFError ("", "Unable to write binary data to dump file");
2516 static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
2519 char dump_array[40];
2520 unsigned char bitset;
2522 if (dumpfile == NULL)
2524 TIFFError ("", "Invalid FILE pointer for dump file");
2528 if (format == DUMP_TEXT)
2530 fprintf (dumpfile," %s ", dump_tag);
2531 for (j = 0, k = 31; k >= 0; j++, k--)
2533 bitset = data & (((uint32)1 << k)) ? 1 : 0;
2534 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2536 sprintf(&dump_array[++j], " ");
2538 dump_array[35] = '\0';
2539 fprintf (dumpfile," %s\n", dump_array);
2543 if ((fwrite (&data, 4, 1, dumpfile)) != 4)
2545 TIFFError ("", "Unable to write binary data to dump file");
2552 static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
2555 char dump_array[80];
2556 unsigned char bitset;
2558 if (dumpfile == NULL)
2560 TIFFError ("", "Invalid FILE pointer for dump file");
2564 if (format == DUMP_TEXT)
2566 fprintf (dumpfile," %s ", dump_tag);
2567 for (j = 0, k = 63; k >= 0; j++, k--)
2569 bitset = data & (((uint64)1 << k)) ? 1 : 0;
2570 sprintf(&dump_array[j], (bitset) ? "1" : "0");
2572 sprintf(&dump_array[++j], " ");
2574 dump_array[71] = '\0';
2575 fprintf (dumpfile," %s\n", dump_array);
2579 if ((fwrite (&data, 8, 1, dumpfile)) != 8)
2581 TIFFError ("", "Unable to write binary data to dump file");
2589 static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
2591 if (format == DUMP_TEXT)
2595 fprintf(dumpfile, "%s ", prefix);
2596 vfprintf(dumpfile, msg, ap);
2597 fprintf(dumpfile, "\n");
2601 static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width,
2602 uint32 row, unsigned char *buff)
2606 unsigned char * dump_ptr;
2608 if (dumpfile == NULL)
2610 TIFFError ("", "Invalid FILE pointer for dump file");
2614 for (i = 0; i < rows; i++)
2616 dump_ptr = buff + (i * width);
2617 if (format == DUMP_TEXT)
2618 dump_info (dumpfile, format, "",
2619 "Row %4d, %d bytes at offset %d",
2620 row + i + 1, width, row * width);
2622 for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
2623 dump_data (dumpfile, format, "", dump_ptr, 10);
2625 dump_data (dumpfile, format, "", dump_ptr, k);
2630 /* Extract one or more samples from an interleaved buffer. If count == 1,
2631 * only the sample plane indicated by sample will be extracted. If count > 1,
2632 * count samples beginning at sample will be extracted. Portions of a
2633 * scanline can be extracted by specifying a start and end value.
2637 extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols,
2638 tsample_t sample, uint16 spp, uint16 bps,
2639 tsample_t count, uint32 start, uint32 end)
2641 int i, bytes_per_sample, sindex;
2642 uint32 col, dst_rowsize, bit_offset;
2643 uint32 src_byte, src_bit;
2647 if ((src == NULL) || (dst == NULL))
2649 TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
2653 if ((start > end) || (start > cols))
2655 TIFFError ("extractContigSamplesBytes",
2656 "Invalid start column value %d ignored", start);
2659 if ((end == 0) || (end > cols))
2661 TIFFError ("extractContigSamplesBytes",
2662 "Invalid end column value %d ignored", end);
2666 dst_rowsize = (bps * (end - start) * count) / 8;
2668 bytes_per_sample = (bps + 7) / 8;
2669 /* Optimize case for copying all samples */
2672 src = in + (start * spp * bytes_per_sample);
2673 _TIFFmemcpy (dst, src, dst_rowsize);
2677 for (col = start; col < end; col++)
2679 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2681 bit_offset = col * bps * spp;
2684 src_byte = bit_offset / 8;
2685 src_bit = bit_offset % 8;
2689 src_byte = (bit_offset + (sindex * bps)) / 8;
2690 src_bit = (bit_offset + (sindex * bps)) % 8;
2692 src = in + src_byte;
2693 for (i = 0; i < bytes_per_sample; i++)
2700 } /* end extractContigSamplesBytes */
2703 extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
2704 tsample_t sample, uint16 spp, uint16 bps,
2705 tsample_t count, uint32 start, uint32 end)
2707 int ready_bits = 0, sindex = 0;
2708 uint32 col, src_byte, src_bit, bit_offset;
2709 uint8 maskbits = 0, matchbits = 0;
2710 uint8 buff1 = 0, buff2 = 0;
2714 if ((src == NULL) || (dst == NULL))
2716 TIFFError("extractContigSamples8bits","Invalid input or output buffer");
2720 if ((start > end) || (start > cols))
2722 TIFFError ("extractContigSamples8bits",
2723 "Invalid start column value %d ignored", start);
2726 if ((end == 0) || (end > cols))
2728 TIFFError ("extractContigSamples8bits",
2729 "Invalid end column value %d ignored", end);
2734 maskbits = (uint8)-1 >> ( 8 - bps);
2736 for (col = start; col < end; col++)
2737 { /* Compute src byte(s) and bits within byte(s) */
2738 bit_offset = col * bps * spp;
2739 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2743 src_byte = bit_offset / 8;
2744 src_bit = bit_offset % 8;
2748 src_byte = (bit_offset + (sindex * bps)) / 8;
2749 src_bit = (bit_offset + (sindex * bps)) % 8;
2752 src = in + src_byte;
2753 matchbits = maskbits << (8 - src_bit - bps);
2754 buff1 = ((*src) & matchbits) << (src_bit);
2756 /* If we have a full buffer's worth, write it out */
2757 if (ready_bits >= 8)
2764 buff2 = (buff2 | (buff1 >> ready_bits));
2769 while (ready_bits > 0)
2771 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
2777 } /* end extractContigSamples8bits */
2780 extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols,
2781 tsample_t sample, uint16 spp, uint16 bps,
2782 tsample_t count, uint32 start, uint32 end)
2784 int ready_bits = 0, sindex = 0;
2785 uint32 col, src_byte, src_bit, bit_offset;
2786 uint16 maskbits = 0, matchbits = 0;
2787 uint16 buff1 = 0, buff2 = 0;
2792 if ((src == NULL) || (dst == NULL))
2794 TIFFError("extractContigSamples16bits","Invalid input or output buffer");
2798 if ((start > end) || (start > cols))
2800 TIFFError ("extractContigSamples16bits",
2801 "Invalid start column value %d ignored", start);
2804 if ((end == 0) || (end > cols))
2806 TIFFError ("extractContigSamples16bits",
2807 "Invalid end column value %d ignored", end);
2812 maskbits = (uint16)-1 >> (16 - bps);
2814 for (col = start; col < end; col++)
2815 { /* Compute src byte(s) and bits within byte(s) */
2816 bit_offset = col * bps * spp;
2817 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2821 src_byte = bit_offset / 8;
2822 src_bit = bit_offset % 8;
2826 src_byte = (bit_offset + (sindex * bps)) / 8;
2827 src_bit = (bit_offset + (sindex * bps)) % 8;
2830 src = in + src_byte;
2831 matchbits = maskbits << (16 - src_bit - bps);
2834 buff1 = (src[0] << 8) | src[1];
2836 buff1 = (src[1] << 8) | src[0];
2838 buff1 = (buff1 & matchbits) << (src_bit);
2839 if (ready_bits < 8) /* add another bps bits to the buffer */
2842 buff2 = (buff2 | (buff1 >> ready_bits));
2844 else /* If we have a full buffer's worth, write it out */
2846 bytebuff = (buff2 >> 8);
2849 /* shift in new bits */
2850 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
2856 /* catch any trailing bits at the end of the line */
2857 while (ready_bits > 0)
2859 bytebuff = (buff2 >> 8);
2865 } /* end extractContigSamples16bits */
2869 extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
2870 tsample_t sample, uint16 spp, uint16 bps,
2871 tsample_t count, uint32 start, uint32 end)
2873 int ready_bits = 0, sindex = 0;
2874 uint32 col, src_byte, src_bit, bit_offset;
2875 uint32 maskbits = 0, matchbits = 0;
2876 uint32 buff1 = 0, buff2 = 0;
2877 uint8 bytebuff1 = 0, bytebuff2 = 0;
2881 if ((in == NULL) || (out == NULL))
2883 TIFFError("extractContigSamples24bits","Invalid input or output buffer");
2887 if ((start > end) || (start > cols))
2889 TIFFError ("extractContigSamples24bits",
2890 "Invalid start column value %d ignored", start);
2893 if ((end == 0) || (end > cols))
2895 TIFFError ("extractContigSamples24bits",
2896 "Invalid end column value %d ignored", end);
2901 maskbits = (uint32)-1 >> ( 32 - bps);
2902 for (col = start; col < end; col++)
2904 /* Compute src byte(s) and bits within byte(s) */
2905 bit_offset = col * bps * spp;
2906 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2910 src_byte = bit_offset / 8;
2911 src_bit = bit_offset % 8;
2915 src_byte = (bit_offset + (sindex * bps)) / 8;
2916 src_bit = (bit_offset + (sindex * bps)) % 8;
2919 src = in + src_byte;
2920 matchbits = maskbits << (32 - src_bit - bps);
2922 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
2924 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
2925 buff1 = (buff1 & matchbits) << (src_bit);
2927 if (ready_bits < 16) /* add another bps bits to the buffer */
2929 bytebuff1 = bytebuff2 = 0;
2930 buff2 = (buff2 | (buff1 >> ready_bits));
2932 else /* If we have a full buffer's worth, write it out */
2934 bytebuff1 = (buff2 >> 24);
2936 bytebuff2 = (buff2 >> 16);
2940 /* shift in new bits */
2941 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
2947 /* catch any trailing bits at the end of the line */
2948 while (ready_bits > 0)
2950 bytebuff1 = (buff2 >> 24);
2953 buff2 = (buff2 << 8);
2954 bytebuff2 = bytebuff1;
2959 } /* end extractContigSamples24bits */
2962 extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
2963 tsample_t sample, uint16 spp, uint16 bps,
2964 tsample_t count, uint32 start, uint32 end)
2966 int ready_bits = 0, sindex = 0, shift_width = 0;
2967 uint32 col, src_byte, src_bit, bit_offset;
2968 uint32 longbuff1 = 0, longbuff2 = 0;
2969 uint64 maskbits = 0, matchbits = 0;
2970 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
2971 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
2975 if ((in == NULL) || (out == NULL))
2977 TIFFError("extractContigSamples32bits","Invalid input or output buffer");
2982 if ((start > end) || (start > cols))
2984 TIFFError ("extractContigSamples32bits",
2985 "Invalid start column value %d ignored", start);
2988 if ((end == 0) || (end > cols))
2990 TIFFError ("extractContigSamples32bits",
2991 "Invalid end column value %d ignored", end);
2995 shift_width = ((bps + 7) / 8) + 1;
2997 maskbits = (uint64)-1 >> ( 64 - bps);
2998 for (col = start; col < end; col++)
3000 /* Compute src byte(s) and bits within byte(s) */
3001 bit_offset = col * bps * spp;
3002 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3006 src_byte = bit_offset / 8;
3007 src_bit = bit_offset % 8;
3011 src_byte = (bit_offset + (sindex * bps)) / 8;
3012 src_bit = (bit_offset + (sindex * bps)) % 8;
3015 src = in + src_byte;
3016 matchbits = maskbits << (64 - src_bit - bps);
3019 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3020 longbuff2 = longbuff1;
3024 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3025 longbuff2 = longbuff1;
3028 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3029 buff1 = (buff3 & matchbits) << (src_bit);
3031 /* If we have a full buffer's worth, write it out */
3032 if (ready_bits >= 32)
3034 bytebuff1 = (buff2 >> 56);
3036 bytebuff2 = (buff2 >> 48);
3038 bytebuff3 = (buff2 >> 40);
3040 bytebuff4 = (buff2 >> 32);
3044 /* shift in new bits */
3045 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3048 { /* add another bps bits to the buffer */
3049 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3050 buff2 = (buff2 | (buff1 >> ready_bits));
3055 while (ready_bits > 0)
3057 bytebuff1 = (buff2 >> 56);
3059 buff2 = (buff2 << 8);
3064 } /* end extractContigSamples32bits */
3067 extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
3068 tsample_t sample, uint16 spp, uint16 bps,
3069 tsample_t count, uint32 start, uint32 end,
3072 int ready_bits = 0, sindex = 0;
3073 uint32 col, src_byte, src_bit, bit_offset;
3074 uint8 maskbits = 0, matchbits = 0;
3075 uint8 buff1 = 0, buff2 = 0;
3079 if ((src == NULL) || (dst == NULL))
3081 TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
3085 if ((start > end) || (start > cols))
3087 TIFFError ("extractContigSamplesShifted8bits",
3088 "Invalid start column value %d ignored", start);
3091 if ((end == 0) || (end > cols))
3093 TIFFError ("extractContigSamplesShifted8bits",
3094 "Invalid end column value %d ignored", end);
3099 maskbits = (uint8)-1 >> ( 8 - bps);
3101 for (col = start; col < end; col++)
3102 { /* Compute src byte(s) and bits within byte(s) */
3103 bit_offset = col * bps * spp;
3104 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3108 src_byte = bit_offset / 8;
3109 src_bit = bit_offset % 8;
3113 src_byte = (bit_offset + (sindex * bps)) / 8;
3114 src_bit = (bit_offset + (sindex * bps)) % 8;
3117 src = in + src_byte;
3118 matchbits = maskbits << (8 - src_bit - bps);
3119 buff1 = ((*src) & matchbits) << (src_bit);
3120 if ((col == start) && (sindex == sample))
3121 buff2 = *src & ((uint8)-1) << (shift);
3123 /* If we have a full buffer's worth, write it out */
3124 if (ready_bits >= 8)
3131 buff2 = buff2 | (buff1 >> ready_bits);
3136 while (ready_bits > 0)
3138 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3144 } /* end extractContigSamplesShifted8bits */
3147 extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols,
3148 tsample_t sample, uint16 spp, uint16 bps,
3149 tsample_t count, uint32 start, uint32 end,
3152 int ready_bits = 0, sindex = 0;
3153 uint32 col, src_byte, src_bit, bit_offset;
3154 uint16 maskbits = 0, matchbits = 0;
3155 uint16 buff1 = 0, buff2 = 0;
3160 if ((src == NULL) || (dst == NULL))
3162 TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
3166 if ((start > end) || (start > cols))
3168 TIFFError ("extractContigSamplesShifted16bits",
3169 "Invalid start column value %d ignored", start);
3172 if ((end == 0) || (end > cols))
3174 TIFFError ("extractContigSamplesShifted16bits",
3175 "Invalid end column value %d ignored", end);
3180 maskbits = (uint16)-1 >> (16 - bps);
3181 for (col = start; col < end; col++)
3182 { /* Compute src byte(s) and bits within byte(s) */
3183 bit_offset = col * bps * spp;
3184 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3188 src_byte = bit_offset / 8;
3189 src_bit = bit_offset % 8;
3193 src_byte = (bit_offset + (sindex * bps)) / 8;
3194 src_bit = (bit_offset + (sindex * bps)) % 8;
3197 src = in + src_byte;
3198 matchbits = maskbits << (16 - src_bit - bps);
3200 buff1 = (src[0] << 8) | src[1];
3202 buff1 = (src[1] << 8) | src[0];
3204 if ((col == start) && (sindex == sample))
3205 buff2 = buff1 & ((uint16)-1) << (8 - shift);
3207 buff1 = (buff1 & matchbits) << (src_bit);
3209 if (ready_bits < 8) /* add another bps bits to the buffer */
3210 buff2 = buff2 | (buff1 >> ready_bits);
3211 else /* If we have a full buffer's worth, write it out */
3213 bytebuff = (buff2 >> 8);
3216 /* shift in new bits */
3217 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3224 /* catch any trailing bits at the end of the line */
3225 while (ready_bits > 0)
3227 bytebuff = (buff2 >> 8);
3233 } /* end extractContigSamplesShifted16bits */
3237 extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
3238 tsample_t sample, uint16 spp, uint16 bps,
3239 tsample_t count, uint32 start, uint32 end,
3242 int ready_bits = 0, sindex = 0;
3243 uint32 col, src_byte, src_bit, bit_offset;
3244 uint32 maskbits = 0, matchbits = 0;
3245 uint32 buff1 = 0, buff2 = 0;
3246 uint8 bytebuff1 = 0, bytebuff2 = 0;
3250 if ((in == NULL) || (out == NULL))
3252 TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
3256 if ((start > end) || (start > cols))
3258 TIFFError ("extractContigSamplesShifted24bits",
3259 "Invalid start column value %d ignored", start);
3262 if ((end == 0) || (end > cols))
3264 TIFFError ("extractContigSamplesShifted24bits",
3265 "Invalid end column value %d ignored", end);
3270 maskbits = (uint32)-1 >> ( 32 - bps);
3271 for (col = start; col < end; col++)
3273 /* Compute src byte(s) and bits within byte(s) */
3274 bit_offset = col * bps * spp;
3275 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3279 src_byte = bit_offset / 8;
3280 src_bit = bit_offset % 8;
3284 src_byte = (bit_offset + (sindex * bps)) / 8;
3285 src_bit = (bit_offset + (sindex * bps)) % 8;
3288 src = in + src_byte;
3289 matchbits = maskbits << (32 - src_bit - bps);
3291 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3293 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3295 if ((col == start) && (sindex == sample))
3296 buff2 = buff1 & ((uint32)-1) << (16 - shift);
3298 buff1 = (buff1 & matchbits) << (src_bit);
3300 if (ready_bits < 16) /* add another bps bits to the buffer */
3302 bytebuff1 = bytebuff2 = 0;
3303 buff2 = (buff2 | (buff1 >> ready_bits));
3305 else /* If we have a full buffer's worth, write it out */
3307 bytebuff1 = (buff2 >> 24);
3309 bytebuff2 = (buff2 >> 16);
3313 /* shift in new bits */
3314 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3320 /* catch any trailing bits at the end of the line */
3321 while (ready_bits > 0)
3323 bytebuff1 = (buff2 >> 24);
3326 buff2 = (buff2 << 8);
3327 bytebuff2 = bytebuff1;
3332 } /* end extractContigSamplesShifted24bits */
3335 extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
3336 tsample_t sample, uint16 spp, uint16 bps,
3337 tsample_t count, uint32 start, uint32 end,
3340 int ready_bits = 0, sindex = 0, shift_width = 0;
3341 uint32 col, src_byte, src_bit, bit_offset;
3342 uint32 longbuff1 = 0, longbuff2 = 0;
3343 uint64 maskbits = 0, matchbits = 0;
3344 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3345 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3349 if ((in == NULL) || (out == NULL))
3351 TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
3356 if ((start > end) || (start > cols))
3358 TIFFError ("extractContigSamplesShifted32bits",
3359 "Invalid start column value %d ignored", start);
3362 if ((end == 0) || (end > cols))
3364 TIFFError ("extractContigSamplesShifted32bits",
3365 "Invalid end column value %d ignored", end);
3369 shift_width = ((bps + 7) / 8) + 1;
3371 maskbits = (uint64)-1 >> ( 64 - bps);
3372 for (col = start; col < end; col++)
3374 /* Compute src byte(s) and bits within byte(s) */
3375 bit_offset = col * bps * spp;
3376 for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3380 src_byte = bit_offset / 8;
3381 src_bit = bit_offset % 8;
3385 src_byte = (bit_offset + (sindex * bps)) / 8;
3386 src_bit = (bit_offset + (sindex * bps)) % 8;
3389 src = in + src_byte;
3390 matchbits = maskbits << (64 - src_bit - bps);
3393 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3394 longbuff2 = longbuff1;
3398 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3399 longbuff2 = longbuff1;
3402 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3403 if ((col == start) && (sindex == sample))
3404 buff2 = buff3 & ((uint64)-1) << (32 - shift);
3406 buff1 = (buff3 & matchbits) << (src_bit);
3408 if (ready_bits < 32)
3409 { /* add another bps bits to the buffer */
3410 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3411 buff2 = (buff2 | (buff1 >> ready_bits));
3413 else /* If we have a full buffer's worth, write it out */
3415 bytebuff1 = (buff2 >> 56);
3417 bytebuff2 = (buff2 >> 48);
3419 bytebuff3 = (buff2 >> 40);
3421 bytebuff4 = (buff2 >> 32);
3425 /* shift in new bits */
3426 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3431 while (ready_bits > 0)
3433 bytebuff1 = (buff2 >> 56);
3435 buff2 = (buff2 << 8);
3440 } /* end extractContigSamplesShifted32bits */
3443 extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3444 tsample_t sample, uint16 spp, uint16 bps,
3445 struct dump_opts *dump)
3447 int shift_width, bytes_per_sample, bytes_per_pixel;
3448 uint32 src_rowsize, src_offset, row, first_col = 0;
3449 uint32 dst_rowsize, dst_offset;
3450 tsample_t count = 1;
3453 bytes_per_sample = (bps + 7) / 8;
3454 bytes_per_pixel = ((bps * spp) + 7) / 8;
3459 if (bytes_per_pixel < (bytes_per_sample + 1))
3460 shift_width = bytes_per_pixel;
3462 shift_width = bytes_per_sample + 1;
3464 src_rowsize = ((bps * spp * cols) + 7) / 8;
3465 dst_rowsize = ((bps * cols) + 7) / 8;
3467 if ((dump->outfile != NULL) && (dump->level == 4))
3469 dump_info (dump->outfile, dump->format, "extractContigSamplesToBuffer",
3470 "Sample %d, %d rows", sample + 1, rows + 1);
3472 for (row = 0; row < rows; row++)
3474 src_offset = row * src_rowsize;
3475 dst_offset = row * dst_rowsize;
3476 src = in + src_offset;
3477 dst = out + dst_offset;
3479 /* pack the data into the scanline */
3480 switch (shift_width)
3482 case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3483 spp, bps, count, first_col, cols))
3486 case 1: if (bps == 1)
3488 if (extractContigSamples8bits (src, dst, cols, sample,
3489 spp, bps, count, first_col, cols))
3494 if (extractContigSamples16bits (src, dst, cols, sample,
3495 spp, bps, count, first_col, cols))
3498 case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3499 spp, bps, count, first_col, cols))
3504 case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3505 spp, bps, count, first_col, cols))
3508 default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
3511 if ((dump->outfile != NULL) && (dump->level == 4))
3512 dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3516 } /* end extractContigSamplesToBuffer */
3519 extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3520 uint32 imagewidth, uint32 tilewidth, tsample_t sample,
3521 uint16 count, uint16 spp, uint16 bps, struct dump_opts *dump)
3523 int shift_width, bytes_per_sample, bytes_per_pixel;
3524 uint32 src_rowsize, src_offset, row;
3525 uint32 dst_rowsize, dst_offset;
3528 bytes_per_sample = (bps + 7) / 8;
3529 bytes_per_pixel = ((bps * spp) + 7) / 8;
3534 if (bytes_per_pixel < (bytes_per_sample + 1))
3535 shift_width = bytes_per_pixel;
3537 shift_width = bytes_per_sample + 1;
3540 if ((dump->outfile != NULL) && (dump->level == 4))
3542 dump_info (dump->outfile, dump->format, "extractContigSamplesToTileBuffer",
3543 "Sample %d, %d rows", sample + 1, rows + 1);
3546 src_rowsize = ((bps * spp * imagewidth) + 7) / 8;
3547 dst_rowsize = ((bps * tilewidth * count) + 7) / 8;
3549 for (row = 0; row < rows; row++)
3551 src_offset = row * src_rowsize;
3552 dst_offset = row * dst_rowsize;
3553 src = in + src_offset;
3554 dst = out + dst_offset;
3556 /* pack the data into the scanline */
3557 switch (shift_width)
3559 case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3560 spp, bps, count, 0, cols))
3563 case 1: if (bps == 1)
3565 if (extractContigSamples8bits (src, dst, cols, sample,
3566 spp, bps, count, 0, cols))
3571 if (extractContigSamples16bits (src, dst, cols, sample,
3572 spp, bps, count, 0, cols))
3575 case 2: if (extractContigSamples24bits (src, dst, cols, sample,
3576 spp, bps, count, 0, cols))
3581 case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3582 spp, bps, count, 0, cols))
3585 default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps);
3588 if ((dump->outfile != NULL) && (dump->level == 4))
3589 dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3593 } /* end extractContigSamplesToTileBuffer */
3595 static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
3598 int32 bytes_read = 0;
3599 uint16 strip, nstrips = TIFFNumberOfStrips(in);
3600 uint32 stripsize = TIFFStripSize(in);
3602 uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
3603 tsize_t scanline_size = TIFFScanlineSize(in);
3605 for (strip = 0; strip < nstrips; strip++)
3607 bytes_read = TIFFReadEncodedStrip (in, strip, bufp, -1);
3608 rows = bytes_read / scanline_size;
3609 if ((strip < (nstrips - 1)) && (bytes_read != (int32)stripsize))
3610 TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
3611 (int)strip + 1, (unsigned long) bytes_read, (unsigned long)stripsize);
3613 if (bytes_read < 0 && !ignore)
3615 TIFFError("", "Error reading strip %lu after %lu rows",
3616 (unsigned long) strip, (unsigned long)rows);
3623 } /* end readContigStripsIntoBuffer */
3626 combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
3627 uint32 cols, uint32 rows, uint16 spp, uint16 bps,
3628 FILE *dumpfile, int format, int level)
3630 int i, bytes_per_sample;
3631 uint32 row, col, col_offset, src_rowsize, dst_rowsize, row_offset;
3638 if ((src == NULL) || (dst == NULL))
3640 TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
3644 bytes_per_sample = (bps + 7) / 8;
3646 src_rowsize = ((bps * cols) + 7) / 8;
3647 dst_rowsize = ((bps * spp * cols) + 7) / 8;
3648 for (row = 0; row < rows; row++)
3650 if ((dumpfile != NULL) && (level == 2))
3652 for (s = 0; s < spp; s++)
3654 dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
3655 dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
3658 dst = out + (row * dst_rowsize);
3659 row_offset = row * src_rowsize;
3660 for (col = 0; col < cols; col++)
3662 col_offset = row_offset + (col * (bps / 8));
3663 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3665 src = srcbuffs[s] + col_offset;
3666 for (i = 0; i < bytes_per_sample; i++)
3667 *(dst + i) = *(src + i);
3668 src += bytes_per_sample;
3669 dst += bytes_per_sample;
3673 if ((dumpfile != NULL) && (level == 2))
3675 dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
3676 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3681 } /* end combineSeparateSamplesBytes */
3684 combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
3685 uint32 rows, uint16 spp, uint16 bps,
3686 FILE *dumpfile, int format, int level)
3689 int bytes_per_sample = 0;
3690 uint32 src_rowsize, dst_rowsize, src_offset;
3692 uint32 row, col, src_byte = 0, src_bit = 0;
3693 uint8 maskbits = 0, matchbits = 0;
3694 uint8 buff1 = 0, buff2 = 0;
3696 unsigned char *src = in[0];
3697 unsigned char *dst = out;
3700 if ((src == NULL) || (dst == NULL))
3702 TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
3706 bytes_per_sample = (bps + 7) / 8;
3707 src_rowsize = ((bps * cols) + 7) / 8;
3708 dst_rowsize = ((bps * cols * spp) + 7) / 8;
3709 maskbits = (uint8)-1 >> ( 8 - bps);
3711 for (row = 0; row < rows; row++)
3715 dst = out + (row * dst_rowsize);
3716 src_offset = row * src_rowsize;
3717 for (col = 0; col < cols; col++)
3719 /* Compute src byte(s) and bits within byte(s) */
3720 bit_offset = col * bps;
3721 src_byte = bit_offset / 8;
3722 src_bit = bit_offset % 8;
3724 matchbits = maskbits << (8 - src_bit - bps);
3725 /* load up next sample from each plane */
3726 for (s = 0; s < spp; s++)
3728 src = in[s] + src_offset + src_byte;
3729 buff1 = ((*src) & matchbits) << (src_bit);
3731 /* If we have a full buffer's worth, write it out */
3732 if (ready_bits >= 8)
3737 strcpy (action, "Flush");
3741 buff2 = (buff2 | (buff1 >> ready_bits));
3742 strcpy (action, "Update");
3746 if ((dumpfile != NULL) && (level == 3))
3748 dump_info (dumpfile, format, "",
3749 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3750 row + 1, col + 1, s, src_byte, src_bit, dst - out);
3751 dump_byte (dumpfile, format, "Match bits", matchbits);
3752 dump_byte (dumpfile, format, "Src bits", *src);
3753 dump_byte (dumpfile, format, "Buff1 bits", buff1);
3754 dump_byte (dumpfile, format, "Buff2 bits", buff2);
3755 dump_info (dumpfile, format, "","%s", action);
3762 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3764 if ((dumpfile != NULL) && (level == 3))
3766 dump_info (dumpfile, format, "",
3767 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3768 row + 1, col + 1, src_byte, src_bit, dst - out);
3769 dump_byte (dumpfile, format, "Final bits", buff1);
3773 if ((dumpfile != NULL) && (level >= 2))
3775 dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
3776 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3781 } /* end combineSeparateSamples8bits */
3784 combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
3785 uint32 rows, uint16 spp, uint16 bps,
3786 FILE *dumpfile, int format, int level)
3788 int ready_bits = 0, bytes_per_sample = 0;
3789 uint32 src_rowsize, dst_rowsize;
3790 uint32 bit_offset, src_offset;
3791 uint32 row, col, src_byte = 0, src_bit = 0;
3792 uint16 maskbits = 0, matchbits = 0;
3793 uint16 buff1 = 0, buff2 = 0;
3796 unsigned char *src = in[0];
3797 unsigned char *dst = out;
3800 if ((src == NULL) || (dst == NULL))
3802 TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
3806 bytes_per_sample = (bps + 7) / 8;
3807 src_rowsize = ((bps * cols) + 7) / 8;
3808 dst_rowsize = ((bps * cols * spp) + 7) / 8;
3809 maskbits = (uint16)-1 >> (16 - bps);
3811 for (row = 0; row < rows; row++)
3815 dst = out + (row * dst_rowsize);
3816 src_offset = row * src_rowsize;
3817 for (col = 0; col < cols; col++)
3819 /* Compute src byte(s) and bits within byte(s) */
3820 bit_offset = col * bps;
3821 src_byte = bit_offset / 8;
3822 src_bit = bit_offset % 8;
3824 matchbits = maskbits << (16 - src_bit - bps);
3825 for (s = 0; s < spp; s++)
3827 src = in[s] + src_offset + src_byte;
3829 buff1 = (src[0] << 8) | src[1];
3831 buff1 = (src[1] << 8) | src[0];
3833 buff1 = (buff1 & matchbits) << (src_bit);
3835 /* If we have a full buffer's worth, write it out */
3836 if (ready_bits >= 8)
3838 bytebuff = (buff2 >> 8);
3841 /* shift in new bits */
3842 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3843 strcpy (action, "Flush");
3846 { /* add another bps bits to the buffer */
3848 buff2 = (buff2 | (buff1 >> ready_bits));
3849 strcpy (action, "Update");
3853 if ((dumpfile != NULL) && (level == 3))
3855 dump_info (dumpfile, format, "",
3856 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3857 row + 1, col + 1, s, src_byte, src_bit, dst - out);
3859 dump_short (dumpfile, format, "Match bits", matchbits);
3860 dump_data (dumpfile, format, "Src bits", src, 2);
3861 dump_short (dumpfile, format, "Buff1 bits", buff1);
3862 dump_short (dumpfile, format, "Buff2 bits", buff2);
3863 dump_byte (dumpfile, format, "Write byte", bytebuff);
3864 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
3869 /* catch any trailing bits at the end of the line */
3872 bytebuff = (buff2 >> 8);
3874 if ((dumpfile != NULL) && (level == 3))
3876 dump_info (dumpfile, format, "",
3877 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3878 row + 1, col + 1, src_byte, src_bit, dst - out);
3879 dump_byte (dumpfile, format, "Final bits", bytebuff);
3883 if ((dumpfile != NULL) && (level == 2))
3885 dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
3886 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
3891 } /* end combineSeparateSamples16bits */
3894 combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
3895 uint32 rows, uint16 spp, uint16 bps,
3896 FILE *dumpfile, int format, int level)
3898 int ready_bits = 0, bytes_per_sample = 0;
3899 uint32 src_rowsize, dst_rowsize;
3900 uint32 bit_offset, src_offset;
3901 uint32 row, col, src_byte = 0, src_bit = 0;
3902 uint32 maskbits = 0, matchbits = 0;
3903 uint32 buff1 = 0, buff2 = 0;
3904 uint8 bytebuff1 = 0, bytebuff2 = 0;
3906 unsigned char *src = in[0];
3907 unsigned char *dst = out;
3910 if ((src == NULL) || (dst == NULL))
3912 TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
3916 bytes_per_sample = (bps + 7) / 8;
3917 src_rowsize = ((bps * cols) + 7) / 8;
3918 dst_rowsize = ((bps * cols * spp) + 7) / 8;
3919 maskbits = (uint32)-1 >> ( 32 - bps);
3921 for (row = 0; row < rows; row++)
3925 dst = out + (row * dst_rowsize);
3926 src_offset = row * src_rowsize;
3927 for (col = 0; col < cols; col++)
3929 /* Compute src byte(s) and bits within byte(s) */
3930 bit_offset = col * bps;
3931 src_byte = bit_offset / 8;
3932 src_bit = bit_offset % 8;
3934 matchbits = maskbits << (32 - src_bit - bps);
3935 for (s = 0; s < spp; s++)
3937 src = in[s] + src_offset + src_byte;
3939 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
3941 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
3942 buff1 = (buff1 & matchbits) << (src_bit);
3944 /* If we have a full buffer's worth, write it out */
3945 if (ready_bits >= 16)
3947 bytebuff1 = (buff2 >> 24);
3949 bytebuff2 = (buff2 >> 16);
3953 /* shift in new bits */
3954 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3955 strcpy (action, "Flush");
3958 { /* add another bps bits to the buffer */
3959 bytebuff1 = bytebuff2 = 0;
3960 buff2 = (buff2 | (buff1 >> ready_bits));
3961 strcpy (action, "Update");
3965 if ((dumpfile != NULL) && (level == 3))
3967 dump_info (dumpfile, format, "",
3968 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3969 row + 1, col + 1, s, src_byte, src_bit, dst - out);
3970 dump_long (dumpfile, format, "Match bits ", matchbits);
3971 dump_data (dumpfile, format, "Src bits ", src, 4);
3972 dump_long (dumpfile, format, "Buff1 bits ", buff1);
3973 dump_long (dumpfile, format, "Buff2 bits ", buff2);
3974 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
3975 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
3976 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
3981 /* catch any trailing bits at the end of the line */
3982 while (ready_bits > 0)
3984 bytebuff1 = (buff2 >> 24);
3987 buff2 = (buff2 << 8);
3988 bytebuff2 = bytebuff1;
3992 if ((dumpfile != NULL) && (level == 3))
3994 dump_info (dumpfile, format, "",
3995 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3996 row + 1, col + 1, src_byte, src_bit, dst - out);
3998 dump_long (dumpfile, format, "Match bits ", matchbits);
3999 dump_data (dumpfile, format, "Src bits ", src, 4);
4000 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4001 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4002 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4003 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4004 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4007 if ((dumpfile != NULL) && (level == 2))
4009 dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
4010 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4015 } /* end combineSeparateSamples24bits */
4018 combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4019 uint32 rows, uint16 spp, uint16 bps,
4020 FILE *dumpfile, int format, int level)
4022 int ready_bits = 0, bytes_per_sample = 0, shift_width = 0;
4023 uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4024 uint32 src_byte = 0, src_bit = 0;
4026 uint32 longbuff1 = 0, longbuff2 = 0;
4027 uint64 maskbits = 0, matchbits = 0;
4028 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4029 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4031 unsigned char *src = in[0];
4032 unsigned char *dst = out;
4035 if ((src == NULL) || (dst == NULL))
4037 TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
4041 bytes_per_sample = (bps + 7) / 8;
4042 src_rowsize = ((bps * cols) + 7) / 8;
4043 dst_rowsize = ((bps * cols * spp) + 7) / 8;
4044 maskbits = (uint64)-1 >> ( 64 - bps);
4045 shift_width = ((bps + 7) / 8) + 1;
4047 for (row = 0; row < rows; row++)
4051 dst = out + (row * dst_rowsize);
4052 src_offset = row * src_rowsize;
4053 for (col = 0; col < cols; col++)
4055 /* Compute src byte(s) and bits within byte(s) */
4056 bit_offset = col * bps;
4057 src_byte = bit_offset / 8;
4058 src_bit = bit_offset % 8;
4060 matchbits = maskbits << (64 - src_bit - bps);
4061 for (s = 0; s < spp; s++)
4063 src = in[s] + src_offset + src_byte;
4066 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4067 longbuff2 = longbuff1;
4071 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4072 longbuff2 = longbuff1;
4074 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4075 buff1 = (buff3 & matchbits) << (src_bit);
4077 /* If we have a full buffer's worth, write it out */
4078 if (ready_bits >= 32)
4080 bytebuff1 = (buff2 >> 56);
4082 bytebuff2 = (buff2 >> 48);
4084 bytebuff3 = (buff2 >> 40);
4086 bytebuff4 = (buff2 >> 32);
4090 /* shift in new bits */
4091 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4092 strcpy (action, "Flush");
4095 { /* add another bps bits to the buffer */
4096 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4097 buff2 = (buff2 | (buff1 >> ready_bits));
4098 strcpy (action, "Update");
4102 if ((dumpfile != NULL) && (level == 3))
4104 dump_info (dumpfile, format, "",
4105 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4106 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4107 dump_wide (dumpfile, format, "Match bits ", matchbits);
4108 dump_data (dumpfile, format, "Src bits ", src, 8);
4109 dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4110 dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4111 dump_info (dumpfile, format, "", "Ready bits: %d, %s", ready_bits, action);
4115 while (ready_bits > 0)
4117 bytebuff1 = (buff2 >> 56);
4119 buff2 = (buff2 << 8);
4123 if ((dumpfile != NULL) && (level == 3))
4125 dump_info (dumpfile, format, "",
4126 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4127 row + 1, col + 1, src_byte, src_bit, dst - out);
4129 dump_long (dumpfile, format, "Match bits ", matchbits);
4130 dump_data (dumpfile, format, "Src bits ", src, 4);
4131 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4132 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4133 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4134 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4135 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4138 if ((dumpfile != NULL) && (level == 2))
4140 dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
4141 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4146 } /* end combineSeparateSamples32bits */
4149 combineSeparateTileSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
4150 uint32 cols, uint32 rows, uint32 imagewidth,
4151 uint32 tw, uint16 spp, uint16 bps,
4152 FILE *dumpfile, int format, int level)
4154 int i, bytes_per_sample;
4155 uint32 row, col, col_offset, src_rowsize, dst_rowsize, src_offset;
4162 if ((src == NULL) || (dst == NULL))
4164 TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
4168 bytes_per_sample = (bps + 7) / 8;
4169 src_rowsize = ((bps * tw) + 7) / 8;
4170 dst_rowsize = imagewidth * bytes_per_sample * spp;
4171 for (row = 0; row < rows; row++)
4173 if ((dumpfile != NULL) && (level == 2))
4175 for (s = 0; s < spp; s++)
4177 dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Input data, Sample %d", s);
4178 dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
4181 dst = out + (row * dst_rowsize);
4182 src_offset = row * src_rowsize;
4184 TIFFError("","Tile row %4d, Src offset %6d Dst offset %6d",
4185 row, src_offset, dst - out);
4187 for (col = 0; col < cols; col++)
4189 col_offset = src_offset + (col * (bps / 8));
4190 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4192 src = srcbuffs[s] + col_offset;
4193 for (i = 0; i < bytes_per_sample; i++)
4194 *(dst + i) = *(src + i);
4195 dst += bytes_per_sample;
4199 if ((dumpfile != NULL) && (level == 2))
4201 dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Output data, combined samples");
4202 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4207 } /* end combineSeparateTileSamplesBytes */
4210 combineSeparateTileSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
4211 uint32 rows, uint32 imagewidth,
4212 uint32 tw, uint16 spp, uint16 bps,
4213 FILE *dumpfile, int format, int level)
4216 uint32 src_rowsize, dst_rowsize, src_offset;
4218 uint32 row, col, src_byte = 0, src_bit = 0;
4219 uint8 maskbits = 0, matchbits = 0;
4220 uint8 buff1 = 0, buff2 = 0;
4222 unsigned char *src = in[0];
4223 unsigned char *dst = out;
4226 if ((src == NULL) || (dst == NULL))
4228 TIFFError("combineSeparateTileSamples8bits","Invalid input or output buffer");
4232 src_rowsize = ((bps * tw) + 7) / 8;
4233 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4234 maskbits = (uint8)-1 >> ( 8 - bps);
4236 for (row = 0; row < rows; row++)
4240 dst = out + (row * dst_rowsize);
4241 src_offset = row * src_rowsize;
4242 for (col = 0; col < cols; col++)
4244 /* Compute src byte(s) and bits within byte(s) */
4245 bit_offset = col * bps;
4246 src_byte = bit_offset / 8;
4247 src_bit = bit_offset % 8;
4249 matchbits = maskbits << (8 - src_bit - bps);
4250 /* load up next sample from each plane */
4251 for (s = 0; s < spp; s++)
4253 src = in[s] + src_offset + src_byte;
4254 buff1 = ((*src) & matchbits) << (src_bit);
4256 /* If we have a full buffer's worth, write it out */
4257 if (ready_bits >= 8)
4262 strcpy (action, "Flush");
4266 buff2 = (buff2 | (buff1 >> ready_bits));
4267 strcpy (action, "Update");
4271 if ((dumpfile != NULL) && (level == 3))
4273 dump_info (dumpfile, format, "",
4274 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4275 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4276 dump_byte (dumpfile, format, "Match bits", matchbits);
4277 dump_byte (dumpfile, format, "Src bits", *src);
4278 dump_byte (dumpfile, format, "Buff1 bits", buff1);
4279 dump_byte (dumpfile, format, "Buff2 bits", buff2);
4280 dump_info (dumpfile, format, "","%s", action);
4287 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
4289 if ((dumpfile != NULL) && (level == 3))
4291 dump_info (dumpfile, format, "",
4292 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4293 row + 1, col + 1, src_byte, src_bit, dst - out);
4294 dump_byte (dumpfile, format, "Final bits", buff1);
4298 if ((dumpfile != NULL) && (level >= 2))
4300 dump_info (dumpfile, format, "combineSeparateTileSamples8bits","Output data");
4301 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4306 } /* end combineSeparateTileSamples8bits */
4309 combineSeparateTileSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
4310 uint32 rows, uint32 imagewidth,
4311 uint32 tw, uint16 spp, uint16 bps,
4312 FILE *dumpfile, int format, int level)
4315 uint32 src_rowsize, dst_rowsize;
4316 uint32 bit_offset, src_offset;
4317 uint32 row, col, src_byte = 0, src_bit = 0;
4318 uint16 maskbits = 0, matchbits = 0;
4319 uint16 buff1 = 0, buff2 = 0;
4322 unsigned char *src = in[0];
4323 unsigned char *dst = out;
4326 if ((src == NULL) || (dst == NULL))
4328 TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
4332 src_rowsize = ((bps * tw) + 7) / 8;
4333 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4334 maskbits = (uint16)-1 >> (16 - bps);
4336 for (row = 0; row < rows; row++)
4340 dst = out + (row * dst_rowsize);
4341 src_offset = row * src_rowsize;
4342 for (col = 0; col < cols; col++)
4344 /* Compute src byte(s) and bits within byte(s) */
4345 bit_offset = col * bps;
4346 src_byte = bit_offset / 8;
4347 src_bit = bit_offset % 8;
4349 matchbits = maskbits << (16 - src_bit - bps);
4350 for (s = 0; s < spp; s++)
4352 src = in[s] + src_offset + src_byte;
4354 buff1 = (src[0] << 8) | src[1];
4356 buff1 = (src[1] << 8) | src[0];
4357 buff1 = (buff1 & matchbits) << (src_bit);
4359 /* If we have a full buffer's worth, write it out */
4360 if (ready_bits >= 8)
4362 bytebuff = (buff2 >> 8);
4365 /* shift in new bits */
4366 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
4367 strcpy (action, "Flush");
4370 { /* add another bps bits to the buffer */
4372 buff2 = (buff2 | (buff1 >> ready_bits));
4373 strcpy (action, "Update");
4377 if ((dumpfile != NULL) && (level == 3))
4379 dump_info (dumpfile, format, "",
4380 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4381 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4383 dump_short (dumpfile, format, "Match bits", matchbits);
4384 dump_data (dumpfile, format, "Src bits", src, 2);
4385 dump_short (dumpfile, format, "Buff1 bits", buff1);
4386 dump_short (dumpfile, format, "Buff2 bits", buff2);
4387 dump_byte (dumpfile, format, "Write byte", bytebuff);
4388 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
4393 /* catch any trailing bits at the end of the line */
4396 bytebuff = (buff2 >> 8);
4398 if ((dumpfile != NULL) && (level == 3))
4400 dump_info (dumpfile, format, "",
4401 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4402 row + 1, col + 1, src_byte, src_bit, dst - out);
4403 dump_byte (dumpfile, format, "Final bits", bytebuff);
4407 if ((dumpfile != NULL) && (level == 2))
4409 dump_info (dumpfile, format, "combineSeparateTileSamples16bits","Output data");
4410 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4415 } /* end combineSeparateTileSamples16bits */
4418 combineSeparateTileSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
4419 uint32 rows, uint32 imagewidth,
4420 uint32 tw, uint16 spp, uint16 bps,
4421 FILE *dumpfile, int format, int level)
4424 uint32 src_rowsize, dst_rowsize;
4425 uint32 bit_offset, src_offset;
4426 uint32 row, col, src_byte = 0, src_bit = 0;
4427 uint32 maskbits = 0, matchbits = 0;
4428 uint32 buff1 = 0, buff2 = 0;
4429 uint8 bytebuff1 = 0, bytebuff2 = 0;
4431 unsigned char *src = in[0];
4432 unsigned char *dst = out;
4435 if ((src == NULL) || (dst == NULL))
4437 TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
4441 src_rowsize = ((bps * tw) + 7) / 8;
4442 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4443 maskbits = (uint32)-1 >> ( 32 - bps);
4445 for (row = 0; row < rows; row++)
4449 dst = out + (row * dst_rowsize);
4450 src_offset = row * src_rowsize;
4451 for (col = 0; col < cols; col++)
4453 /* Compute src byte(s) and bits within byte(s) */
4454 bit_offset = col * bps;
4455 src_byte = bit_offset / 8;
4456 src_bit = bit_offset % 8;
4458 matchbits = maskbits << (32 - src_bit - bps);
4459 for (s = 0; s < spp; s++)
4461 src = in[s] + src_offset + src_byte;
4463 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4465 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4466 buff1 = (buff1 & matchbits) << (src_bit);
4468 /* If we have a full buffer's worth, write it out */
4469 if (ready_bits >= 16)
4471 bytebuff1 = (buff2 >> 24);
4473 bytebuff2 = (buff2 >> 16);
4477 /* shift in new bits */
4478 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
4479 strcpy (action, "Flush");
4482 { /* add another bps bits to the buffer */
4483 bytebuff1 = bytebuff2 = 0;
4484 buff2 = (buff2 | (buff1 >> ready_bits));
4485 strcpy (action, "Update");
4489 if ((dumpfile != NULL) && (level == 3))
4491 dump_info (dumpfile, format, "",
4492 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4493 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4494 dump_long (dumpfile, format, "Match bits ", matchbits);
4495 dump_data (dumpfile, format, "Src bits ", src, 4);
4496 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4497 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4498 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4499 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4500 dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
4505 /* catch any trailing bits at the end of the line */
4506 while (ready_bits > 0)
4508 bytebuff1 = (buff2 >> 24);
4511 buff2 = (buff2 << 8);
4512 bytebuff2 = bytebuff1;
4516 if ((dumpfile != NULL) && (level == 3))
4518 dump_info (dumpfile, format, "",
4519 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4520 row + 1, col + 1, src_byte, src_bit, dst - out);
4522 dump_long (dumpfile, format, "Match bits ", matchbits);
4523 dump_data (dumpfile, format, "Src bits ", src, 4);
4524 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4525 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4526 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4527 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4528 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4531 if ((dumpfile != NULL) && (level == 2))
4533 dump_info (dumpfile, format, "combineSeparateTileSamples24bits","Output data");
4534 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
4539 } /* end combineSeparateTileSamples24bits */
4542 combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
4543 uint32 rows, uint32 imagewidth,
4544 uint32 tw, uint16 spp, uint16 bps,
4545 FILE *dumpfile, int format, int level)
4547 int ready_bits = 0, shift_width = 0;
4548 uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
4549 uint32 src_byte = 0, src_bit = 0;
4551 uint32 longbuff1 = 0, longbuff2 = 0;
4552 uint64 maskbits = 0, matchbits = 0;
4553 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
4554 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
4556 unsigned char *src = in[0];
4557 unsigned char *dst = out;
4560 if ((src == NULL) || (dst == NULL))
4562 TIFFError("combineSeparateTileSamples32bits","Invalid input or output buffer");
4566 src_rowsize = ((bps * tw) + 7) / 8;
4567 dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
4568 maskbits = (uint64)-1 >> ( 64 - bps);
4569 shift_width = ((bps + 7) / 8) + 1;
4571 for (row = 0; row < rows; row++)
4575 dst = out + (row * dst_rowsize);
4576 src_offset = row * src_rowsize;
4577 for (col = 0; col < cols; col++)
4579 /* Compute src byte(s) and bits within byte(s) */
4580 bit_offset = col * bps;
4581 src_byte = bit_offset / 8;
4582 src_bit = bit_offset % 8;
4584 matchbits = maskbits << (64 - src_bit - bps);
4585 for (s = 0; s < spp; s++)
4587 src = in[s] + src_offset + src_byte;
4590 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
4591 longbuff2 = longbuff1;
4595 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
4596 longbuff2 = longbuff1;
4599 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
4600 buff1 = (buff3 & matchbits) << (src_bit);
4602 /* If we have a full buffer's worth, write it out */
4603 if (ready_bits >= 32)
4605 bytebuff1 = (buff2 >> 56);
4607 bytebuff2 = (buff2 >> 48);
4609 bytebuff3 = (buff2 >> 40);
4611 bytebuff4 = (buff2 >> 32);
4615 /* shift in new bits */
4616 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
4617 strcpy (action, "Flush");
4620 { /* add another bps bits to the buffer */
4621 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
4622 buff2 = (buff2 | (buff1 >> ready_bits));
4623 strcpy (action, "Update");
4627 if ((dumpfile != NULL) && (level == 3))
4629 dump_info (dumpfile, format, "",
4630 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4631 row + 1, col + 1, s, src_byte, src_bit, dst - out);
4632 dump_wide (dumpfile, format, "Match bits ", matchbits);
4633 dump_data (dumpfile, format, "Src bits ", src, 8);
4634 dump_wide (dumpfile, format, "Buff1 bits ", buff1);
4635 dump_wide (dumpfile, format, "Buff2 bits ", buff2);
4636 dump_info (dumpfile, format, "", "Ready bits: %d, %s", ready_bits, action);
4640 while (ready_bits > 0)
4642 bytebuff1 = (buff2 >> 56);
4644 buff2 = (buff2 << 8);
4648 if ((dumpfile != NULL) && (level == 3))
4650 dump_info (dumpfile, format, "",
4651 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4652 row + 1, col + 1, src_byte, src_bit, dst - out);
4654 dump_long (dumpfile, format, "Match bits ", matchbits);
4655 dump_data (dumpfile, format, "Src bits ", src, 4);
4656 dump_long (dumpfile, format, "Buff1 bits ", buff1);
4657 dump_long (dumpfile, format, "Buff2 bits ", buff2);
4658 dump_byte (dumpfile, format, "Write bits1", bytebuff1);
4659 dump_byte (dumpfile, format, "Write bits2", bytebuff2);
4660 dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
4663 if ((dumpfile != NULL) && (level == 2))
4665 dump_info (dumpfile, format, "combineSeparateTileSamples32bits","Output data");
4666 dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
4671 } /* end combineSeparateTileSamples32bits */
4674 static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
4675 uint32 width, uint16 spp,
4676 struct dump_opts *dump)
4678 int i, j, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
4679 int32 bytes_read = 0;
4680 uint16 bps, nstrips, planar, strips_per_sample;
4681 uint32 src_rowsize, dst_rowsize, rows_processed, rps;
4682 uint32 rows_this_strip = 0;
4685 tsize_t scanlinesize = TIFFScanlineSize(in);
4686 tsize_t stripsize = TIFFStripSize(in);
4687 unsigned char *srcbuffs[MAX_SAMPLES];
4688 unsigned char *buff = NULL;
4689 unsigned char *dst = NULL;
4693 TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
4697 memset (srcbuffs, '\0', sizeof(srcbuffs));
4698 TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
4699 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
4700 TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
4704 bytes_per_sample = (bps + 7) / 8;
4705 bytes_per_pixel = ((bps * spp) + 7) / 8;
4706 if (bytes_per_pixel < (bytes_per_sample + 1))
4707 shift_width = bytes_per_pixel;
4709 shift_width = bytes_per_sample + 1;
4711 src_rowsize = ((bps * width) + 7) / 8;
4712 dst_rowsize = ((bps * width * spp) + 7) / 8;
4715 if ((dump->infile != NULL) && (dump->level == 3))
4717 dump_info (dump->infile, dump->format, "",
4718 "Image width %d, length %d, Scanline size, %4d bytes",
4719 width, length, scanlinesize);
4720 dump_info (dump->infile, dump->format, "",
4721 "Bits per sample %d, Samples per pixel %d, Shift width %d",
4722 bps, spp, shift_width);
4725 /* Libtiff seems to assume/require that data for separate planes are
4726 * written one complete plane after another and not interleaved in any way.
4727 * Multiple scanlines and possibly strips of the same plane must be
4728 * written before data for any other plane.
4730 nstrips = TIFFNumberOfStrips(in);
4731 strips_per_sample = nstrips /spp;
4733 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4736 buff = _TIFFmalloc(stripsize);
4739 TIFFError ("readSeparateStripsIntoBuffer",
4740 "Unable to allocate strip read buffer for sample %d", s);
4741 for (i = 0; i < s; i++)
4742 _TIFFfree (srcbuffs[i]);
4749 for (j = 0; (j < strips_per_sample) && (result == 1); j++)
4751 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4754 strip = (s * strips_per_sample) + j;
4755 bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
4756 rows_this_strip = bytes_read / src_rowsize;
4757 if (bytes_read < 0 && !ignore)
4759 TIFFError(TIFFFileName(in),
4760 "Error, can't read strip %lu for sample %d",
4761 (unsigned long) strip, s + 1);
4766 TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d",
4767 strip, bytes_read, rows_this_strip, shift_width);
4771 if (rps > rows_this_strip)
4772 rps = rows_this_strip;
4773 dst = obuf + (dst_rowsize * rows_processed);
4776 if (combineSeparateSamplesBytes (srcbuffs, dst, width, rps,
4777 spp, bps, dump->infile,
4778 dump->format, dump->level))
4786 switch (shift_width)
4788 case 1: if (combineSeparateSamples8bits (srcbuffs, dst, width, rps,
4789 spp, bps, dump->infile,
4790 dump->format, dump->level))
4796 case 2: if (combineSeparateSamples16bits (srcbuffs, dst, width, rps,
4797 spp, bps, dump->infile,
4798 dump->format, dump->level))
4804 case 3: if (combineSeparateSamples24bits (srcbuffs, dst, width, rps,
4805 spp, bps, dump->infile,
4806 dump->format, dump->level))
4816 case 8: if (combineSeparateSamples32bits (srcbuffs, dst, width, rps,
4817 spp, bps, dump->infile,
4818 dump->format, dump->level))
4824 default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
4830 if ((rows_processed + rps) > length)
4832 rows_processed = length;
4833 rps = length - rows_processed;
4836 rows_processed += rps;
4839 /* free any buffers allocated for each plane or scanline and
4840 * any temporary buffers
4842 for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4850 } /* end readSeparateStripsIntoBuffer */
4853 get_page_geometry (char *name, struct pagedef *page)
4858 for (ptr = name; *ptr; ptr++)
4859 *ptr = (char)tolower((int)*ptr);
4861 for (n = 0; n < MAX_PAPERNAMES; n++)
4863 if (strcmp(name, PaperTable[n].name) == 0)
4865 page->width = PaperTable[n].width;
4866 page->length = PaperTable[n].length;
4867 strncpy (page->name, PaperTable[n].name, 15);
4868 page->name[15] = '\0';
4878 initPageSetup (struct pagedef *page, struct pageseg *pagelist,
4879 struct buffinfo seg_buffs[])
4883 strcpy (page->name, "");
4884 page->mode = PAGE_MODE_NONE;
4885 page->res_unit = RESUNIT_NONE;
4890 page->hmargin = 0.0;
4891 page->vmargin = 0.0;
4894 page->orient = ORIENTATION_NONE;
4896 for (i = 0; i < MAX_SECTIONS; i++)
4898 pagelist[i].x1 = (uint32)0;
4899 pagelist[i].x2 = (uint32)0;
4900 pagelist[i].y1 = (uint32)0;
4901 pagelist[i].y2 = (uint32)0;
4902 pagelist[i].buffsize = (uint32)0;
4903 pagelist[i].position = 0;
4904 pagelist[i].total = 0;
4907 for (i = 0; i < MAX_OUTBUFFS; i++)
4909 seg_buffs[i].size = 0;
4910 seg_buffs[i].buffer = NULL;
4915 initImageData (struct image_data *image)
4921 image->res_unit = RESUNIT_NONE;
4925 image->photometric = 0;
4926 image->orientation = 0;
4927 image->compression = COMPRESSION_NONE;
4928 image->adjustments = 0;
4932 initCropMasks (struct crop_mask *cps)
4936 cps->crop_mode = CROP_NONE;
4937 cps->res_unit = RESUNIT_NONE;
4938 cps->edge_ref = EDGE_TOP;
4941 for (i = 0; i < 4; i++)
4942 cps->margins[i] = 0.0;
4943 cps->bufftotal = (uint32)0;
4944 cps->combined_width = (uint32)0;
4945 cps->combined_length = (uint32)0;
4946 cps->rotation = (uint16)0;
4947 cps->photometric = INVERT_DATA_AND_TAG;
4948 cps->mirror = (uint16)0;
4949 cps->invert = (uint16)0;
4950 cps->zones = (uint32)0;
4951 cps->regions = (uint32)0;
4952 for (i = 0; i < MAX_REGIONS; i++)
4954 cps->corners[i].X1 = 0.0;
4955 cps->corners[i].X2 = 0.0;
4956 cps->corners[i].Y1 = 0.0;
4957 cps->corners[i].Y2 = 0.0;
4958 cps->regionlist[i].x1 = 0;
4959 cps->regionlist[i].x2 = 0;
4960 cps->regionlist[i].y1 = 0;
4961 cps->regionlist[i].y2 = 0;
4962 cps->regionlist[i].width = 0;
4963 cps->regionlist[i].length = 0;
4964 cps->regionlist[i].buffsize = 0;
4965 cps->regionlist[i].buffptr = NULL;
4966 cps->zonelist[i].position = 0;
4967 cps->zonelist[i].total = 0;
4969 cps->exp_mode = ONE_FILE_COMPOSITE;
4970 cps->img_mode = COMPOSITE_IMAGES;
4973 static void initDumpOptions(struct dump_opts *dump)
4976 dump->format = DUMP_NONE;
4978 sprintf (dump->mode, "w");
4979 memset (dump->infilename, '\0', PATH_MAX + 1);
4980 memset (dump->outfilename, '\0',PATH_MAX + 1);
4981 dump->infile = NULL;
4982 dump->outfile = NULL;
4985 /* Compute pixel offsets into the image for margins and fixed regions */
4987 computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
4992 /* Values for these offsets are in pixels from start of image, not bytes,
4993 * and are indexed from zero to width - 1 or length - 1 */
4994 uint32 tmargin, bmargin, lmargin, rmargin;
4995 uint32 startx, endx; /* offsets of first and last columns to extract */
4996 uint32 starty, endy; /* offsets of first and last row to extract */
4997 uint32 width, length, crop_width, crop_length;
4998 uint32 i, max_width, max_length, zwidth, zlength, buffsize;
4999 uint32 x1, x2, y1, y2;
5001 if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
5008 if (((image->xres == 0) || (image->yres == 0)) &&
5009 (crop->res_unit != RESUNIT_NONE) &&
5010 ((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
5011 (crop->crop_mode & CROP_LENGTH) || (crop->crop_mode & CROP_WIDTH)))
5013 TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
5014 TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
5021 /* Translate user units to image units */
5023 switch (crop->res_unit) {
5024 case RESUNIT_CENTIMETER:
5025 if (image->res_unit == RESUNIT_INCH)
5029 if (image->res_unit == RESUNIT_CENTIMETER)
5032 case RESUNIT_NONE: /* Dimensions in pixels */
5037 if (crop->crop_mode & CROP_REGIONS)
5039 max_width = max_length = 0;
5040 for (i = 0; i < crop->regions; i++)
5042 if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
5044 x1 = (uint32) (crop->corners[i].X1 * scale * xres);
5045 x2 = (uint32) (crop->corners[i].X2 * scale * xres);
5046 y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
5047 y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
5051 x1 = (uint32) (crop->corners[i].X1);
5052 x2 = (uint32) (crop->corners[i].X2);
5053 y1 = (uint32) (crop->corners[i].Y1);
5054 y2 = (uint32) (crop->corners[i].Y2);
5057 crop->regionlist[i].x1 = 0;
5059 crop->regionlist[i].x1 = (uint32) (x1 - 1);
5061 if (x2 > image->width - 1)
5062 crop->regionlist[i].x2 = image->width - 1;
5064 crop->regionlist[i].x2 = (uint32) (x2 - 1);
5065 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5068 crop->regionlist[i].y1 = 0;
5070 crop->regionlist[i].y1 = (uint32) (y1 - 1);
5072 if (y2 > image->length - 1)
5073 crop->regionlist[i].y2 = image->length - 1;
5075 crop->regionlist[i].y2 = (uint32) (y2 - 1);
5077 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5079 if (zwidth > max_width)
5081 if (zlength > max_length)
5082 max_length = zlength;
5085 (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
5087 crop->regionlist[i].buffsize = buffsize;
5088 crop->bufftotal += buffsize;
5089 if (crop->img_mode == COMPOSITE_IMAGES)
5091 switch (crop->edge_ref)
5095 crop->combined_length = zlength;
5096 crop->combined_width += zwidth;
5099 case EDGE_TOP: /* width from left, length from top */
5101 crop->combined_width = zwidth;
5102 crop->combined_length += zlength;
5110 /* Convert crop margins into offsets into image
5111 * Margins are expressed as pixel rows and columns, not bytes
5113 if (crop->crop_mode & CROP_MARGINS)
5115 if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5116 { /* User has specified pixels as reference unit */
5117 tmargin = (uint32)(crop->margins[0]);
5118 lmargin = (uint32)(crop->margins[1]);
5119 bmargin = (uint32)(crop->margins[2]);
5120 rmargin = (uint32)(crop->margins[3]);
5123 { /* inches or centimeters specified */
5124 tmargin = (uint32)(crop->margins[0] * scale * yres);
5125 lmargin = (uint32)(crop->margins[1] * scale * xres);
5126 bmargin = (uint32)(crop->margins[2] * scale * yres);
5127 rmargin = (uint32)(crop->margins[3] * scale * xres);
5130 if ((lmargin + rmargin) > image->width)
5132 TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
5133 lmargin = (uint32) 0;
5134 rmargin = (uint32) 0;
5137 if ((tmargin + bmargin) > image->length)
5139 TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length");
5140 tmargin = (uint32) 0;
5141 bmargin = (uint32) 0;
5146 { /* no margins requested */
5147 tmargin = (uint32) 0;
5148 lmargin = (uint32) 0;
5149 bmargin = (uint32) 0;
5150 rmargin = (uint32) 0;
5153 /* Width, height, and margins are expressed as pixel offsets into image */
5154 if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
5156 if (crop->crop_mode & CROP_WIDTH)
5157 width = (uint32)crop->width;
5159 width = image->width - lmargin - rmargin;
5161 if (crop->crop_mode & CROP_LENGTH)
5162 length = (uint32)crop->length;
5164 length = image->length - tmargin - bmargin;
5168 if (crop->crop_mode & CROP_WIDTH)
5169 width = (uint32)(crop->width * scale * image->xres);
5171 width = image->width - lmargin - rmargin;
5173 if (crop->crop_mode & CROP_LENGTH)
5174 length = (uint32)(crop->length * scale * image->yres);
5176 length = image->length - tmargin - bmargin;
5179 off->tmargin = tmargin;
5180 off->bmargin = bmargin;
5181 off->lmargin = lmargin;
5182 off->rmargin = rmargin;
5184 /* Calculate regions defined by margins, width, and length.
5185 * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
5186 * since they are used to compute offsets into buffers */
5187 switch (crop->edge_ref) {
5190 if ((startx + width) >= (image->width - rmargin))
5191 endx = image->width - rmargin - 1;
5193 endx = startx + width - 1;
5195 endy = image->length - bmargin - 1;
5196 if ((endy - length) <= tmargin)
5199 starty = endy - length + 1;
5202 endx = image->width - rmargin - 1;
5203 if ((endx - width) <= lmargin)
5206 startx = endx - width + 1;
5209 if ((starty + length) >= (image->length - bmargin))
5210 endy = image->length - bmargin - 1;
5212 endy = starty + length - 1;
5214 case EDGE_TOP: /* width from left, length from top */
5218 if ((startx + width) >= (image->width - rmargin))
5219 endx = image->width - rmargin - 1;
5221 endx = startx + width - 1;
5224 if ((starty + length) >= (image->length - bmargin))
5225 endy = image->length - bmargin - 1;
5227 endy = starty + length - 1;
5230 off->startx = startx;
5231 off->starty = starty;
5235 crop_width = endx - startx + 1;
5236 crop_length = endy - starty + 1;
5238 if (crop_width <= 0)
5240 TIFFError("computeInputPixelOffsets",
5241 "Invalid left/right margins and /or image crop width requested");
5244 if (crop_width > image->width)
5245 crop_width = image->width;
5247 if (crop_length <= 0)
5249 TIFFError("computeInputPixelOffsets",
5250 "Invalid top/bottom margins and /or image crop length requested");
5253 if (crop_length > image->length)
5254 crop_length = image->length;
5256 off->crop_width = crop_width;
5257 off->crop_length = crop_length;
5260 } /* end computeInputPixelOffsets */
5263 * Translate crop options into pixel offsets for one or more regions of the image.
5264 * Options are applied in this order: margins, specific width and length, zones,
5265 * but all are optional. Margins are relative to each edge. Width, length and
5266 * zones are relative to the specified reference edge. Zones are expressed as
5267 * X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
5268 * 2:3 would indicate the middle third of the region qualified by margins and
5269 * any explicit width and length specified. Regions are specified by coordinates
5270 * of the top left and lower right corners with range 1 to width or height.
5274 getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
5276 struct offset offsets;
5279 uint32 seg, total, need_buff = 0;
5281 uint32 zwidth, zlength;
5283 memset(&offsets, '\0', sizeof(struct offset));
5284 crop->bufftotal = 0;
5285 crop->combined_width = (uint32)0;
5286 crop->combined_length = (uint32)0;
5287 crop->selections = 0;
5289 /* Compute pixel offsets if margins or fixed width or length specified */
5290 if ((crop->crop_mode & CROP_MARGINS) ||
5291 (crop->crop_mode & CROP_REGIONS) ||
5292 (crop->crop_mode & CROP_LENGTH) ||
5293 (crop->crop_mode & CROP_WIDTH))
5295 if (computeInputPixelOffsets(crop, image, &offsets))
5297 TIFFError ("getCropOffsets", "Unable to compute crop margins");
5301 crop->selections = crop->regions;
5302 /* Regions are only calculated from top and left edges with no margins */
5303 if (crop->crop_mode & CROP_REGIONS)
5307 { /* cropped area is the full image */
5308 offsets.tmargin = 0;
5309 offsets.lmargin = 0;
5310 offsets.bmargin = 0;
5311 offsets.rmargin = 0;
5312 offsets.crop_width = image->width;
5313 offsets.crop_length = image->length;
5315 offsets.endx = image->width - 1;
5317 offsets.endy = image->length - 1;
5321 if (dump->outfile != NULL)
5323 dump_info (dump->outfile, dump->format, "", "Margins: Top: %d Left: %d Bottom: %d Right: %d",
5324 offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin);
5325 dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width: %6d Length: %6d",
5326 offsets.crop_width, offsets.crop_length);
5329 if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
5331 if (need_buff == FALSE) /* No margins or fixed width or length areas */
5333 crop->selections = 0;
5334 crop->combined_width = image->width;
5335 crop->combined_length = image->length;
5340 /* Use one region for margins and fixed width or length areas
5341 * even though it was not formally declared as a region.
5343 crop->selections = 1;
5345 crop->zonelist[0].total = 1;
5346 crop->zonelist[0].position = 1;
5350 crop->selections = crop->zones;
5352 for (i = 0; i < crop->zones; i++)
5354 seg = crop->zonelist[i].position;
5355 total = crop->zonelist[i].total;
5357 switch (crop->edge_ref)
5359 case EDGE_LEFT: /* zones from left to right, length from top */
5360 zlength = offsets.crop_length;
5361 crop->regionlist[i].y1 = offsets.starty;
5362 crop->regionlist[i].y2 = offsets.endy;
5364 crop->regionlist[i].x1 = offsets.startx +
5365 (uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
5366 test = (int32)offsets.startx +
5367 (int32)(offsets.crop_width * 1.0 * seg / total);
5369 crop->regionlist[i].x2 = 0;
5372 if (test > (int32)(image->width - 1))
5373 crop->regionlist[i].x2 = image->width - 1;
5375 crop->regionlist[i].x2 = test - 1;
5377 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5379 /* This is passed to extractCropZone or extractCompositeZones */
5380 crop->combined_length = (uint32)zlength;
5381 if (crop->exp_mode == COMPOSITE_IMAGES)
5382 crop->combined_width += (uint32)zwidth;
5384 crop->combined_width = (uint32)zwidth;
5386 case EDGE_BOTTOM: /* width from left, zones from bottom to top */
5387 zwidth = offsets.crop_width;
5388 crop->regionlist[i].x1 = offsets.startx;
5389 crop->regionlist[i].x2 = offsets.endx;
5391 test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
5393 crop->regionlist[i].y1 = 0;
5395 crop->regionlist[i].y1 = test + 1;
5397 test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total);
5399 crop->regionlist[i].y2 = 0;
5402 if (test > (int32)(image->length - 1))
5403 crop->regionlist[i].y2 = image->length - 1;
5405 crop->regionlist[i].y2 = test;
5407 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5409 /* This is passed to extractCropZone or extractCompositeZones */
5410 if (crop->exp_mode == COMPOSITE_IMAGES)
5411 crop->combined_length += (uint32)zlength;
5413 crop->combined_length = (uint32)zlength;
5414 crop->combined_width = (uint32)zwidth;
5416 case EDGE_RIGHT: /* zones from right to left, length from top */
5417 zlength = offsets.crop_length;
5418 crop->regionlist[i].y1 = offsets.starty;
5419 crop->regionlist[i].y2 = offsets.endy;
5421 crop->regionlist[i].x1 = offsets.startx +
5422 (uint32)(offsets.crop_width * (total - seg) * 1.0 / total);
5423 test = offsets.startx +
5424 (offsets.crop_width * (total - seg + 1) * 1.0 / total);
5426 crop->regionlist[i].x2 = 0;
5429 if (test > (int32)(image->width - 1))
5430 crop->regionlist[i].x2 = image->width - 1;
5432 crop->regionlist[i].x2 = test - 1;
5434 zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
5436 /* This is passed to extractCropZone or extractCompositeZones */
5437 crop->combined_length = (uint32)zlength;
5438 if (crop->exp_mode == COMPOSITE_IMAGES)
5439 crop->combined_width += (uint32)zwidth;
5441 crop->combined_width = (uint32)zwidth;
5443 case EDGE_TOP: /* width from left, zones from top to bottom */
5445 zwidth = offsets.crop_width;
5446 crop->regionlist[i].x1 = offsets.startx;
5447 crop->regionlist[i].x2 = offsets.endx;
5449 crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
5450 test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
5452 crop->regionlist[i].y2 = 0;
5455 if (test > (int32)(image->length - 1))
5456 crop->regionlist[i].y2 = image->length - 1;
5458 crop->regionlist[i].y2 = test - 1;
5460 zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
5462 /* This is passed to extractCropZone or extractCompositeZones */
5463 if (crop->exp_mode == COMPOSITE_IMAGES)
5464 crop->combined_length += (uint32)zlength;
5466 crop->combined_length = (uint32)zlength;
5467 crop->combined_width = (uint32)zwidth;
5469 } /* end switch statement */
5472 ((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
5473 crop->regionlist[i].width = (uint32) zwidth;
5474 crop->regionlist[i].length = (uint32) zlength;
5475 crop->regionlist[i].buffsize = buffsize;
5476 crop->bufftotal += buffsize;
5479 if (dump->outfile != NULL)
5480 dump_info (dump->outfile, dump->format, "", "Zone %d, width: %4d, length: %4d, x1: %4d x2: %4d y1: %4d y2: %4d",
5481 i + 1, (uint32)zwidth, (uint32)zlength,
5482 crop->regionlist[i].x1, crop->regionlist[i].x2,
5483 crop->regionlist[i].y1, crop->regionlist[i].y2);
5487 } /* end getCropOffsets */
5491 computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
5492 struct pagedef *page, struct pageseg *sections,
5493 struct dump_opts* dump)
5496 double pwidth, plength; /* Output page width and length in user units*/
5497 uint32 iwidth, ilength; /* Input image width and length in pixels*/
5498 uint32 owidth, olength; /* Output image width and length in pixels*/
5499 uint32 orows, ocols; /* rows and cols for output */
5500 uint32 hmargin, vmargin; /* Horizontal and vertical margins */
5501 uint32 x1, x2, y1, y2, line_bytes;
5502 unsigned int orientation;
5506 if (page->res_unit == RESUNIT_NONE)
5507 page->res_unit = image->res_unit;
5509 switch (image->res_unit) {
5510 case RESUNIT_CENTIMETER:
5511 if (page->res_unit == RESUNIT_INCH)
5515 if (page->res_unit == RESUNIT_CENTIMETER)
5518 case RESUNIT_NONE: /* Dimensions in pixels */
5523 /* get width, height, resolutions of input image selection */
5524 if (crop->combined_width > 0)
5525 iwidth = crop->combined_width;
5527 iwidth = image->width;
5528 if (crop->combined_length > 0)
5529 ilength = crop->combined_length;
5531 ilength = image->length;
5533 if (page->hres <= 1.0)
5534 page->hres = image->xres;
5535 if (page->vres <= 1.0)
5536 page->vres = image->yres;
5538 if ((page->hres < 1.0) || (page->vres < 1.0))
5540 TIFFError("computeOutputPixelOffsets",
5541 "Invalid horizontal or vertical resolution specified or read from input image");
5545 /* If no page sizes are being specified, we just use the input image size to
5546 * calculate maximum margins that can be taken from image.
5548 if (page->width <= 0)
5551 pwidth = page->width;
5553 if (page->length <= 0)
5556 plength = page->length;
5560 TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
5561 "Hmargin: %3.2f, Vmargin: %3.2f",
5562 page->name, page->vres, page->hres,
5563 page->hmargin, page->vmargin);
5564 TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f",
5565 page->res_unit, scale, pwidth, plength);
5568 /* compute margins at specified unit and resolution */
5569 if (page->mode & PAGE_MODE_MARGINS)
5571 if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
5572 { /* inches or centimeters specified */
5573 hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
5574 vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
5577 { /* Otherwise user has specified pixels as reference unit */
5578 hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
5579 vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
5582 if ((hmargin * 2.0) > (pwidth * page->hres))
5584 TIFFError("computeOutputPixelOffsets",
5585 "Combined left and right margins exceed page width");
5586 hmargin = (uint32) 0;
5589 if ((vmargin * 2.0) > (plength * page->vres))
5591 TIFFError("computeOutputPixelOffsets",
5592 "Combined top and bottom margins exceed page length");
5593 vmargin = (uint32) 0;
5603 if (page->mode & PAGE_MODE_ROWSCOLS )
5605 /* Maybe someday but not for now */
5606 if (page->mode & PAGE_MODE_MARGINS)
5607 TIFFError("computeOutputPixelOffsets",
5608 "Output margins cannot be specified with rows and columns");
5610 owidth = TIFFhowmany(iwidth, page->cols);
5611 olength = TIFFhowmany(ilength, page->rows);
5615 if (page->mode & PAGE_MODE_PAPERSIZE )
5617 owidth = (uint32)((pwidth * page->hres) - (hmargin * 2));
5618 olength = (uint32)((plength * page->vres) - (vmargin * 2));
5622 owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
5623 olength = (uint32)(ilength - (vmargin * 2 * page->vres));
5627 if (owidth > iwidth)
5629 if (olength > ilength)
5632 /* Compute the number of pages required for Portrait or Landscape */
5633 switch (page->orient)
5635 case ORIENTATION_NONE:
5636 case ORIENTATION_PORTRAIT:
5637 ocols = TIFFhowmany(iwidth, owidth);
5638 orows = TIFFhowmany(ilength, olength);
5639 orientation = ORIENTATION_PORTRAIT;
5642 case ORIENTATION_LANDSCAPE:
5643 ocols = TIFFhowmany(iwidth, olength);
5644 orows = TIFFhowmany(ilength, owidth);
5648 orientation = ORIENTATION_LANDSCAPE;
5651 case ORIENTATION_AUTO:
5653 x1 = TIFFhowmany(iwidth, owidth);
5654 x2 = TIFFhowmany(ilength, olength);
5655 y1 = TIFFhowmany(iwidth, olength);
5656 y2 = TIFFhowmany(ilength, owidth);
5658 if ( (x1 * x2) < (y1 * y2))
5662 orientation = ORIENTATION_PORTRAIT;
5671 orientation = ORIENTATION_LANDSCAPE;
5680 /* If user did not specify rows and cols, set them from calcuation */
5686 line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
5688 if ((page->rows * page->cols) > MAX_SECTIONS)
5690 TIFFError("computeOutputPixelOffsets",
5691 "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
5695 /* build the list of offsets for each output section */
5696 for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
5698 y1 = (uint32)(olength * i);
5699 y2 = (uint32)(olength * (i + 1) - 1);
5702 for (j = 0; j < ocols; j++, k++)
5704 x1 = (uint32)(owidth * j);
5705 x2 = (uint32)(owidth * (j + 1) - 1);
5708 sections[k].x1 = x1;
5709 sections[k].x2 = x2;
5710 sections[k].y1 = y1;
5711 sections[k].y2 = y2;
5712 sections[k].buffsize = line_bytes * olength;
5713 sections[k].position = k + 1;
5714 sections[k].total = orows * ocols;
5718 } /* end computeOutputPixelOffsets */
5721 loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned char **read_ptr)
5724 float xres = 0.0, yres = 0.0;
5725 uint16 nstrips = 0, ntiles = 0, planar = 0;
5726 uint16 bps = 0, spp = 0, res_unit = 0;
5727 uint16 orientation = 0;
5728 uint16 input_compression = 0, input_photometric = 0;
5729 uint16 subsampling_horiz, subsampling_vert;
5730 uint32 width = 0, length = 0;
5731 uint32 stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
5732 uint32 tw = 0, tl = 0; /* Tile width and length */
5733 uint32 tile_rowsize = 0;
5734 unsigned char *read_buff = NULL;
5735 unsigned char *new_buff = NULL;
5737 static uint32 prev_readsize = 0;
5739 TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
5740 TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
5741 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
5742 TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
5743 if (! TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric))
5744 TIFFError("loadImage","Image lacks Photometric interpreation tag");
5745 if (! TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width))
5746 TIFFError("loadimage","Image lacks image width tag");
5747 if(! TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length))
5748 TIFFError("loadimage","Image lacks image length tag");
5749 TIFFGetFieldDefaulted(in, TIFFTAG_XRESOLUTION, &xres);
5750 TIFFGetFieldDefaulted(in, TIFFTAG_YRESOLUTION, &yres);
5751 if (!TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit))
5752 res_unit = RESUNIT_INCH;
5753 if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression))
5754 input_compression = COMPRESSION_NONE;
5757 char compressionid[16];
5759 switch (input_compression)
5761 case COMPRESSION_NONE: /* 1 dump mode */
5762 strcpy (compressionid, "None/dump");
5764 case COMPRESSION_CCITTRLE: /* 2 CCITT modified Huffman RLE */
5765 strcpy (compressionid, "Huffman RLE");
5767 case COMPRESSION_CCITTFAX3: /* 3 CCITT Group 3 fax encoding */
5768 strcpy (compressionid, "Group3 Fax");
5770 case COMPRESSION_CCITTFAX4: /* 4 CCITT Group 4 fax encoding */
5771 strcpy (compressionid, "Group4 Fax");
5773 case COMPRESSION_LZW: /* 5 Lempel-Ziv & Welch */
5774 strcpy (compressionid, "LZW");
5776 case COMPRESSION_OJPEG: /* 6 !6.0 JPEG */
5777 strcpy (compressionid, "Old Jpeg");
5779 case COMPRESSION_JPEG: /* 7 %JPEG DCT compression */
5780 strcpy (compressionid, "New Jpeg");
5782 case COMPRESSION_NEXT: /* 32766 NeXT 2-bit RLE */
5783 strcpy (compressionid, "Next RLE");
5785 case COMPRESSION_CCITTRLEW: /* 32771 #1 w/ word alignment */
5786 strcpy (compressionid, "CITTRLEW");
5788 case COMPRESSION_PACKBITS: /* 32773 Macintosh RLE */
5789 strcpy (compressionid, "Mac Packbits");
5791 case COMPRESSION_THUNDERSCAN: /* 32809 ThunderScan RLE */
5792 strcpy (compressionid, "Thunderscan");
5794 case COMPRESSION_IT8CTPAD: /* 32895 IT8 CT w/padding */
5795 strcpy (compressionid, "IT8 padded");
5797 case COMPRESSION_IT8LW: /* 32896 IT8 Linework RLE */
5798 strcpy (compressionid, "IT8 RLE");
5800 case COMPRESSION_IT8MP: /* 32897 IT8 Monochrome picture */
5801 strcpy (compressionid, "IT8 mono");
5803 case COMPRESSION_IT8BL: /* 32898 IT8 Binary line art */
5804 strcpy (compressionid, "IT8 lineart");
5806 case COMPRESSION_PIXARFILM: /* 32908 Pixar companded 10bit LZW */
5807 strcpy (compressionid, "Pixar 10 bit");
5809 case COMPRESSION_PIXARLOG: /* 32909 Pixar companded 11bit ZIP */
5810 strcpy (compressionid, "Pixar 11bit");
5812 case COMPRESSION_DEFLATE: /* 32946 Deflate compression */
5813 strcpy (compressionid, "Deflate");
5815 case COMPRESSION_ADOBE_DEFLATE: /* 8 Deflate compression */
5816 strcpy (compressionid, "Adobe deflate");
5819 strcpy (compressionid, "None/unknown");
5822 TIFFError("loadImage", "Input compression %s", compressionid);
5825 scanlinesize = TIFFScanlineSize(in);
5828 image->planar = planar;
5829 image->width = width;
5830 image->length = length;
5833 image->res_unit = res_unit;
5834 image->compression = input_compression;
5835 image->photometric = input_photometric;
5837 char photometricid[12];
5839 switch (input_photometric)
5841 case PHOTOMETRIC_MINISWHITE:
5842 strcpy (photometricid, "MinIsWhite");
5844 case PHOTOMETRIC_MINISBLACK:
5845 strcpy (photometricid, "MinIsBlack");
5847 case PHOTOMETRIC_RGB:
5848 strcpy (photometricid, "RGB");
5850 case PHOTOMETRIC_PALETTE:
5851 strcpy (photometricid, "Palette");
5853 case PHOTOMETRIC_MASK:
5854 strcpy (photometricid, "Mask");
5856 case PHOTOMETRIC_SEPARATED:
5857 strcpy (photometricid, "Separated");
5859 case PHOTOMETRIC_YCBCR:
5860 strcpy (photometricid, "YCBCR");
5862 case PHOTOMETRIC_CIELAB:
5863 strcpy (photometricid, "CIELab");
5865 case PHOTOMETRIC_ICCLAB:
5866 strcpy (photometricid, "ICCLab");
5868 case PHOTOMETRIC_ITULAB:
5869 strcpy (photometricid, "ITULab");
5871 case PHOTOMETRIC_LOGL:
5872 strcpy (photometricid, "LogL");
5874 case PHOTOMETRIC_LOGLUV:
5875 strcpy (photometricid, "LOGLuv");
5878 strcpy (photometricid, "Unknown");
5881 TIFFError("loadImage", "Input photometric interpretation %s", photometricid);
5884 image->orientation = orientation;
5885 switch (orientation)
5888 case ORIENTATION_TOPLEFT:
5889 image->adjustments = 0;
5891 case ORIENTATION_TOPRIGHT:
5892 image->adjustments = MIRROR_HORIZ;
5894 case ORIENTATION_BOTRIGHT:
5895 image->adjustments = ROTATECW_180;
5897 case ORIENTATION_BOTLEFT:
5898 image->adjustments = MIRROR_VERT;
5900 case ORIENTATION_LEFTTOP:
5901 image->adjustments = MIRROR_VERT | ROTATECW_90;
5903 case ORIENTATION_RIGHTTOP:
5904 image->adjustments = ROTATECW_90;
5906 case ORIENTATION_RIGHTBOT:
5907 image->adjustments = MIRROR_VERT | ROTATECW_270;
5909 case ORIENTATION_LEFTBOT:
5910 image->adjustments = ROTATECW_270;
5913 image->adjustments = 0;
5914 image->orientation = ORIENTATION_TOPLEFT;
5917 if ((bps == 0) || (spp == 0))
5919 TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
5924 if (TIFFIsTiled(in))
5927 tlsize = TIFFTileSize(in);
5928 ntiles = TIFFNumberOfTiles(in);
5929 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
5930 TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
5932 tile_rowsize = TIFFTileRowSize(in);
5933 buffsize = tlsize * ntiles;
5936 if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
5938 buffsize = ntiles * tl * tile_rowsize;
5940 TIFFError("loadImage",
5941 "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
5942 tlsize, (unsigned long)buffsize);
5946 if (dump->infile != NULL)
5947 dump_info (dump->infile, dump->format, "",
5948 "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
5949 tlsize, ntiles, tile_rowsize);
5954 TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
5955 stsize = TIFFStripSize(in);
5956 nstrips = TIFFNumberOfStrips(in);
5957 buffsize = stsize * nstrips;
5959 if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
5961 buffsize = ((length * width * spp * bps) + 7) / 8;
5963 TIFFError("loadImage",
5964 "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
5965 stsize, (unsigned long)buffsize);
5969 if (dump->infile != NULL)
5970 dump_info (dump->infile, dump->format, "",
5971 "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
5972 stsize, nstrips, rowsperstrip, scanlinesize);
5975 if (input_compression == COMPRESSION_JPEG)
5976 { /* Force conversion to RGB */
5977 jpegcolormode = JPEGCOLORMODE_RGB;
5978 TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
5980 /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
5982 { /* Otherwise, can't handle subsampled input */
5983 if (input_photometric == PHOTOMETRIC_YCBCR)
5985 TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
5986 &subsampling_horiz, &subsampling_vert);
5987 if (subsampling_horiz != 1 || subsampling_vert != 1)
5989 TIFFError("loadImage",
5990 "Can't copy/convert subsampled image with subsampling %d horiz %d vert",
5991 subsampling_horiz, subsampling_vert);
5997 read_buff = *read_ptr;
5999 read_buff = (unsigned char *)_TIFFmalloc(buffsize);
6002 if (prev_readsize < buffsize)
6004 new_buff = _TIFFrealloc(read_buff, buffsize);
6008 read_buff = (unsigned char *)_TIFFmalloc(buffsize);
6011 read_buff = new_buff;
6017 TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6021 prev_readsize = buffsize;
6022 *read_ptr = read_buff;
6024 /* N.B. The read functions used copy separate plane data into a buffer as interleaved
6025 * samples rather than separate planes so the same logic works to extract regions
6026 * regardless of the way the data are organized in the input file.
6030 if (planar == PLANARCONFIG_CONTIG)
6032 if (!(readContigStripsIntoBuffer(in, read_buff)))
6034 TIFFError("loadImage", "Unable to read contiguous strips into buffer");
6040 if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
6042 TIFFError("loadImage", "Unable to read separate strips into buffer");
6049 if (planar == PLANARCONFIG_CONTIG)
6051 if (!(readContigTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6053 TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
6059 if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
6061 TIFFError("loadImage", "Unable to read separate tiles into buffer");
6066 default: TIFFError("loadImage", "Unsupported image file format");
6070 if ((dump->infile != NULL) && (dump->level == 2))
6072 dump_info (dump->infile, dump->format, "loadImage",
6073 "Image width %d, length %d, Raw image data, %4d bytes",
6074 width, length, buffsize);
6075 dump_info (dump->infile, dump->format, "",
6076 "Bits per sample %d, Samples per pixel %d", bps, spp);
6078 for (i = 0; i < length; i++)
6079 dump_buffer(dump->infile, dump->format, 1, scanlinesize,
6080 i, read_buff + (i * scanlinesize));
6083 } /* end loadImage */
6085 static int correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
6087 uint16 mirror, rotation;
6088 unsigned char *work_buff;
6090 work_buff = *work_buff_ptr;
6091 if ((image == NULL) || (work_buff == NULL))
6093 TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
6097 if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
6099 mirror = (uint16)(image->adjustments & MIRROR_BOTH);
6100 if (mirrorImage(image->spp, image->bps, mirror,
6101 image->width, image->length, work_buff))
6103 TIFFError ("correct_orientation", "Unable to mirror image");
6108 if (image->adjustments & ROTATE_ANY)
6110 if (image->adjustments & ROTATECW_90)
6111 rotation = (uint16) 90;
6113 if (image->adjustments & ROTATECW_180)
6114 rotation = (uint16) 180;
6116 if (image->adjustments & ROTATECW_270)
6117 rotation = (uint16) 270;
6120 TIFFError ("correct_orientation", "Invalid rotation value: %d",
6121 image->adjustments & ROTATE_ANY);
6125 if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
6127 TIFFError ("correct_orientation", "Unable to rotate image");
6130 image->orientation = ORIENTATION_TOPLEFT;
6134 } /* end correct_orientation */
6137 /* Extract multiple zones from an image and combine into a single composite image */
6139 extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
6140 unsigned char *read_buff, unsigned char *crop_buff)
6142 int shift_width, bytes_per_sample, bytes_per_pixel;
6143 uint32 i, trailing_bits, prev_trailing_bits;
6144 uint32 row, first_row, last_row, first_col, last_col;
6145 uint32 src_rowsize, dst_rowsize, src_offset, dst_offset;
6146 uint32 crop_width, crop_length, img_width, img_length;
6147 uint32 prev_length, prev_width, composite_width;
6150 tsample_t count, sample = 0; /* Update to extract one or more samples */
6152 img_width = image->width;
6153 img_length = image->length;
6158 bytes_per_sample = (bps + 7) / 8;
6159 bytes_per_pixel = ((bps * spp) + 7) / 8;
6164 if (bytes_per_pixel < (bytes_per_sample + 1))
6165 shift_width = bytes_per_pixel;
6167 shift_width = bytes_per_sample + 1;
6172 /* These are setup for adding additional sections */
6173 prev_width = prev_length = 0;
6174 prev_trailing_bits = trailing_bits = 0;
6175 composite_width = crop->combined_width;
6176 crop->combined_width = 0;
6177 crop->combined_length = 0;
6179 for (i = 0; i < crop->selections; i++)
6181 /* rows, columns, width, length are expressed in pixels */
6182 first_row = crop->regionlist[i].y1;
6183 last_row = crop->regionlist[i].y2;
6184 first_col = crop->regionlist[i].x1;
6185 last_col = crop->regionlist[i].x2;
6187 crop_width = last_col - first_col + 1;
6188 crop_length = last_row - first_row + 1;
6190 /* These should not be needed for composite images */
6191 crop->regionlist[i].width = crop_width;
6192 crop->regionlist[i].length = crop_length;
6193 crop->regionlist[i].buffptr = crop_buff;
6195 src_rowsize = ((img_width * bps * spp) + 7) / 8;
6196 dst_rowsize = (((crop_width * bps * count) + 7) / 8);
6198 switch (crop->edge_ref)
6203 if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
6205 TIFFError ("extractCompositeRegions",
6206 "Only equal width regions can be combined for -E top or bottom");
6210 crop->combined_width = crop_width;
6211 crop->combined_length += crop_length;
6213 for (row = first_row; row <= last_row; row++)
6215 src_offset = row * src_rowsize;
6216 dst_offset = (row - first_row) * dst_rowsize;
6217 src = read_buff + src_offset;
6218 dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
6219 switch (shift_width)
6221 case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6222 spp, bps, count, first_col,
6225 TIFFError("extractCompositeRegions",
6226 "Unable to extract row %d", row);
6230 case 1: if (bps == 1)
6232 if (extractContigSamplesShifted8bits (src, dst, img_width,
6233 sample, spp, bps, count,
6234 first_col, last_col + 1,
6235 prev_trailing_bits))
6237 TIFFError("extractCompositeRegions",
6238 "Unable to extract row %d", row);
6244 if (extractContigSamplesShifted16bits (src, dst, img_width,
6245 sample, spp, bps, count,
6246 first_col, last_col + 1,
6247 prev_trailing_bits))
6249 TIFFError("extractCompositeRegions",
6250 "Unable to extract row %d", row);
6254 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6255 sample, spp, bps, count,
6256 first_col, last_col + 1,
6257 prev_trailing_bits))
6259 TIFFError("extractCompositeRegions",
6260 "Unable to extract row %d", row);
6266 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6267 sample, spp, bps, count,
6268 first_col, last_col + 1,
6269 prev_trailing_bits))
6271 TIFFError("extractCompositeRegions",
6272 "Unable to extract row %d", row);
6276 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6280 prev_length += crop_length;
6282 case EDGE_LEFT: /* splice the pieces of each row together, side by side */
6284 if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
6286 TIFFError ("extractCompositeRegions",
6287 "Only equal length regions can be combined for -E left or right");
6290 crop->combined_width += crop_width;
6291 crop->combined_length = crop_length;
6292 dst_rowsize = (((composite_width * bps * count) + 7) / 8);
6293 trailing_bits = (crop_width * bps * count) % 8;
6294 for (row = first_row; row <= last_row; row++)
6296 src_offset = row * src_rowsize;
6297 dst_offset = (row - first_row) * dst_rowsize;
6298 src = read_buff + src_offset;
6299 dst = crop_buff + dst_offset + prev_width;
6301 switch (shift_width)
6303 case 0: if (extractContigSamplesBytes (src, dst, img_width,
6304 sample, spp, bps, count,
6305 first_col, last_col + 1))
6307 TIFFError("extractCompositeRegions",
6308 "Unable to extract row %d", row);
6312 case 1: if (bps == 1)
6314 if (extractContigSamplesShifted8bits (src, dst, img_width,
6315 sample, spp, bps, count,
6316 first_col, last_col + 1,
6317 prev_trailing_bits))
6319 TIFFError("extractCompositeRegions",
6320 "Unable to extract row %d", row);
6326 if (extractContigSamplesShifted16bits (src, dst, img_width,
6327 sample, spp, bps, count,
6328 first_col, last_col + 1,
6329 prev_trailing_bits))
6331 TIFFError("extractCompositeRegions",
6332 "Unable to extract row %d", row);
6336 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6337 sample, spp, bps, count,
6338 first_col, last_col + 1,
6339 prev_trailing_bits))
6341 TIFFError("extractCompositeRegions",
6342 "Unable to extract row %d", row);
6348 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6349 sample, spp, bps, count,
6350 first_col, last_col + 1,
6351 prev_trailing_bits))
6353 TIFFError("extractCompositeRegions",
6354 "Unable to extract row %d", row);
6358 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
6362 prev_width += (crop_width * bps * count) / 8;
6363 prev_trailing_bits += trailing_bits;
6364 if (prev_trailing_bits > 7)
6365 prev_trailing_bits-= 8;
6369 if (crop->combined_width != composite_width)
6370 TIFFError("combineSeparateRegions","Combined width does not match composite width");
6373 } /* end extractCompositeRegions */
6375 /* Copy a single region of input buffer to an output buffer.
6376 * The read functions used copy separate plane data into a buffer
6377 * as interleaved samples rather than separate planes so the same
6378 * logic works to extract regions regardless of the way the data
6379 * are organized in the input file. This function can be used to
6380 * extract one or more samples from the input image by updating the
6381 * parameters for starting sample and number of samples to copy in the
6382 * fifth and eighth arguments of the call to extractContigSamples.
6383 * They would be passed as new elements of the crop_mask struct.
6387 extractSeparateRegion(struct image_data *image, struct crop_mask *crop,
6388 unsigned char *read_buff, unsigned char *crop_buff,
6391 int shift_width, prev_trailing_bits = 0;
6392 uint32 bytes_per_sample, bytes_per_pixel;
6393 uint32 src_rowsize, dst_rowsize;
6394 uint32 row, first_row, last_row, first_col, last_col;
6395 uint32 src_offset, dst_offset;
6396 uint32 crop_width, crop_length, img_width, img_length;
6399 tsample_t count, sample = 0; /* Update to extract more or more samples */
6401 img_width = image->width;
6402 img_length = image->length;
6407 bytes_per_sample = (bps + 7) / 8;
6408 bytes_per_pixel = ((bps * spp) + 7) / 8;
6410 shift_width = 0; /* Byte aligned data only */
6413 if (bytes_per_pixel < (bytes_per_sample + 1))
6414 shift_width = bytes_per_pixel;
6416 shift_width = bytes_per_sample + 1;
6419 /* rows, columns, width, length are expressed in pixels */
6420 first_row = crop->regionlist[region].y1;
6421 last_row = crop->regionlist[region].y2;
6422 first_col = crop->regionlist[region].x1;
6423 last_col = crop->regionlist[region].x2;
6425 crop_width = last_col - first_col + 1;
6426 crop_length = last_row - first_row + 1;
6428 crop->regionlist[region].width = crop_width;
6429 crop->regionlist[region].length = crop_length;
6430 crop->regionlist[region].buffptr = crop_buff;
6434 src_rowsize = ((img_width * bps * spp) + 7) / 8;
6435 dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
6437 for (row = first_row; row <= last_row; row++)
6439 src_offset = row * src_rowsize;
6440 dst_offset = (row - first_row) * dst_rowsize;
6441 src = read_buff + src_offset;
6442 dst = crop_buff + dst_offset;
6444 switch (shift_width)
6446 case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
6447 spp, bps, count, first_col,
6450 TIFFError("extractSeparateRegion",
6451 "Unable to extract row %d", row);
6455 case 1: if (bps == 1)
6457 if (extractContigSamplesShifted8bits (src, dst, img_width,
6458 sample, spp, bps, count,
6459 first_col, last_col + 1,
6460 prev_trailing_bits))
6462 TIFFError("extractSeparateRegion",
6463 "Unable to extract row %d", row);
6469 if (extractContigSamplesShifted16bits (src, dst, img_width,
6470 sample, spp, bps, count,
6471 first_col, last_col + 1,
6472 prev_trailing_bits))
6474 TIFFError("extractSeparateRegion",
6475 "Unable to extract row %d", row);
6479 case 2: if (extractContigSamplesShifted24bits (src, dst, img_width,
6480 sample, spp, bps, count,
6481 first_col, last_col + 1,
6482 prev_trailing_bits))
6484 TIFFError("extractSeparateRegion",
6485 "Unable to extract row %d", row);
6491 case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
6492 sample, spp, bps, count,
6493 first_col, last_col + 1,
6494 prev_trailing_bits))
6496 TIFFError("extractSeparateRegion",
6497 "Unable to extract row %d", row);
6501 default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
6507 } /* end extractSeparateRegion */
6510 extractImageSection(struct image_data *image, struct pageseg *section,
6511 unsigned char *src_buff, unsigned char *sect_buff)
6513 unsigned char bytebuff1, bytebuff2;
6514 unsigned char *src, *dst;
6516 uint32 img_width, img_length, img_rowsize;
6517 uint32 j, shift1, shift2, trailing_bits;
6518 uint32 row, first_row, last_row, first_col, last_col;
6519 uint32 src_offset, dst_offset, row_offset, col_offset;
6520 uint32 offset1, offset2, full_bytes;
6521 uint32 sect_width, sect_length;
6526 unsigned char bitset;
6527 static char *bitarray = NULL;
6530 img_width = image->width;
6531 img_length = image->length;
6541 if (bitarray == NULL)
6543 if ((bitarray = (char *)malloc(img_width)) == NULL)
6545 TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
6551 /* rows, columns, width, length are expressed in pixels */
6552 first_row = section->y1;
6553 last_row = section->y2;
6554 first_col = section->x1;
6555 last_col = section->x2;
6557 sect_width = last_col - first_col + 1;
6558 sect_length = last_row - first_row + 1;
6559 img_rowsize = ((img_width * bps + 7) / 8) * spp;
6560 full_bytes = (sect_width * spp * bps) / 8; /* number of COMPLETE bytes per row in section */
6561 trailing_bits = (sect_width * bps) % 8;
6564 TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
6565 first_row, last_row, first_col, last_col);
6566 TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
6567 img_width, img_length, bps, spp);
6568 TIFFError ("", "Sect width: %d, Sect length: %d, full bytes: %d trailing bits %d\n",
6569 sect_width, sect_length, full_bytes, trailing_bits);
6574 col_offset = first_col * spp * bps / 8;
6575 for (row = first_row; row <= last_row; row++)
6577 /* row_offset = row * img_width * spp * bps / 8; */
6578 row_offset = row * img_rowsize;
6579 src_offset = row_offset + col_offset;
6582 TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset, dst_offset);
6584 _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
6585 dst_offset += full_bytes;
6590 shift1 = spp * ((first_col * bps) % 8);
6591 shift2 = spp * ((last_col * bps) % 8);
6592 for (row = first_row; row <= last_row; row++)
6594 /* pull out the first byte */
6595 row_offset = row * img_rowsize;
6596 offset1 = row_offset + (first_col * bps / 8);
6597 offset2 = row_offset + (last_col * bps / 8);
6600 for (j = 0, k = 7; j < 8; j++, k--)
6602 bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
6603 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6605 sprintf(&bitarray[8], " ");
6606 sprintf(&bitarray[9], " ");
6607 for (j = 10, k = 7; j < 18; j++, k--)
6609 bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
6610 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6612 bitarray[18] = '\0';
6613 TIFFError ("", "Row: %3d Offset1: %d, Shift1: %d, Offset2: %d, Shift2: %d\n",
6614 row, offset1, shift1, offset2, shift2);
6617 bytebuff1 = bytebuff2 = 0;
6618 if (shift1 == 0) /* the region is byte and sample alligned */
6620 _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
6623 TIFFError ("", " Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset);
6624 sprintf(&bitarray[18], "\n");
6625 sprintf(&bitarray[19], "\t");
6626 for (j = 20, k = 7; j < 28; j++, k--)
6628 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6629 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6634 dst_offset += full_bytes;
6636 if (trailing_bits != 0)
6638 bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
6639 sect_buff[dst_offset] = bytebuff2;
6641 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n",
6642 offset2, dst_offset);
6643 for (j = 30, k = 7; j < 38; j++, k--)
6645 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6646 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6648 bitarray[38] = '\0';
6649 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6654 else /* each destination byte will have to be built from two source bytes*/
6657 TIFFError ("", " Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset);
6659 for (j = 0; j <= full_bytes; j++)
6661 bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
6662 bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
6663 sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
6666 sprintf(&bitarray[18], "\n");
6667 sprintf(&bitarray[19], "\t");
6668 for (j = 20, k = 7; j < 28; j++, k--)
6670 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6671 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6676 dst_offset += full_bytes;
6678 if (trailing_bits != 0)
6681 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset);
6683 if (shift2 > shift1)
6685 bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
6686 bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
6687 sect_buff[dst_offset] = bytebuff2;
6689 TIFFError ("", " Shift2 > Shift1\n");
6694 if (shift2 < shift1)
6696 bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
6697 sect_buff[dst_offset] &= bytebuff2;
6699 TIFFError ("", " Shift2 < Shift1\n");
6704 TIFFError ("", " Shift2 == Shift1\n");
6709 sprintf(&bitarray[28], " ");
6710 sprintf(&bitarray[29], " ");
6711 for (j = 30, k = 7; j < 38; j++, k--)
6713 bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
6714 sprintf(&bitarray[j], (bitset) ? "1" : "0");
6716 bitarray[38] = '\0';
6717 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
6725 } /* end extractImageSection */
6728 writeSelections(TIFF *in, TIFF **out, struct crop_mask *crop,
6729 struct image_data *image, struct dump_opts *dump,
6730 struct buffinfo seg_buffs[], char *mp, char *filename,
6731 unsigned int *page, unsigned int total_pages)
6735 unsigned char *crop_buff = NULL;
6737 /* Where we open a new file depends on the export mode */
6738 switch (crop->exp_mode)
6740 case ONE_FILE_COMPOSITE: /* Regions combined into single image */
6742 crop_buff = seg_buffs[0].buffer;
6743 if (update_output_file (out, mp, autoindex, filename, page))
6745 page_count = total_pages;
6746 if (writeCroppedImage(in, *out, image, dump,
6747 crop->combined_width,
6748 crop->combined_length,
6749 crop_buff, *page, total_pages))
6751 TIFFError("writeRegions", "Unable to write new image");
6755 case ONE_FILE_SEPARATED: /* Regions as separated images */
6757 if (update_output_file (out, mp, autoindex, filename, page))
6759 page_count = crop->selections * total_pages;
6760 for (i = 0; i < crop->selections; i++)
6762 crop_buff = seg_buffs[i].buffer;
6763 if (writeCroppedImage(in, *out, image, dump,
6764 crop->regionlist[i].width,
6765 crop->regionlist[i].length,
6766 crop_buff, *page, page_count))
6768 TIFFError("writeRegions", "Unable to write new image");
6773 case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
6775 if (update_output_file (out, mp, autoindex, filename, page))
6778 crop_buff = seg_buffs[0].buffer;
6779 if (writeCroppedImage(in, *out, image, dump,
6780 crop->combined_width,
6781 crop->combined_length,
6782 crop_buff, *page, total_pages))
6784 TIFFError("writeRegions", "Unable to write new image");
6788 case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
6790 page_count = crop->selections;
6791 if (update_output_file (out, mp, autoindex, filename, page))
6794 for (i = 0; i < crop->selections; i++)
6796 crop_buff = seg_buffs[i].buffer;
6797 /* Write the current region to the current file */
6798 if (writeCroppedImage(in, *out, image, dump,
6799 crop->regionlist[i].width,
6800 crop->regionlist[i].length,
6801 crop_buff, *page, page_count))
6803 TIFFError("writeRegions", "Unable to write new image");
6808 case FILE_PER_SELECTION:
6811 for (i = 0; i < crop->selections; i++)
6813 if (update_output_file (out, mp, autoindex, filename, page))
6816 crop_buff = seg_buffs[i].buffer;
6817 /* Write the current region to the current file */
6818 if (writeCroppedImage(in, *out, image, dump,
6819 crop->regionlist[i].width,
6820 crop->regionlist[i].length,
6821 crop_buff, *page, page_count))
6823 TIFFError("writeRegions", "Unable to write new image");
6828 default: return (1);
6832 } /* end writeRegions */
6835 writeImageSections(TIFF *in, TIFF *out, struct image_data *image,
6836 struct pagedef *page, struct pageseg *sections,
6837 struct dump_opts * dump, unsigned char *src_buff,
6838 unsigned char **sect_buff_ptr)
6841 uint32 i, k, width, length, sectsize;
6842 unsigned char *sect_buff = *sect_buff_ptr;
6847 k = page->cols * page->rows;
6848 if ((k < 1) || (k > MAX_SECTIONS))
6850 TIFFError("writeImageSections",
6851 "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
6855 for (i = 0; i < k; i++)
6857 width = sections[i].x2 - sections[i].x1 + 1;
6858 length = sections[i].y2 - sections[i].y1 + 1;
6860 ceil((width * image->bps + 7) / (double)8) * image->spp * length;
6861 /* allocate a buffer if we don't have one already */
6862 if (createImageSection(sectsize, sect_buff_ptr))
6864 TIFFError("writeImageSections", "Unable to allocate section buffer");
6867 sect_buff = *sect_buff_ptr;
6869 if (extractImageSection (image, §ions[i], src_buff, sect_buff))
6871 TIFFError("writeImageSections", "Unable to extract image sections");
6875 /* call the write routine here instead of outside the loop */
6876 if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
6878 TIFFError("writeImageSections", "Unable to write image section");
6884 } /* end writeImageSections */
6886 /* Code in this function is heavily indebted to code in tiffcp
6887 * with modifications by Richard Nolde to handle orientation correctly.
6888 * It will have to be updated significantly if support is added to
6889 * extract one or more samples from original image since the
6890 * original code assumes we are always copying all samples.
6893 writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
6894 struct dump_opts *dump, uint32 width, uint32 length,
6895 double hres, double vres,
6896 unsigned char *sect_buff)
6899 uint16 input_compression, input_photometric;
6900 uint16 input_planar;
6903 /* Calling this seems to reset the compression mode on the TIFF *in file.
6904 TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
6906 input_compression = image->compression;
6907 input_photometric = image->photometric;
6911 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
6912 TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
6913 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
6914 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
6917 TIFFError("writeSingleSection", "Input compression: %s",
6918 (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
6919 ((input_compression == COMPRESSION_JPEG) ? "New Jpeg" : "Non Jpeg"));
6921 /* This is the global variable compression which is set
6922 * if the user has specified a command line option for
6923 * a compression option. Should be passed around in one
6924 * of the parameters instead of as a global. If no user
6925 * option specified it will still be (uint16) -1. */
6926 if (compression != (uint16)-1)
6927 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
6929 { /* OJPEG is no longer supported for writing so upgrade to JPEG */
6930 if (input_compression == COMPRESSION_OJPEG)
6932 compression = COMPRESSION_JPEG;
6933 jpegcolormode = JPEGCOLORMODE_RAW;
6934 TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
6936 else /* Use the compression from the input file */
6937 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
6940 if (compression == COMPRESSION_JPEG)
6942 if ((input_photometric == PHOTOMETRIC_PALETTE) || /* color map indexed */
6943 (input_photometric == PHOTOMETRIC_MASK)) /* holdout mask */
6945 TIFFError ("writeSingleSection",
6946 "JPEG compression cannot be used with %s image data",
6947 (input_photometric == PHOTOMETRIC_PALETTE) ?
6948 "palette" : "mask");
6951 if ((input_photometric == PHOTOMETRIC_RGB) &&
6952 (jpegcolormode == JPEGCOLORMODE_RGB))
6953 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
6955 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
6959 if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
6960 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
6961 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
6963 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
6967 TIFFError("writeSingleSection", "Input photometric: %s",
6968 (input_photometric == PHOTOMETRIC_RGB) ? "RGB" :
6969 ((input_photometric == PHOTOMETRIC_YCBCR) ? "YCbCr" : "Not RGB or YCbCr"));
6972 if (((input_photometric == PHOTOMETRIC_LOGL) ||
6973 (input_photometric == PHOTOMETRIC_LOGLUV)) &&
6974 ((compression != COMPRESSION_SGILOG) &&
6975 (compression != COMPRESSION_SGILOG24)))
6977 TIFFError("writeSingleSection",
6978 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
6983 TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
6985 CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
6987 /* The loadimage function reads input orientation and sets
6988 * image->orientation. The correct_image_orientation function
6989 * applies the required rotation and mirror operations to
6990 * present the data in TOPLEFT orientation and updates
6991 * image->orientation if any transforms are performed,
6992 * as per EXIF standard.
6994 TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
6997 * Choose tiles/strip for the output image according to
6998 * the command line arguments (-tiles, -strips) and the
6999 * structure of the input image.
7002 outtiled = TIFFIsTiled(in);
7005 * Setup output file's tile width&height. If either
7006 * is not specified, use either the value from the
7007 * input image or, if nothing is defined, use the
7010 if (tilewidth == (uint32) 0)
7011 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7012 if (tilelength == (uint32) 0)
7013 TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7015 if (tilewidth == 0 || tilelength == 0)
7016 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7017 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7018 TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7019 TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7022 * RowsPerStrip is left unspecified: use either the
7023 * value from the input image or, if nothing is defined,
7024 * use the library default.
7026 if (rowsperstrip == (uint32) 0)
7028 if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7029 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7030 if (compression != COMPRESSION_JPEG)
7032 if (rowsperstrip > length)
7033 rowsperstrip = length;
7037 if (rowsperstrip == (uint32) -1)
7038 rowsperstrip = length;
7039 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7042 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7043 if (config != (uint16) -1)
7044 TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7046 CopyField(TIFFTAG_PLANARCONFIG, config);
7048 CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7049 CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7051 /* SMinSampleValue & SMaxSampleValue */
7052 switch (compression) {
7053 /* These are references to GLOBAL variables set by defaults
7054 * and /or the compression flag
7056 case COMPRESSION_JPEG:
7057 if (((bps % 8) == 0) || ((bps % 12) == 0))
7059 TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7060 TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7064 TIFFError("writeSingleSection",
7065 "JPEG compression requires 8 or 12 bits per sample");
7069 case COMPRESSION_LZW:
7070 case COMPRESSION_ADOBE_DEFLATE:
7071 case COMPRESSION_DEFLATE:
7072 if (predictor != (uint16)-1)
7073 TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7075 CopyField(TIFFTAG_PREDICTOR, predictor);
7077 case COMPRESSION_CCITTFAX3:
7078 case COMPRESSION_CCITTFAX4:
7079 if (compression == COMPRESSION_CCITTFAX3) {
7080 if (g3opts != (uint32) -1)
7081 TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7083 CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7085 CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7086 CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7087 CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7088 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7089 CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7090 CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7091 CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7096 if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7097 TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7100 const char* inknames;
7101 if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7102 TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7103 if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7104 int inknameslen = strlen(inknames) + 1;
7105 const char* cp = inknames;
7107 cp = strchr(cp, '\0');
7110 inknameslen += (strlen(cp) + 1);
7114 TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7119 unsigned short pg0, pg1;
7120 if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7121 if (pageNum < 0) /* only one input file */
7122 TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
7124 TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
7128 for (p = tags; p < &tags[NTAGS]; p++)
7129 CopyTag(p->tag, p->count, p->type);
7131 /* Update these since they are overwritten from input res by loop above */
7132 TIFFSetField(out, TIFFTAG_XRESOLUTION, (float)hres);
7133 TIFFSetField(out, TIFFTAG_YRESOLUTION, (float)vres);
7135 /* Compute the tile or strip dimensions and write to disk */
7138 if (config == PLANARCONFIG_CONTIG)
7139 writeBufferToContigTiles (out, sect_buff, length, width, spp, dump);
7141 writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
7145 if (config == PLANARCONFIG_CONTIG)
7146 writeBufferToContigStrips (out, sect_buff, length);
7148 writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
7151 if (!TIFFWriteDirectory(out))
7158 } /* end writeSingleSection */
7161 /* Create a buffer to write one section at a time */
7163 createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
7165 unsigned char *sect_buff = NULL;
7166 unsigned char *new_buff = NULL;
7167 static uint32 prev_sectsize = 0;
7169 sect_buff = *sect_buff_ptr;
7173 sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7174 *sect_buff_ptr = sect_buff;
7175 _TIFFmemset(sect_buff, 0, sectsize);
7179 if (prev_sectsize < sectsize)
7181 new_buff = _TIFFrealloc(sect_buff, sectsize);
7185 sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
7188 sect_buff = new_buff;
7190 _TIFFmemset(sect_buff, 0, sectsize);
7196 TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
7199 prev_sectsize = sectsize;
7200 *sect_buff_ptr = sect_buff;
7203 } /* end createImageSection */
7206 /* Process selections defined by regions, zones, margins, or fixed sized areas */
7208 processCropSelections(struct image_data *image, struct crop_mask *crop,
7209 unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
7212 uint32 width, length, total_width, total_length;
7214 unsigned char *crop_buff = NULL;
7215 unsigned char *read_buff = NULL;
7216 unsigned char *next_buff = NULL;
7217 tsize_t prev_cropsize = 0;
7219 read_buff = *read_buff_ptr;
7221 if (crop->img_mode == COMPOSITE_IMAGES)
7223 cropsize = crop->bufftotal;
7224 crop_buff = seg_buffs[0].buffer;
7226 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7229 prev_cropsize = seg_buffs[0].size;
7230 if (prev_cropsize < cropsize)
7232 next_buff = _TIFFrealloc(crop_buff, cropsize);
7235 _TIFFfree (crop_buff);
7236 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7239 crop_buff = next_buff;
7245 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7249 _TIFFmemset(crop_buff, 0, cropsize);
7250 seg_buffs[0].buffer = crop_buff;
7251 seg_buffs[0].size = cropsize;
7253 /* Checks for matching width or length as required */
7254 if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
7257 if (crop->crop_mode & CROP_INVERT)
7259 switch (crop->photometric)
7261 /* Just change the interpretation */
7262 case PHOTOMETRIC_MINISWHITE:
7263 case PHOTOMETRIC_MINISBLACK:
7264 image->photometric = crop->photometric;
7266 case INVERT_DATA_ONLY:
7267 case INVERT_DATA_AND_TAG:
7268 if (invertImage(image->photometric, image->spp, image->bps,
7269 crop->combined_width, crop->combined_length, crop_buff))
7271 TIFFError("processCropSelections",
7272 "Failed to invert colorspace for composite regions");
7275 if (crop->photometric == INVERT_DATA_AND_TAG)
7277 switch (image->photometric)
7279 case PHOTOMETRIC_MINISWHITE:
7280 image->photometric = PHOTOMETRIC_MINISBLACK;
7282 case PHOTOMETRIC_MINISBLACK:
7283 image->photometric = PHOTOMETRIC_MINISWHITE;
7294 /* Mirror and Rotate will not work with multiple regions unless they are the same width */
7295 if (crop->crop_mode & CROP_MIRROR)
7297 if (mirrorImage(image->spp, image->bps, crop->mirror,
7298 crop->combined_width, crop->combined_length, crop_buff))
7300 TIFFError("processCropSelections", "Failed to mirror composite regions %s",
7301 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7306 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7308 if (rotateImage(crop->rotation, image, &crop->combined_width,
7309 &crop->combined_length, &crop_buff))
7311 TIFFError("processCropSelections",
7312 "Failed to rotate composite regions by %d degrees", crop->rotation);
7315 seg_buffs[0].buffer = crop_buff;
7316 seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
7317 * image->spp) * crop->combined_length;
7320 else /* Separated Images */
7322 total_width = total_length = 0;
7323 for (i = 0; i < crop->selections; i++)
7325 cropsize = crop->bufftotal;
7326 crop_buff = seg_buffs[i].buffer;
7328 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7331 prev_cropsize = seg_buffs[0].size;
7332 if (prev_cropsize < cropsize)
7334 next_buff = _TIFFrealloc(crop_buff, cropsize);
7337 _TIFFfree (crop_buff);
7338 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7341 crop_buff = next_buff;
7347 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7351 _TIFFmemset(crop_buff, 0, cropsize);
7352 seg_buffs[i].buffer = crop_buff;
7353 seg_buffs[i].size = cropsize;
7355 if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
7357 TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
7361 width = crop->regionlist[i].width;
7362 length = crop->regionlist[i].length;
7364 if (crop->crop_mode & CROP_INVERT)
7366 switch (crop->photometric)
7368 /* Just change the interpretation */
7369 case PHOTOMETRIC_MINISWHITE:
7370 case PHOTOMETRIC_MINISBLACK:
7371 image->photometric = crop->photometric;
7373 case INVERT_DATA_ONLY:
7374 case INVERT_DATA_AND_TAG:
7375 if (invertImage(image->photometric, image->spp, image->bps,
7376 width, length, crop_buff))
7378 TIFFError("processCropSelections",
7379 "Failed to invert colorspace for region");
7382 if (crop->photometric == INVERT_DATA_AND_TAG)
7384 switch (image->photometric)
7386 case PHOTOMETRIC_MINISWHITE:
7387 image->photometric = PHOTOMETRIC_MINISBLACK;
7389 case PHOTOMETRIC_MINISBLACK:
7390 image->photometric = PHOTOMETRIC_MINISWHITE;
7401 if (crop->crop_mode & CROP_MIRROR)
7403 if (mirrorImage(image->spp, image->bps, crop->mirror,
7404 width, length, crop_buff))
7406 TIFFError("processCropSelections", "Failed to mirror crop region %s",
7407 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7412 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7414 if (rotateImage(crop->rotation, image, &crop->regionlist[i].width,
7415 &crop->regionlist[i].length, &crop_buff))
7417 TIFFError("processCropSelections",
7418 "Failed to rotate crop region by %d degrees", crop->rotation);
7421 total_width += crop->regionlist[i].width;
7422 total_length += crop->regionlist[i].length;
7423 crop->combined_width = total_width;
7424 crop->combined_length = total_length;
7425 seg_buffs[i].buffer = crop_buff;
7426 seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
7427 * image->spp) * crop->regionlist[i].length;
7432 } /* end processCropSelections */
7434 /* Copy the crop section of the data from the current image into a buffer
7435 * and adjust the IFD values to reflect the new size. If no cropping is
7436 * required, use the origial read buffer as the crop buffer.
7438 * There is quite a bit of redundancy between this routine and the more
7439 * specialized processCropSelections, but this provides
7440 * the most optimized path when no Zones or Regions are required.
7443 createCroppedImage(struct image_data *image, struct crop_mask *crop,
7444 unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
7447 unsigned char *read_buff = NULL;
7448 unsigned char *crop_buff = NULL;
7449 unsigned char *new_buff = NULL;
7450 static tsize_t prev_cropsize = 0;
7452 read_buff = *read_buff_ptr;
7454 /* process full image, no crop buffer needed */
7455 crop_buff = read_buff;
7456 *crop_buff_ptr = read_buff;
7457 crop->combined_width = image->width;
7458 crop->combined_length = image->length;
7460 cropsize = crop->bufftotal;
7461 crop_buff = *crop_buff_ptr;
7464 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7465 *crop_buff_ptr = crop_buff;
7466 _TIFFmemset(crop_buff, 0, cropsize);
7467 prev_cropsize = cropsize;
7471 if (prev_cropsize < cropsize)
7473 new_buff = _TIFFrealloc(crop_buff, cropsize);
7477 crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
7480 crop_buff = new_buff;
7481 _TIFFmemset(crop_buff, 0, cropsize);
7487 TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
7490 *crop_buff_ptr = crop_buff;
7492 if (crop->crop_mode & CROP_INVERT)
7494 switch (crop->photometric)
7496 /* Just change the interpretation */
7497 case PHOTOMETRIC_MINISWHITE:
7498 case PHOTOMETRIC_MINISBLACK:
7499 image->photometric = crop->photometric;
7501 case INVERT_DATA_ONLY:
7502 case INVERT_DATA_AND_TAG:
7503 if (invertImage(image->photometric, image->spp, image->bps,
7504 crop->combined_width, crop->combined_length, crop_buff))
7506 TIFFError("createCroppedImage",
7507 "Failed to invert colorspace for image or cropped selection");
7510 if (crop->photometric == INVERT_DATA_AND_TAG)
7512 switch (image->photometric)
7514 case PHOTOMETRIC_MINISWHITE:
7515 image->photometric = PHOTOMETRIC_MINISBLACK;
7517 case PHOTOMETRIC_MINISBLACK:
7518 image->photometric = PHOTOMETRIC_MINISWHITE;
7529 if (crop->crop_mode & CROP_MIRROR)
7531 if (mirrorImage(image->spp, image->bps, crop->mirror,
7532 crop->combined_width, crop->combined_length, crop_buff))
7534 TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s",
7535 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
7540 if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
7542 if (rotateImage(crop->rotation, image, &crop->combined_width,
7543 &crop->combined_length, crop_buff_ptr))
7545 TIFFError("createCroppedImage",
7546 "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
7551 if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
7552 *read_buff_ptr = NULL; /* so we don't try to free it later */
7555 } /* end createCroppedImage */
7558 /* Code in this function is heavily indebted to code in tiffcp
7559 * with modifications by Richard Nolde to handle orientation correctly.
7560 * It will have to be updated significantly if support is added to
7561 * extract one or more samples from original image since the
7562 * original code assumes we are always copying all samples.
7563 * Use of global variables for config, compression and others
7564 * should be replaced by addition to the crop_mask struct (which
7565 * will be renamed to proc_opts indicating that is controlls
7566 * user supplied processing options, not just cropping) and
7567 * then passed in as an argument.
7570 writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image,
7571 struct dump_opts *dump, uint32 width, uint32 length,
7572 unsigned char *crop_buff, int pagenum, int total_pages)
7575 uint16 input_compression, input_photometric;
7576 uint16 input_planar;
7579 input_compression = image->compression;
7580 input_photometric = image->photometric;
7584 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
7585 TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
7586 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
7587 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
7590 TIFFError("writeCroppedImage", "Input compression: %s",
7591 (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
7592 ((input_compression == COMPRESSION_JPEG) ? "New Jpeg" : "Non Jpeg"));
7595 if (compression != (uint16)-1)
7596 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
7599 if (input_compression == COMPRESSION_OJPEG)
7601 compression = COMPRESSION_JPEG;
7602 jpegcolormode = JPEGCOLORMODE_RAW;
7603 TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
7606 CopyField(TIFFTAG_COMPRESSION, compression);
7609 if (compression == COMPRESSION_JPEG)
7611 if ((input_photometric == PHOTOMETRIC_PALETTE) || /* color map indexed */
7612 (input_photometric == PHOTOMETRIC_MASK)) /* $holdout mask */
7614 TIFFError ("writeCroppedImage",
7615 "JPEG compression cannot be used with %s image data",
7616 (input_photometric == PHOTOMETRIC_PALETTE) ?
7617 "palette" : "mask");
7620 if ((input_photometric == PHOTOMETRIC_RGB) &&
7621 (jpegcolormode == JPEGCOLORMODE_RGB))
7622 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
7624 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
7628 if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
7630 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7631 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7635 if (input_compression == COMPRESSION_SGILOG ||
7636 input_compression == COMPRESSION_SGILOG24)
7638 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
7639 PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
7642 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
7646 if (((input_photometric == PHOTOMETRIC_LOGL) ||
7647 (input_photometric == PHOTOMETRIC_LOGLUV)) &&
7648 ((compression != COMPRESSION_SGILOG) &&
7649 (compression != COMPRESSION_SGILOG24)))
7651 TIFFError("writeCroppedImage",
7652 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
7657 TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
7659 CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
7661 /* The loadimage function reads input orientation and sets
7662 * image->orientation. The correct_image_orientation function
7663 * applies the required rotation and mirror operations to
7664 * present the data in TOPLEFT orientation and updates
7665 * image->orientation if any transforms are performed,
7666 * as per EXIF standard.
7668 TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
7671 * Choose tiles/strip for the output image according to
7672 * the command line arguments (-tiles, -strips) and the
7673 * structure of the input image.
7676 outtiled = TIFFIsTiled(in);
7679 * Setup output file's tile width&height. If either
7680 * is not specified, use either the value from the
7681 * input image or, if nothing is defined, use the
7684 if (tilewidth == (uint32) 0)
7685 TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
7686 if (tilelength == (uint32) 0)
7687 TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
7689 if (tilewidth == 0 || tilelength == 0)
7690 TIFFDefaultTileSize(out, &tilewidth, &tilelength);
7691 TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
7692 TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
7695 * RowsPerStrip is left unspecified: use either the
7696 * value from the input image or, if nothing is defined,
7697 * use the library default.
7699 if (rowsperstrip == (uint32) 0)
7701 if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
7702 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
7703 if (compression != COMPRESSION_JPEG)
7705 if (rowsperstrip > length)
7706 rowsperstrip = length;
7710 if (rowsperstrip == (uint32) -1)
7711 rowsperstrip = length;
7712 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7715 TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
7716 if (config != (uint16) -1)
7717 TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
7719 CopyField(TIFFTAG_PLANARCONFIG, config);
7721 CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
7722 CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
7724 /* SMinSampleValue & SMaxSampleValue */
7725 switch (compression) {
7726 case COMPRESSION_JPEG:
7727 if (((bps % 8) == 0) || ((bps % 12) == 0))
7729 TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
7730 TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
7734 TIFFError("writeCroppedImage",
7735 "JPEG compression requires 8 or 12 bits per sample");
7739 case COMPRESSION_LZW:
7740 case COMPRESSION_ADOBE_DEFLATE:
7741 case COMPRESSION_DEFLATE:
7742 if (predictor != (uint16)-1)
7743 TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
7745 CopyField(TIFFTAG_PREDICTOR, predictor);
7747 case COMPRESSION_CCITTFAX3:
7748 case COMPRESSION_CCITTFAX4:
7751 TIFFError("writeCroppedImage",
7752 "Group 3/4 compression is not usable with bps > 1");
7755 if (compression == COMPRESSION_CCITTFAX3) {
7756 if (g3opts != (uint32) -1)
7757 TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
7759 CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
7761 CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
7762 CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
7763 CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
7764 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
7765 CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
7766 CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
7767 CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
7769 case COMPRESSION_NONE:
7775 if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
7776 TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
7779 const char* inknames;
7780 if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
7781 TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
7782 if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
7783 int inknameslen = strlen(inknames) + 1;
7784 const char* cp = inknames;
7786 cp = strchr(cp, '\0');
7789 inknameslen += (strlen(cp) + 1);
7793 TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
7798 unsigned short pg0, pg1;
7799 if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
7800 TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
7804 for (p = tags; p < &tags[NTAGS]; p++)
7805 CopyTag(p->tag, p->count, p->type);
7807 /* Compute the tile or strip dimensions and write to disk */
7810 if (config == PLANARCONFIG_CONTIG)
7812 if (writeBufferToContigTiles (out, crop_buff, length, width, spp, dump))
7813 TIFFError("","Unable to write contiguous tile data for page %d", pagenum);
7817 if (writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump))
7818 TIFFError("","Unable to write separate tile data for page %d", pagenum);
7823 if (config == PLANARCONFIG_CONTIG)
7825 if (writeBufferToContigStrips (out, crop_buff, length))
7826 TIFFError("","Unable to write contiguous strip data for page %d", pagenum);
7830 if (writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump))
7831 TIFFError("","Unable to write separate strip data for page %d", pagenum);
7835 if (!TIFFWriteDirectory(out))
7837 TIFFError("","Failed to write IFD for page number %d", pagenum);
7843 } /* end writeCroppedImage */
7846 rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
7847 uint32 length, uint32 col, uint8 *src, uint8 *dst)
7850 uint32 src_byte = 0, src_bit = 0;
7851 uint32 row, rowsize = 0, bit_offset = 0;
7852 uint8 matchbits = 0, maskbits = 0;
7853 uint8 buff1 = 0, buff2 = 0;
7857 if ((src == NULL) || (dst == NULL))
7859 TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
7863 rowsize = ((bps * spp * width) + 7) / 8;
7865 maskbits = (uint8)-1 >> ( 8 - bps);
7868 for (row = 0; row < length ; row++)
7870 bit_offset = col * bps * spp;
7871 for (sample = 0; sample < spp; sample++)
7875 src_byte = bit_offset / 8;
7876 src_bit = bit_offset % 8;
7880 src_byte = (bit_offset + (sample * bps)) / 8;
7881 src_bit = (bit_offset + (sample * bps)) % 8;
7886 case 90: next = src + src_byte - (row * rowsize);
7888 case 270: next = src + src_byte + (row * rowsize);
7890 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
7893 matchbits = maskbits << (8 - src_bit - bps);
7894 buff1 = ((*next) & matchbits) << (src_bit);
7896 /* If we have a full buffer's worth, write it out */
7897 if (ready_bits >= 8)
7905 buff2 = (buff2 | (buff1 >> ready_bits));
7913 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
7918 } /* end rotateContigSamples8bits */
7922 rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
7923 uint32 length, uint32 col, uint8 *src, uint8 *dst)
7926 uint32 row, rowsize, bit_offset;
7927 uint32 src_byte = 0, src_bit = 0;
7928 uint16 matchbits = 0, maskbits = 0;
7929 uint16 buff1 = 0, buff2 = 0;
7934 if ((src == NULL) || (dst == NULL))
7936 TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
7940 rowsize = ((bps * spp * width) + 7) / 8;
7942 maskbits = (uint16)-1 >> (16 - bps);
7944 for (row = 0; row < length; row++)
7946 bit_offset = col * bps * spp;
7947 for (sample = 0; sample < spp; sample++)
7951 src_byte = bit_offset / 8;
7952 src_bit = bit_offset % 8;
7956 src_byte = (bit_offset + (sample * bps)) / 8;
7957 src_bit = (bit_offset + (sample * bps)) % 8;
7962 case 90: next = src + src_byte - (row * rowsize);
7964 case 270: next = src + src_byte + (row * rowsize);
7966 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
7969 matchbits = maskbits << (16 - src_bit - bps);
7971 buff1 = (next[0] << 8) | next[1];
7973 buff1 = (next[1] << 8) | next[0];
7975 buff1 = (buff1 & matchbits) << (src_bit);
7977 /* If we have a full buffer's worth, write it out */
7978 if (ready_bits >= 8)
7980 bytebuff = (buff2 >> 8);
7983 /* shift in new bits */
7984 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
7987 { /* add another bps bits to the buffer */
7989 buff2 = (buff2 | (buff1 >> ready_bits));
7997 bytebuff = (buff2 >> 8);
8002 } /* end rotateContigSamples16bits */
8005 rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8006 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8009 uint32 row, rowsize, bit_offset;
8010 uint32 src_byte = 0, src_bit = 0;
8011 uint32 matchbits = 0, maskbits = 0;
8012 uint32 buff1 = 0, buff2 = 0;
8013 uint8 bytebuff1 = 0, bytebuff2 = 0;
8018 if ((src == NULL) || (dst == NULL))
8020 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8024 rowsize = ((bps * spp * width) + 7) / 8;
8026 maskbits = (uint32)-1 >> (32 - bps);
8028 for (row = 0; row < length; row++)
8030 bit_offset = col * bps * spp;
8031 for (sample = 0; sample < spp; sample++)
8035 src_byte = bit_offset / 8;
8036 src_bit = bit_offset % 8;
8040 src_byte = (bit_offset + (sample * bps)) / 8;
8041 src_bit = (bit_offset + (sample * bps)) % 8;
8046 case 90: next = src + src_byte - (row * rowsize);
8048 case 270: next = src + src_byte + (row * rowsize);
8050 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8053 matchbits = maskbits << (32 - src_bit - bps);
8055 buff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8057 buff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8058 buff1 = (buff1 & matchbits) << (src_bit);
8060 /* If we have a full buffer's worth, write it out */
8061 if (ready_bits >= 16)
8063 bytebuff1 = (buff2 >> 24);
8065 bytebuff2 = (buff2 >> 16);
8069 /* shift in new bits */
8070 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8073 { /* add another bps bits to the buffer */
8074 bytebuff1 = bytebuff2 = 0;
8075 buff2 = (buff2 | (buff1 >> ready_bits));
8081 /* catch any trailing bits at the end of the line */
8082 while (ready_bits > 0)
8084 bytebuff1 = (buff2 >> 24);
8087 buff2 = (buff2 << 8);
8088 bytebuff2 = bytebuff1;
8093 } /* end rotateContigSamples24bits */
8096 rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
8097 uint32 length, uint32 col, uint8 *src, uint8 *dst)
8099 int ready_bits = 0, shift_width = 0;
8100 int bytes_per_sample, bytes_per_pixel;
8101 uint32 row, rowsize, bit_offset;
8102 uint32 src_byte, src_bit;
8103 uint32 longbuff1 = 0, longbuff2 = 0;
8104 uint64 maskbits = 0, matchbits = 0;
8105 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8106 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8111 if ((src == NULL) || (dst == NULL))
8113 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8117 bytes_per_sample = (bps + 7) / 8;
8118 bytes_per_pixel = ((bps * spp) + 7) / 8;
8119 if (bytes_per_pixel < (bytes_per_sample + 1))
8120 shift_width = bytes_per_pixel;
8122 shift_width = bytes_per_sample + 1;
8124 rowsize = ((bps * spp * width) + 7) / 8;
8126 maskbits = (uint64)-1 >> (64 - bps);
8128 for (row = 0; row < length; row++)
8130 bit_offset = col * bps * spp;
8131 for (sample = 0; sample < spp; sample++)
8135 src_byte = bit_offset / 8;
8136 src_bit = bit_offset % 8;
8140 src_byte = (bit_offset + (sample * bps)) / 8;
8141 src_bit = (bit_offset + (sample * bps)) % 8;
8146 case 90: next = src + src_byte - (row * rowsize);
8148 case 270: next = src + src_byte + (row * rowsize);
8150 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
8153 matchbits = maskbits << (64 - src_bit - bps);
8156 longbuff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
8157 longbuff2 = longbuff1;
8161 longbuff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
8162 longbuff2 = longbuff1;
8165 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8166 buff1 = (buff3 & matchbits) << (src_bit);
8168 if (ready_bits < 32)
8169 { /* add another bps bits to the buffer */
8170 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8171 buff2 = (buff2 | (buff1 >> ready_bits));
8173 else /* If we have a full buffer's worth, write it out */
8175 bytebuff1 = (buff2 >> 56);
8177 bytebuff2 = (buff2 >> 48);
8179 bytebuff3 = (buff2 >> 40);
8181 bytebuff4 = (buff2 >> 32);
8185 /* shift in new bits */
8186 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8191 while (ready_bits > 0)
8193 bytebuff1 = (buff2 >> 56);
8195 buff2 = (buff2 << 8);
8200 } /* end rotateContigSamples32bits */
8203 /* Rotate an image by a multiple of 90 degrees clockwise */
8205 rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
8206 uint32 *img_length, unsigned char **ibuff_ptr)
8209 uint32 bytes_per_pixel, bytes_per_sample;
8210 uint32 row, rowsize, src_offset, dst_offset;
8211 uint32 i, col, width, length;
8212 uint32 colsize, buffsize, col_offset, pix_offset;
8213 unsigned char *ibuff;
8218 unsigned char *rbuff = NULL;
8221 length = *img_length;
8225 rowsize = ((bps * spp * width) + 7) / 8;
8226 colsize = ((bps * spp * length) + 7) / 8;
8227 if ((colsize * width) > (rowsize * length))
8228 buffsize = (colsize + 1) * width;
8230 buffsize = (rowsize + 1) * length;
8232 bytes_per_sample = (bps + 7) / 8;
8233 bytes_per_pixel = ((bps * spp) + 7) / 8;
8234 if (bytes_per_pixel < (bytes_per_sample + 1))
8235 shift_width = bytes_per_pixel;
8237 shift_width = bytes_per_sample + 1;
8242 case 360: return (0);
8246 default: TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
8250 if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
8252 TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
8255 _TIFFmemset(rbuff, '\0', buffsize);
8260 case 180: if ((bps % 8) == 0) /* byte alligned data */
8263 pix_offset = (spp * bps) / 8;
8264 for (row = 0; row < length; row++)
8266 dst_offset = (length - row - 1) * rowsize;
8267 for (col = 0; col < width; col++)
8269 col_offset = (width - col - 1) * pix_offset;
8270 dst = rbuff + dst_offset + col_offset;
8272 for (i = 0; i < bytes_per_pixel; i++)
8278 { /* non 8 bit per sample data */
8279 for (row = 0; row < length; row++)
8281 src_offset = row * rowsize;
8282 dst_offset = (length - row - 1) * rowsize;
8283 src = ibuff + src_offset;
8284 dst = rbuff + dst_offset;
8285 switch (shift_width)
8287 case 1: if (bps == 1)
8289 if (reverseSamples8bits(spp, bps, width, src, dst))
8296 if (reverseSamples16bits(spp, bps, width, src, dst))
8302 case 2: if (reverseSamples24bits(spp, bps, width, src, dst))
8310 case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
8316 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8323 *(ibuff_ptr) = rbuff;
8326 case 90: if ((bps % 8) == 0) /* byte aligned data */
8328 for (col = 0; col < width; col++)
8330 src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
8331 dst_offset = col * colsize;
8332 src = ibuff + src_offset;
8333 dst = rbuff + dst_offset;
8334 for (row = length; row > 0; row--)
8336 for (i = 0; i < bytes_per_pixel; i++)
8337 *dst++ = *(src + i);
8343 { /* non 8 bit per sample data */
8344 for (col = 0; col < width; col++)
8346 src_offset = (length - 1) * rowsize;
8347 dst_offset = col * colsize;
8348 src = ibuff + src_offset;
8349 dst = rbuff + dst_offset;
8350 switch (shift_width)
8352 case 1: if (bps == 1)
8354 if (rotateContigSamples8bits(rotation, spp, bps, width,
8355 length, col, src, dst))
8362 if (rotateContigSamples16bits(rotation, spp, bps, width,
8363 length, col, src, dst))
8369 case 2: if (rotateContigSamples24bits(rotation, spp, bps, width,
8370 length, col, src, dst))
8378 case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
8379 length, col, src, dst))
8385 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8392 *(ibuff_ptr) = rbuff;
8394 *img_width = length;
8395 *img_length = width;
8396 image->width = length;
8397 image->length = width;
8398 res_temp = image->xres;
8399 image->xres = image->yres;
8400 image->yres = res_temp;
8403 case 270: if ((bps % 8) == 0) /* byte aligned data */
8405 for (col = 0; col < width; col++)
8407 src_offset = col * bytes_per_pixel;
8408 dst_offset = (width - col - 1) * colsize;
8409 src = ibuff + src_offset;
8410 dst = rbuff + dst_offset;
8411 for (row = length; row > 0; row--)
8413 for (i = 0; i < bytes_per_pixel; i++)
8414 *dst++ = *(src + i);
8420 { /* non 8 bit per sample data */
8421 for (col = 0; col < width; col++)
8424 dst_offset = (width - col - 1) * colsize;
8425 src = ibuff + src_offset;
8426 dst = rbuff + dst_offset;
8427 switch (shift_width)
8429 case 1: if (bps == 1)
8431 if (rotateContigSamples8bits(rotation, spp, bps, width,
8432 length, col, src, dst))
8439 if (rotateContigSamples16bits(rotation, spp, bps, width,
8440 length, col, src, dst))
8446 case 2: if (rotateContigSamples24bits(rotation, spp, bps, width,
8447 length, col, src, dst))
8455 case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
8456 length, col, src, dst))
8462 default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
8469 *(ibuff_ptr) = rbuff;
8471 *img_width = length;
8472 *img_length = width;
8473 image->width = length;
8474 image->length = width;
8475 res_temp = image->xres;
8476 image->xres = image->yres;
8477 image->yres = res_temp;
8484 } /* end rotateImage */
8487 reverseSamples8bits (uint16 spp, uint16 bps, uint32 width,
8488 uint8 *ibuff, uint8 *obuff)
8492 uint32 src_byte, src_bit;
8493 uint32 bit_offset = 0;
8494 uint8 match_bits = 0, mask_bits = 0;
8495 uint8 buff1 = 0, buff2 = 0;
8500 if ((ibuff == NULL) || (obuff == NULL))
8502 TIFFError("reverseSamples8bits","Invalid image or work buffer");
8507 mask_bits = (uint8)-1 >> ( 8 - bps);
8509 for (col = width; col > 0; col--)
8511 /* Compute src byte(s) and bits within byte(s) */
8512 bit_offset = (col - 1) * bps * spp;
8513 for (sample = 0; sample < spp; sample++)
8517 src_byte = bit_offset / 8;
8518 src_bit = bit_offset % 8;
8522 src_byte = (bit_offset + (sample * bps)) / 8;
8523 src_bit = (bit_offset + (sample * bps)) % 8;
8526 src = ibuff + src_byte;
8527 match_bits = mask_bits << (8 - src_bit - bps);
8528 buff1 = ((*src) & match_bits) << (src_bit);
8531 buff2 = (buff2 | (buff1 >> ready_bits));
8532 else /* If we have a full buffer's worth, write it out */
8543 buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
8548 } /* end reverseSamples8bits */
8552 reverseSamples16bits (uint16 spp, uint16 bps, uint32 width,
8553 uint8 *ibuff, uint8 *obuff)
8557 uint32 src_byte = 0, high_bit = 0;
8558 uint32 bit_offset = 0;
8559 uint16 match_bits = 0, mask_bits = 0;
8560 uint16 buff1 = 0, buff2 = 0;
8566 if ((ibuff == NULL) || (obuff == NULL))
8568 TIFFError("reverseSample16bits","Invalid image or work buffer");
8573 mask_bits = (uint16)-1 >> (16 - bps);
8575 for (col = width; col > 0; col--)
8577 /* Compute src byte(s) and bits within byte(s) */
8578 bit_offset = (col - 1) * bps * spp;
8579 for (sample = 0; sample < spp; sample++)
8583 src_byte = bit_offset / 8;
8584 high_bit = bit_offset % 8;
8588 src_byte = (bit_offset + (sample * bps)) / 8;
8589 high_bit = (bit_offset + (sample * bps)) % 8;
8592 src = ibuff + src_byte;
8593 match_bits = mask_bits << (16 - high_bit - bps);
8595 buff1 = (src[0] << 8) | src[1];
8597 buff1 = (src[1] << 8) | src[0];
8598 buff1 = (buff1 & match_bits) << (high_bit);
8601 { /* add another bps bits to the buffer */
8603 buff2 = (buff2 | (buff1 >> ready_bits));
8605 else /* If we have a full buffer's worth, write it out */
8607 bytebuff = (buff2 >> 8);
8610 /* shift in new bits */
8611 buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
8619 bytebuff = (buff2 >> 8);
8624 } /* end reverseSamples16bits */
8627 reverseSamples24bits (uint16 spp, uint16 bps, uint32 width,
8628 uint8 *ibuff, uint8 *obuff)
8632 uint32 src_byte = 0, high_bit = 0;
8633 uint32 bit_offset = 0;
8634 uint32 match_bits = 0, mask_bits = 0;
8635 uint32 buff1 = 0, buff2 = 0;
8636 uint8 bytebuff1 = 0, bytebuff2 = 0;
8641 if ((ibuff == NULL) || (obuff == NULL))
8643 TIFFError("reverseSamples24bits","Invalid image or work buffer");
8648 mask_bits = (uint32)-1 >> (32 - bps);
8650 for (col = width; col > 0; col--)
8652 /* Compute src byte(s) and bits within byte(s) */
8653 bit_offset = (col - 1) * bps * spp;
8654 for (sample = 0; sample < spp; sample++)
8658 src_byte = bit_offset / 8;
8659 high_bit = bit_offset % 8;
8663 src_byte = (bit_offset + (sample * bps)) / 8;
8664 high_bit = (bit_offset + (sample * bps)) % 8;
8667 src = ibuff + src_byte;
8668 match_bits = mask_bits << (32 - high_bit - bps);
8670 buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8672 buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8673 buff1 = (buff1 & match_bits) << (high_bit);
8675 if (ready_bits < 16)
8676 { /* add another bps bits to the buffer */
8677 bytebuff1 = bytebuff2 = 0;
8678 buff2 = (buff2 | (buff1 >> ready_bits));
8680 else /* If we have a full buffer's worth, write it out */
8682 bytebuff1 = (buff2 >> 24);
8684 bytebuff2 = (buff2 >> 16);
8688 /* shift in new bits */
8689 buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
8695 /* catch any trailing bits at the end of the line */
8696 while (ready_bits > 0)
8698 bytebuff1 = (buff2 >> 24);
8701 buff2 = (buff2 << 8);
8702 bytebuff2 = bytebuff1;
8707 } /* end reverseSamples24bits */
8711 reverseSamples32bits (uint16 spp, uint16 bps, uint32 width,
8712 uint8 *ibuff, uint8 *obuff)
8714 int ready_bits = 0, shift_width = 0;
8715 int bytes_per_sample, bytes_per_pixel;
8717 uint32 src_byte = 0, high_bit = 0;
8719 uint32 longbuff1 = 0, longbuff2 = 0;
8720 uint64 mask_bits = 0, match_bits = 0;
8721 uint64 buff1 = 0, buff2 = 0, buff3 = 0;
8722 uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
8727 if ((ibuff == NULL) || (obuff == NULL))
8729 TIFFError("reverseSamples32bits","Invalid image or work buffer");
8734 mask_bits = (uint64)-1 >> (64 - bps);
8737 bytes_per_sample = (bps + 7) / 8;
8738 bytes_per_pixel = ((bps * spp) + 7) / 8;
8739 if (bytes_per_pixel < (bytes_per_sample + 1))
8740 shift_width = bytes_per_pixel;
8742 shift_width = bytes_per_sample + 1;
8744 for (col = width; col > 0; col--)
8746 /* Compute src byte(s) and bits within byte(s) */
8747 bit_offset = (col - 1) * bps * spp;
8748 for (sample = 0; sample < spp; sample++)
8752 src_byte = bit_offset / 8;
8753 high_bit = bit_offset % 8;
8757 src_byte = (bit_offset + (sample * bps)) / 8;
8758 high_bit = (bit_offset + (sample * bps)) % 8;
8761 src = ibuff + src_byte;
8762 match_bits = mask_bits << (64 - high_bit - bps);
8765 longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
8766 longbuff2 = longbuff1;
8770 longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
8771 longbuff2 = longbuff1;
8773 buff3 = ((uint64)longbuff1 << 32) | longbuff2;
8774 buff1 = (buff3 & match_bits) << (high_bit);
8776 if (ready_bits < 32)
8777 { /* add another bps bits to the buffer */
8778 bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
8779 buff2 = (buff2 | (buff1 >> ready_bits));
8781 else /* If we have a full buffer's worth, write it out */
8783 bytebuff1 = (buff2 >> 56);
8785 bytebuff2 = (buff2 >> 48);
8787 bytebuff3 = (buff2 >> 40);
8789 bytebuff4 = (buff2 >> 32);
8793 /* shift in new bits */
8794 buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
8799 while (ready_bits > 0)
8801 bytebuff1 = (buff2 >> 56);
8803 buff2 = (buff2 << 8);
8808 } /* end reverseSamples32bits */
8811 reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width,
8812 uint8 *src, uint8 *dst)
8815 uint32 col, bytes_per_pixel, col_offset;
8817 unsigned char swapbuff[32];
8819 if ((src == NULL) || (dst == NULL))
8821 TIFFError("reverseSamplesBytes","Invalid input or output buffer");
8825 bytes_per_pixel = ((bps * spp) + 7) / 8;
8828 case 8: /* Use memcpy for multiple bytes per sample data */
8831 case 2: for (col = 0; col < (width / 2); col++)
8833 col_offset = col * bytes_per_pixel;
8834 _TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
8835 _TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
8836 _TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
8839 case 1: /* Use byte copy only for single byte per sample data */
8840 for (col = 0; col < (width / 2); col++)
8842 for (i = 0; i < spp; i++)
8845 *src++ = *(dst - spp + i);
8846 *(dst - spp + i) = bytebuff1;
8851 default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
8855 } /* end reverseSamplesBytes */
8858 /* Mirror an image horizontally or vertically */
8860 mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
8863 uint32 bytes_per_pixel, bytes_per_sample;
8864 uint32 row, rowsize, row_offset;
8865 unsigned char *line_buff = NULL;
8870 rowsize = ((width * bps * spp) + 7) / 8;
8875 line_buff = (unsigned char *)_TIFFmalloc(rowsize);
8876 if (line_buff == NULL)
8878 TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
8882 dst = ibuff + (rowsize * (length - 1));
8883 for (row = 0; row < length / 2; row++)
8885 _TIFFmemcpy(line_buff, src, rowsize);
8886 _TIFFmemcpy(src, dst, rowsize);
8887 _TIFFmemcpy(dst, line_buff, rowsize);
8892 _TIFFfree(line_buff);
8893 if (mirror == MIRROR_VERT)
8896 if ((bps % 8) == 0) /* byte alligned data */
8898 for (row = 0; row < length; row++)
8900 row_offset = row * rowsize;
8901 src = ibuff + row_offset;
8902 dst = ibuff + row_offset + rowsize;
8903 if (reverseSamplesBytes(spp, bps, width, src, dst))
8910 { /* non 8 bit per sample data */
8911 if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
8913 TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
8916 bytes_per_sample = (bps + 7) / 8;
8917 bytes_per_pixel = ((bps * spp) + 7) / 8;
8918 if (bytes_per_pixel < (bytes_per_sample + 1))
8919 shift_width = bytes_per_pixel;
8921 shift_width = bytes_per_sample + 1;
8923 for (row = 0; row < length; row++)
8925 row_offset = row * rowsize;
8926 src = ibuff + row_offset;
8927 _TIFFmemset (line_buff, '\0', rowsize);
8928 switch (shift_width)
8930 case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
8932 _TIFFfree(line_buff);
8935 _TIFFmemcpy (src, line_buff, rowsize);
8937 case 2: if (reverseSamples24bits(spp, bps, width, src, line_buff))
8939 _TIFFfree(line_buff);
8942 _TIFFmemcpy (src, line_buff, rowsize);
8946 case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
8948 _TIFFfree(line_buff);
8951 _TIFFmemcpy (src, line_buff, rowsize);
8953 default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
8954 _TIFFfree(line_buff);
8959 _TIFFfree(line_buff);
8963 default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
8971 /* Invert the light and dark values for a bilevel or grayscale image */
8973 invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
8976 unsigned char bytebuff1, bytebuff2, bytebuff3, bytebuff4;
8983 TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
8987 if (photometric != PHOTOMETRIC_MINISWHITE && photometric != PHOTOMETRIC_MINISBLACK)
8989 TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
8996 TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
9002 case 32: src_uint32 = (uint32 *)src;
9003 for (row = 0; row < length; row++)
9004 for (col = 0; col < width; col++)
9006 *src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
9010 case 16: src_uint16 = (uint16 *)src;
9011 for (row = 0; row < length; row++)
9012 for (col = 0; col < width; col++)
9014 *src_uint16 = (uint16)0xFFFF - *src_uint16;
9018 case 8: for (row = 0; row < length; row++)
9019 for (col = 0; col < width; col++)
9021 *src = (uint8)255 - *src;
9025 case 4: for (row = 0; row < length; row++)
9026 for (col = 0; col < width; col++)
9028 bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
9029 bytebuff2 = 16 - (*src & 15);
9030 *src = bytebuff1 << 4 & bytebuff2;
9034 case 2: for (row = 0; row < length; row++)
9035 for (col = 0; col < width; col++)
9037 bytebuff1 = 4 - (uint8)(*src & 192 >> 6);
9038 bytebuff2 = 4 - (uint8)(*src & 48 >> 4);
9039 bytebuff3 = 4 - (uint8)(*src & 12 >> 2);
9040 bytebuff4 = 4 - (uint8)(*src & 3);
9041 *src = (bytebuff1 << 6) || (bytebuff2 << 4) || (bytebuff3 << 2) || bytebuff4;
9045 case 1: for (row = 0; row < length; row++)
9046 for (col = 0; col < width; col += 8 /(spp * bps))
9052 default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
9059 /* vim: set ts=8 sts=8 sw=8 noet: */