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: */