2 /* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
3 * the image data through additional options listed below
6 * Copyright (c) 1988-1997 Sam Leffler
7 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
8 * Additions (c) Richard Nolde 2006-2010
10 * Permission to use, copy, modify, distribute, and sell this software and
11 * its documentation for any purpose is hereby granted without fee, provided
12 * that (i) the above copyright notices and this permission notice appear in
13 * all copies of the software and related documentation, and (ii) the names of
14 * Sam Leffler and Silicon Graphics may not be used in any advertising or
15 * publicity relating to the software without the specific, prior written
16 * permission of Sam Leffler and Silicon Graphics.
18 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
20 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
22 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS OR ANY OTHER COPYRIGHT
23 * HOLDERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL
24 * DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
25 * DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
26 * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
27 * OR PERFORMANCE OF THIS SOFTWARE.
29 * Some portions of the current code are derived from tiffcp, primarly in
30 * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though
31 * some of the original functions have been extended to support arbitrary bit
32 * depths. These functions are presented at the top of this file.
34 * Add support for the options below to extract sections of image(s)
35 * and to modify the whole image or selected portions of each image by
36 * rotations, mirroring, and colorscale/colormap inversion of selected
37 * types of TIFF images when appropriate. Some color model dependent
38 * functions are restricted to bilevel or 8 bit per sample data.
39 * See the man page for the full explanations.
42 * -h Display the syntax guide.
43 * -v Report the version and last build date for tiffcrop and libtiff.
44 * -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1
45 * Specify a series of coordinates to define rectangular
46 * regions by the top left and lower right corners.
47 * -e c|d|i|m|s export mode for images and selections from input images
48 * combined All images and selections are written to a single file (default)
49 * with multiple selections from one image combined into a single image
50 * divided All images and selections are written to a single file
51 * with each selection from one image written to a new image
52 * image Each input image is written to a new file (numeric filename sequence)
53 * with multiple selections from the image combined into one image
54 * multiple Each input image is written to a new file (numeric filename sequence)
55 * with each selection from the image written to a new image
56 * separated Individual selections from each image are written to separate files
57 * -U units [in, cm, px ] inches, centimeters or pixels
58 * -H # Set horizontal resolution of output images to #
59 * -V # Set vertical resolution of output images to #
60 * -J # Horizontal margin of output page to # expressed in current
61 * units when sectioning image into columns x rows
62 * using the -S cols:rows option.
63 * -K # Vertical margin of output page to # expressed in current
64 * units when sectioning image into columns x rows
65 * using the -S cols:rows option.
66 * -X # Horizontal dimension of region to extract expressed in current
68 * -Y # Vertical dimension of region to extract expressed in current
70 * -O orient Orientation for output image, portrait, landscape, auto
71 * -P page Page size for output image segments, eg letter, legal, tabloid,
73 * -S cols:rows Divide the image into equal sized segments using cols across
75 * -E t|l|r|b Edge to use as origin
76 * -m #,#,#,# Margins from edges for selection: top, left, bottom, right
78 * -Z #:#,#:# Zones of the image designated as zone X of Y,
79 * eg 1:3 would be first of three equal portions measured
81 * -N odd|even|#,#-#,#|last
82 * Select sequences and/or ranges of images within file
83 * to process. The words odd or even may be used to specify
84 * all odd or even numbered images the word last may be used
85 * in place of a number in the sequence to indicate the final
86 * image in the file without knowing how many images there are.
87 * -R # Rotate image or crop selection by 90,180,or 270 degrees
89 * -F h|v Flip (mirror) image or crop selection horizontally
91 * -I [black|white|data|both]
92 * Invert color space, eg dark to light for bilevel and grayscale images
93 * If argument is white or black, set the PHOTOMETRIC_INTERPRETATION
94 * tag to MinIsBlack or MinIsWhite without altering the image data
95 * If the argument is data or both, the image data are modified:
96 * both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
97 * data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
98 * -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
99 * Dump raw data for input and/or output images to individual files
100 * in raw (binary) format or text (ASCII) representing binary data
101 * as strings of 1s and 0s. The filename arguments are used as stems
102 * from which individual files are created for each image. Text format
103 * includes annotations for image parameters and scanline info. Level
104 * selects which functions dump data, with higher numbers selecting
105 * lower level, scanline level routines. Debug reports a limited set
106 * of messages to monitor progess without enabling dump logs.
109 static char tiffcrop_version_id
[] = "2.4";
110 static char tiffcrop_rev_date
[] = "12-13-2010";
112 #include "tif_config.h"
121 #include <sys/stat.h>
133 extern int getopt(int, char**, char*);
137 # include "libport.h"
143 # define unlink delete
147 #define PATH_MAX 1024
151 #define streq(a,b) (strcmp((a),(b)) == 0)
153 #define strneq(a,b,n) (strncmp((a),(b),(n)) == 0)
159 #define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
160 #define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
164 * Definitions and data structures required to support cropping and image
170 #define EDGE_BOTTOM 3
172 #define EDGE_CENTER 5
174 #define MIRROR_HORIZ 1
175 #define MIRROR_VERT 2
176 #define MIRROR_BOTH 3
177 #define ROTATECW_90 8
178 #define ROTATECW_180 16
179 #define ROTATECW_270 32
180 #define ROTATE_ANY ROTATECW_90 || ROTATECW_180 || ROTATECW_270
183 #define CROP_MARGINS 1
185 #define CROP_LENGTH 4
187 #define CROP_REGIONS 16
188 #define CROP_ROTATE 32
189 #define CROP_MIRROR 64
190 #define CROP_INVERT 128
192 /* Modes for writing out images and selections */
193 #define ONE_FILE_COMPOSITE 0 /* One file, sections combined sections */
194 #define ONE_FILE_SEPARATED 1 /* One file, sections to new IFDs */
195 #define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
196 #define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
197 #define FILE_PER_SELECTION 4 /* One file per selection */
199 #define COMPOSITE_IMAGES 0 /* Selections combined into one image */
200 #define SEPARATED_IMAGES 1 /* Selections saved to separate images */
205 #define MAX_REGIONS 8 /* number of regions to extract from a single page */
206 #define MAX_OUTBUFFS 8 /* must match larger of zones or regions */
207 #define MAX_SECTIONS 32 /* number of sections per page to write to output */
208 #define MAX_IMAGES 2048 /* number of images in descrete list, not in the file */
209 #define MAX_SAMPLES 8 /* maximum number of samples per pixel supported */
210 #define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
211 #define MAX_EXPORT_PAGES 999999 /* maximum number of export pages per file */
217 /* Offsets into buffer for margins and fixed width and length segments */
231 /* Description of a zone within the image. Position 1 of 3 zones would be
232 * the first third of the image. These are computed after margins and
233 * width/length requests are applied so that you can extract multiple
234 * zones from within a larger region for OCR or barcode recognition.
238 uint32 size
; /* size of this buffer */
239 unsigned char *buffer
; /* address of the allocated buffer */
243 int position
; /* ordinal of segment to be extracted */
244 int total
; /* total equal sized divisions of crop area */
248 uint32 x1
; /* index of left edge */
249 uint32 x2
; /* index of right edge */
250 uint32 y1
; /* index of top edge */
251 uint32 y2
; /* index of bottom edge */
252 int position
; /* ordinal of segment to be extracted */
253 int total
; /* total equal sized divisions of crop area */
254 uint32 buffsize
; /* size of buffer needed to hold the cropped zone */
258 double X1
; /* index of left edge in current units */
259 double X2
; /* index of right edge in current units */
260 double Y1
; /* index of top edge in current units */
261 double Y2
; /* index of bottom edge in current units */
265 uint32 x1
; /* pixel offset of left edge */
266 uint32 x2
; /* pixel offset of right edge */
267 uint32 y1
; /* pixel offset of top edge */
268 uint32 y2
; /* picel offset of bottom edge */
269 uint32 width
; /* width in pixels */
270 uint32 length
; /* length in pixels */
271 uint32 buffsize
; /* size of buffer needed to hold the cropped region */
272 unsigned char *buffptr
; /* address of start of the region */
275 /* Cropping parameters from command line and image data
276 * Note: This should be renamed to proc_opts and expanded to include all current globals
277 * if possible, but each function that accesses global variables will have to be redone.
280 double width
; /* Selection width for master crop region in requested units */
281 double length
; /* Selection length for master crop region in requesed units */
282 double margins
[4]; /* Top, left, bottom, right margins */
283 float xres
; /* Horizontal resolution read from image*/
284 float yres
; /* Vertical resolution read from image */
285 uint32 combined_width
; /* Width of combined cropped zones */
286 uint32 combined_length
; /* Length of combined cropped zones */
287 uint32 bufftotal
; /* Size of buffer needed to hold all the cropped region */
288 uint16 img_mode
; /* Composite or separate images created from zones or regions */
289 uint16 exp_mode
; /* Export input images or selections to one or more files */
290 uint16 crop_mode
; /* Crop options to be applied */
291 uint16 res_unit
; /* Resolution unit for margins and selections */
292 uint16 edge_ref
; /* Reference edge for sections extraction and combination */
293 uint16 rotation
; /* Clockwise rotation of the extracted region or image */
294 uint16 mirror
; /* Mirror extracted region or image horizontally or vertically */
295 uint16 invert
; /* Invert the color map of image or region */
296 uint16 photometric
; /* Status of photometric interpretation for inverted image */
297 uint16 selections
; /* Number of regions or zones selected */
298 uint16 regions
; /* Number of regions delimited by corner coordinates */
299 struct region regionlist
[MAX_REGIONS
]; /* Regions within page or master crop region */
300 uint16 zones
; /* Number of zones delimited by Ordinal:Total requested */
301 struct zone zonelist
[MAX_REGIONS
]; /* Zones indices to define a region */
302 struct coordpairs corners
[MAX_REGIONS
]; /* Coordinates of upper left and lower right corner */
305 #define MAX_PAPERNAMES 49
306 #define MAX_PAPERNAME_LENGTH 15
307 #define DEFAULT_RESUNIT RESUNIT_INCH
308 #define DEFAULT_PAGE_HEIGHT 14.0
309 #define DEFAULT_PAGE_WIDTH 8.5
310 #define DEFAULT_RESOLUTION 300
311 #define DEFAULT_PAPER_SIZE "legal"
313 #define ORIENTATION_NONE 0
314 #define ORIENTATION_PORTRAIT 1
315 #define ORIENTATION_LANDSCAPE 2
316 #define ORIENTATION_SEASCAPE 4
317 #define ORIENTATION_AUTO 16
319 #define PAGE_MODE_NONE 0
320 #define PAGE_MODE_RESOLUTION 1
321 #define PAGE_MODE_PAPERSIZE 2
322 #define PAGE_MODE_MARGINS 4
323 #define PAGE_MODE_ROWSCOLS 8
325 #define INVERT_DATA_ONLY 10
326 #define INVERT_DATA_AND_TAG 11
329 char name
[MAX_PAPERNAME_LENGTH
];
335 /* European page sizes corrected from update sent by
336 * thomas . jarosch @ intra2net . com on 5/7/2010
337 * Paper Size Width Length Aspect Ratio */
338 struct paperdef PaperTable
[MAX_PAPERNAMES
] = {
339 {"default", 8.500, 14.000, 0.607},
340 {"pa4", 8.264, 11.000, 0.751},
341 {"letter", 8.500, 11.000, 0.773},
342 {"legal", 8.500, 14.000, 0.607},
343 {"half-letter", 8.500, 5.514, 1.542},
344 {"executive", 7.264, 10.528, 0.690},
345 {"tabloid", 11.000, 17.000, 0.647},
346 {"11x17", 11.000, 17.000, 0.647},
347 {"ledger", 17.000, 11.000, 1.545},
348 {"archa", 9.000, 12.000, 0.750},
349 {"archb", 12.000, 18.000, 0.667},
350 {"archc", 18.000, 24.000, 0.750},
351 {"archd", 24.000, 36.000, 0.667},
352 {"arche", 36.000, 48.000, 0.750},
353 {"csheet", 17.000, 22.000, 0.773},
354 {"dsheet", 22.000, 34.000, 0.647},
355 {"esheet", 34.000, 44.000, 0.773},
356 {"superb", 11.708, 17.042, 0.687},
357 {"commercial", 4.139, 9.528, 0.434},
358 {"monarch", 3.889, 7.528, 0.517},
359 {"envelope-dl", 4.333, 8.681, 0.499},
360 {"envelope-c5", 6.389, 9.028, 0.708},
361 {"europostcard", 4.139, 5.833, 0.710},
362 {"a0", 33.110, 46.811, 0.707},
363 {"a1", 23.386, 33.110, 0.706},
364 {"a2", 16.535, 23.386, 0.707},
365 {"a3", 11.693, 16.535, 0.707},
366 {"a4", 8.268, 11.693, 0.707},
367 {"a5", 5.827, 8.268, 0.705},
368 {"a6", 4.134, 5.827, 0.709},
369 {"a7", 2.913, 4.134, 0.705},
370 {"a8", 2.047, 2.913, 0.703},
371 {"a9", 1.457, 2.047, 0.712},
372 {"a10", 1.024, 1.457, 0.703},
373 {"b0", 39.370, 55.669, 0.707},
374 {"b1", 27.835, 39.370, 0.707},
375 {"b2", 19.685, 27.835, 0.707},
376 {"b3", 13.898, 19.685, 0.706},
377 {"b4", 9.843, 13.898, 0.708},
378 {"b5", 6.929, 9.843, 0.704},
379 {"b6", 4.921, 6.929, 0.710},
380 {"c0", 36.102, 51.063, 0.707},
381 {"c1", 25.512, 36.102, 0.707},
382 {"c2", 18.031, 25.512, 0.707},
383 {"c3", 12.756, 18.031, 0.707},
384 {"c4", 9.016, 12.756, 0.707},
385 {"c5", 6.378, 9.016, 0.707},
386 {"c6", 4.488, 6.378, 0.704},
387 {"", 0.000, 0.000, 1.000}
390 /* Structure to define input image parameters */
406 /* Structure to define the output image modifiers */
409 double width
; /* width in pixels */
410 double length
; /* length in pixels */
411 double hmargin
; /* margins to subtract from width of sections */
412 double vmargin
; /* margins to subtract from height of sections */
413 double hres
; /* horizontal resolution for output */
414 double vres
; /* vertical resolution for output */
415 uint32 mode
; /* bitmask of modifiers to page format */
416 uint16 res_unit
; /* resolution unit for output image */
417 unsigned int rows
; /* number of section rows */
418 unsigned int cols
; /* number of section cols */
419 unsigned int orient
; /* portrait, landscape, seascape, auto */
427 char infilename
[PATH_MAX
+ 1];
428 char outfilename
[PATH_MAX
+ 1];
434 static int outtiled
= -1;
435 static uint32 tilewidth
= 0;
436 static uint32 tilelength
= 0;
438 static uint16 config
= 0;
439 static uint16 compression
= 0;
440 static uint16 predictor
= 0;
441 static uint16 fillorder
= 0;
442 static uint32 rowsperstrip
= 0;
443 static uint32 g3opts
= 0;
444 static int ignore
= FALSE
; /* if true, ignore read errors */
445 static uint32 defg3opts
= (uint32
) -1;
446 static int quality
= 100; /* JPEG quality */
447 /* static int jpegcolormode = -1; was JPEGCOLORMODE_RGB; */
448 static int jpegcolormode
= JPEGCOLORMODE_RGB
;
449 static uint16 defcompression
= (uint16
) -1;
450 static uint16 defpredictor
= (uint16
) -1;
451 static int pageNum
= 0;
452 static int little_endian
= 1;
454 /* Functions adapted from tiffcp with additions or significant modifications */
455 static int readContigStripsIntoBuffer (TIFF
*, uint8
*);
456 static int readSeparateStripsIntoBuffer (TIFF
*, uint8
*, uint32
, uint32
, tsample_t
, struct dump_opts
*);
457 static int readContigTilesIntoBuffer (TIFF
*, uint8
*, uint32
, uint32
, uint32
, uint32
, tsample_t
, uint16
);
458 static int readSeparateTilesIntoBuffer (TIFF
*, uint8
*, uint32
, uint32
, uint32
, uint32
, tsample_t
, uint16
);
459 static int writeBufferToContigStrips (TIFF
*, uint8
*, uint32
);
460 static int writeBufferToContigTiles (TIFF
*, uint8
*, uint32
, uint32
, tsample_t
, struct dump_opts
*);
461 static int writeBufferToSeparateStrips (TIFF
*, uint8
*, uint32
, uint32
, tsample_t
, struct dump_opts
*);
462 static int writeBufferToSeparateTiles (TIFF
*, uint8
*, uint32
, uint32
, tsample_t
, struct dump_opts
*);
463 static int extractContigSamplesToBuffer (uint8
*, uint8
*, uint32
, uint32
, tsample_t
,
464 uint16
, uint16
, struct dump_opts
*);
465 static int processCompressOptions(char*);
466 static void usage(void);
468 /* All other functions by Richard Nolde, not found in tiffcp */
469 static void initImageData (struct image_data
*);
470 static void initCropMasks (struct crop_mask
*);
471 static void initPageSetup (struct pagedef
*, struct pageseg
*, struct buffinfo
[]);
472 static void initDumpOptions(struct dump_opts
*);
474 /* Command line and file naming functions */
475 void process_command_opts (int, char *[], char *, char *, uint32
*,
476 uint16
*, uint16
*, uint32
*, uint32
*, uint32
*,
477 struct crop_mask
*, struct pagedef
*,
479 unsigned int *, unsigned int *);
480 static int update_output_file (TIFF
**, char *, int, char *, unsigned int *);
483 /* * High level functions for whole image manipulation */
484 static int get_page_geometry (char *, struct pagedef
*);
485 static int computeInputPixelOffsets(struct crop_mask
*, struct image_data
*,
487 static int computeOutputPixelOffsets (struct crop_mask
*, struct image_data
*,
488 struct pagedef
*, struct pageseg
*,
490 static int loadImage(TIFF
*, struct image_data
*, struct dump_opts
*, unsigned char **);
491 static int correct_orientation(struct image_data
*, unsigned char **);
492 static int getCropOffsets(struct image_data
*, struct crop_mask
*, struct dump_opts
*);
493 static int processCropSelections(struct image_data
*, struct crop_mask
*,
494 unsigned char **, struct buffinfo
[]);
495 static int writeSelections(TIFF
*, TIFF
**, struct crop_mask
*, struct image_data
*,
496 struct dump_opts
*, struct buffinfo
[],
497 char *, char *, unsigned int*, unsigned int);
499 /* Section functions */
500 static int createImageSection(uint32
, unsigned char **);
501 static int extractImageSection(struct image_data
*, struct pageseg
*,
502 unsigned char *, unsigned char *);
503 static int writeSingleSection(TIFF
*, TIFF
*, struct image_data
*,
504 struct dump_opts
*, uint32
, uint32
,
505 double, double, unsigned char *);
506 static int writeImageSections(TIFF
*, TIFF
*, struct image_data
*,
507 struct pagedef
*, struct pageseg
*,
508 struct dump_opts
*, unsigned char *,
510 /* Whole image functions */
511 static int createCroppedImage(struct image_data
*, struct crop_mask
*,
512 unsigned char **, unsigned char **);
513 static int writeCroppedImage(TIFF
*, TIFF
*, struct image_data
*image
,
514 struct dump_opts
* dump
,
515 uint32
, uint32
, unsigned char *, int, int);
517 /* Image manipulation functions */
518 static int rotateContigSamples8bits(uint16
, uint16
, uint16
, uint32
,
519 uint32
, uint32
, uint8
*, uint8
*);
520 static int rotateContigSamples16bits(uint16
, uint16
, uint16
, uint32
,
521 uint32
, uint32
, uint8
*, uint8
*);
522 static int rotateContigSamples24bits(uint16
, uint16
, uint16
, uint32
,
523 uint32
, uint32
, uint8
*, uint8
*);
524 static int rotateContigSamples32bits(uint16
, uint16
, uint16
, uint32
,
525 uint32
, uint32
, uint8
*, uint8
*);
526 static int rotateImage(uint16
, struct image_data
*, uint32
*, uint32
*,
528 static int mirrorImage(uint16
, uint16
, uint16
, uint32
, uint32
,
530 static int invertImage(uint16
, uint16
, uint16
, uint32
, uint32
,
533 /* Functions to reverse the sequence of samples in a scanline */
534 static int reverseSamples8bits (uint16
, uint16
, uint32
, uint8
*, uint8
*);
535 static int reverseSamples16bits (uint16
, uint16
, uint32
, uint8
*, uint8
*);
536 static int reverseSamples24bits (uint16
, uint16
, uint32
, uint8
*, uint8
*);
537 static int reverseSamples32bits (uint16
, uint16
, uint32
, uint8
*, uint8
*);
538 static int reverseSamplesBytes (uint16
, uint16
, uint32
, uint8
*, uint8
*);
540 /* Functions for manipulating individual samples in an image */
541 static int extractSeparateRegion(struct image_data
*, struct crop_mask
*,
542 unsigned char *, unsigned char *, int);
543 static int extractCompositeRegions(struct image_data
*, struct crop_mask
*,
544 unsigned char *, unsigned char *);
545 static int extractContigSamples8bits (uint8
*, uint8
*, uint32
,
546 tsample_t
, uint16
, uint16
,
547 tsample_t
, uint32
, uint32
);
548 static int extractContigSamples16bits (uint8
*, uint8
*, uint32
,
549 tsample_t
, uint16
, uint16
,
550 tsample_t
, uint32
, uint32
);
551 static int extractContigSamples24bits (uint8
*, uint8
*, uint32
,
552 tsample_t
, uint16
, uint16
,
553 tsample_t
, uint32
, uint32
);
554 static int extractContigSamples32bits (uint8
*, uint8
*, uint32
,
555 tsample_t
, uint16
, uint16
,
556 tsample_t
, uint32
, uint32
);
557 static int extractContigSamplesBytes (uint8
*, uint8
*, uint32
,
558 tsample_t
, uint16
, uint16
,
559 tsample_t
, uint32
, uint32
);
560 static int extractContigSamplesShifted8bits (uint8
*, uint8
*, uint32
,
561 tsample_t
, uint16
, uint16
,
562 tsample_t
, uint32
, uint32
,
564 static int extractContigSamplesShifted16bits (uint8
*, uint8
*, uint32
,
565 tsample_t
, uint16
, uint16
,
566 tsample_t
, uint32
, uint32
,
568 static int extractContigSamplesShifted24bits (uint8
*, uint8
*, uint32
,
569 tsample_t
, uint16
, uint16
,
570 tsample_t
, uint32
, uint32
,
572 static int extractContigSamplesShifted32bits (uint8
*, uint8
*, uint32
,
573 tsample_t
, uint16
, uint16
,
574 tsample_t
, uint32
, uint32
,
576 static int extractContigSamplesToTileBuffer(uint8
*, uint8
*, uint32
, uint32
,
577 uint32
, uint32
, tsample_t
, uint16
,
578 uint16
, uint16
, struct dump_opts
*);
580 /* Functions to combine separate planes into interleaved planes */
581 static int combineSeparateSamples8bits (uint8
*[], uint8
*, uint32
, uint32
,
582 uint16
, uint16
, FILE *, int, int);
583 static int combineSeparateSamples16bits (uint8
*[], uint8
*, uint32
, uint32
,
584 uint16
, uint16
, FILE *, int, int);
585 static int combineSeparateSamples24bits (uint8
*[], uint8
*, uint32
, uint32
,
586 uint16
, uint16
, FILE *, int, int);
587 static int combineSeparateSamples32bits (uint8
*[], uint8
*, uint32
, uint32
,
588 uint16
, uint16
, FILE *, int, int);
589 static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
590 uint32
, uint32
, tsample_t
, uint16
,
593 static int combineSeparateTileSamples8bits (uint8
*[], uint8
*, uint32
, uint32
,
594 uint32
, uint32
, uint16
, uint16
,
596 static int combineSeparateTileSamples16bits (uint8
*[], uint8
*, uint32
, uint32
,
597 uint32
, uint32
, uint16
, uint16
,
599 static int combineSeparateTileSamples24bits (uint8
*[], uint8
*, uint32
, uint32
,
600 uint32
, uint32
, uint16
, uint16
,
602 static int combineSeparateTileSamples32bits (uint8
*[], uint8
*, uint32
, uint32
,
603 uint32
, uint32
, uint16
, uint16
,
605 static int combineSeparateTileSamplesBytes (unsigned char *[], unsigned char *,
606 uint32
, uint32
, uint32
, uint32
,
607 tsample_t
, uint16
, FILE *, int, int);
609 /* Dump functions for debugging */
610 static void dump_info (FILE *, int, char *, char *, ...);
611 static int dump_data (FILE *, int, char *, unsigned char *, uint32
);
612 static int dump_byte (FILE *, int, char *, unsigned char);
613 static int dump_short (FILE *, int, char *, uint16
);
614 static int dump_long (FILE *, int, char *, uint32
);
615 static int dump_wide (FILE *, int, char *, uint64
);
616 static int dump_buffer (FILE *, int, uint32
, uint32
, uint32
, unsigned char *);
618 /* End function declarations */
619 /* Functions derived in whole or in part from tiffcp */
620 /* The following functions are taken largely intact from tiffcp */
622 static char* usage_info
[] = {
623 "usage: tiffcrop [options] source1 ... sourceN destination",
624 "where options are:",
625 " -h Print this syntax listing",
626 " -v Print tiffcrop version identifier and last revision date",
628 " -a Append to output instead of overwriting",
629 " -d offset Set initial directory offset, counting first image as one, not zero",
630 " -p contig Pack samples contiguously (e.g. RGBRGB...)",
631 " -p separate Store samples separately (e.g. RRR...GGG...BBB...)",
632 " -s Write output in strips",
633 " -t Write output in tiles",
634 " -i Ignore read errors",
636 " -r # Make each strip have no more than # rows",
637 " -w # Set output tile width (pixels)",
638 " -l # Set output tile length (pixels)",
640 " -f lsb2msb Force lsb-to-msb FillOrder for output",
641 " -f msb2lsb Force msb-to-lsb FillOrder for output",
643 " -c lzw[:opts] Compress output with Lempel-Ziv & Welch encoding",
644 " -c zip[:opts] Compress output with deflate encoding",
645 " -c jpeg[:opts] Compress output with JPEG encoding",
646 " -c packbits Compress output with packbits encoding",
647 " -c g3[:opts] Compress output with CCITT Group 3 encoding",
648 " -c g4 Compress output with CCITT Group 4 encoding",
649 " -c none Use no compression algorithm on output",
652 " 1d Use default CCITT Group 3 1D-encoding",
653 " 2d Use optional CCITT Group 3 2D-encoding",
654 " fill Byte-align EOL codes",
655 "For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
658 " # Set compression quality level (0-100, default 100)",
659 " raw Output color image as raw YCbCr",
660 " rgb Output color image as RGB",
661 "For example, -c jpeg:rgb:50 to get JPEG-encoded RGB data with 50% comp. quality",
663 "LZW and deflate options:",
664 " # Set predictor value",
665 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
667 "Page and selection options:",
668 " -N odd|even|#,#-#,#|last sequences and ranges of images within file to process",
669 " The words odd or even may be used to specify all odd or even numbered images.",
670 " The word last may be used in place of a number in the sequence to indicate.",
671 " The final image in the file without knowing how many images there are.",
672 " Numbers are counted from one even though TIFF IFDs are counted from zero.",
674 " -E t|l|r|b edge to use as origin for width and length of crop region",
675 " -U units [in, cm, px ] inches, centimeters or pixels",
677 " -m #,#,#,# margins from edges for selection: top, left, bottom, right separated by commas",
678 " -X # horizontal dimension of region to extract expressed in current units",
679 " -Y # vertical dimension of region to extract expressed in current units",
680 " -Z #:#,#:# zones of the image designated as position X of Y,",
681 " eg 1:3 would be first of three equal portions measured from reference edge",
682 " -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
683 " regions of the image designated by upper left and lower right coordinates",
685 "Export grouping options:",
686 " -e c|d|i|m|s export mode for images and selections from input images.",
687 " When exporting a composite image from multiple zones or regions",
688 " (combined and image modes), the selections must have equal sizes",
689 " for the axis perpendicular to the edge specified with -E.",
690 " c|combined All images and selections are written to a single file (default).",
691 " with multiple selections from one image combined into a single image.",
692 " d|divided All images and selections are written to a single file",
693 " with each selection from one image written to a new image.",
694 " i|image Each input image is written to a new file (numeric filename sequence)",
695 " with multiple selections from the image combined into one image.",
696 " m|multiple Each input image is written to a new file (numeric filename sequence)",
697 " with each selection from the image written to a new image.",
698 " s|separated Individual selections from each image are written to separate files.",
701 " -H # Set horizontal resolution of output images to #",
702 " -V # Set vertical resolution of output images to #",
703 " -J # Set horizontal margin of output page to # expressed in current units",
704 " when sectioning image into columns x rows using the -S cols:rows option",
705 " -K # Set verticalal margin of output page to # expressed in current units",
706 " when sectioning image into columns x rows using the -S cols:rows option",
708 " -O orient orientation for output image, portrait, landscape, auto",
709 " -P page page size for output image segments, eg letter, legal, tabloid, etc",
710 " use #.#x#.# to specify a custom page size in the currently defined units",
711 " where #.# represents the width and length",
712 " -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
715 " flip (mirror) image or region horizontally, vertically, or both",
716 " -R # [90,180,or 270] degrees clockwise rotation of image or extracted region",
717 " -I [black|white|data|both]",
718 " invert color space, eg dark to light for bilevel and grayscale images",
719 " If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
720 " tag to MinIsBlack or MinIsWhite without altering the image data",
721 " If the argument is data or both, the image data are modified:",
722 " both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
723 " data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
725 "-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
726 " Debug/dump program progress and/or data to non-TIFF files.",
727 " Options include the following and must be joined as a comma",
728 " separate list. The use of this option is generally limited to",
729 " program debugging and development of future options.",
731 " debug:N Display limited program progress indicators where larger N",
732 " increase the level of detail. Note: Tiffcrop may be compiled with",
733 " -DDEVELMODE to enable additional very low level debug reporting.",
735 " Format:txt|raw Format any logged data as ASCII text or raw binary ",
736 " values. ASCII text dumps include strings of ones and zeroes",
737 " representing the binary values in the image data plus identifying headers.",
739 " level:N Specify the level of detail presented in the dump files.",
740 " This can vary from dumps of the entire input or output image data to dumps",
741 " of data processed by specific functions. Current range of levels is 1 to 3.",
743 " input:full-path-to-directory/input-dumpname",
745 " output:full-path-to-directory/output-dumpnaem",
747 " When dump files are being written, each image will be written to a separate",
748 " file with the name built by adding a numeric sequence value to the dumpname",
749 " and an extension of .txt for ASCII dumps or .bin for binary dumps.",
751 " The four debug/dump options are independent, though it makes little sense to",
752 " specify a dump file without specifying a detail level.",
757 /* This function could be modified to pass starting sample offset
758 * and number of samples as args to select fewer than spp
759 * from input image. These would then be passed to individual
760 * extractContigSampleXX routines.
762 static int readContigTilesIntoBuffer (TIFF
* in
, uint8
* buf
,
765 uint32 tw
, uint32 tl
,
766 tsample_t spp
, uint16 bps
)
769 tsample_t sample
= 0;
770 tsample_t count
= spp
;
771 uint32 row
, col
, trow
;
773 uint32 dst_rowsize
, shift_width
;
774 uint32 bytes_per_sample
, bytes_per_pixel
;
775 uint32 trailing_bits
, prev_trailing_bits
;
776 uint32 tile_rowsize
= TIFFTileRowSize(in
);
777 uint32 src_offset
, dst_offset
;
778 uint32 row_offset
, col_offset
;
779 uint8
*bufp
= (uint8
*) buf
;
780 unsigned char *src
= NULL
;
781 unsigned char *dst
= NULL
;
782 tsize_t tbytes
= 0, tile_buffsize
= 0;
783 tsize_t tilesize
= TIFFTileSize(in
);
784 unsigned char *tilebuf
= NULL
;
786 bytes_per_sample
= (bps
+ 7) / 8;
787 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
793 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
794 shift_width
= bytes_per_pixel
;
796 shift_width
= bytes_per_sample
+ 1;
799 tile_buffsize
= tilesize
;
801 if (tilesize
< (tsize_t
)(tl
* tile_rowsize
))
804 TIFFError("readContigTilesIntoBuffer",
805 "Tilesize %lu is too small, using alternate calculation %u",
806 tilesize
, tl
* tile_rowsize
);
808 tile_buffsize
= tl
* tile_rowsize
;
811 tilebuf
= _TIFFmalloc(tile_buffsize
);
815 dst_rowsize
= ((imagewidth
* bps
* spp
) + 7) / 8;
816 for (row
= 0; row
< imagelength
; row
+= tl
)
818 nrow
= (row
+ tl
> imagelength
) ? imagelength
- row
: tl
;
819 for (col
= 0; col
< imagewidth
; col
+= tw
)
821 tbytes
= TIFFReadTile(in
, tilebuf
, col
, row
, 0, 0);
822 if (tbytes
< tilesize
&& !ignore
)
824 TIFFError(TIFFFileName(in
),
825 "Error, can't read tile at row %lu col %lu, Read %lu bytes of %lu",
826 (unsigned long) col
, (unsigned long) row
, (unsigned long)tbytes
,
827 (unsigned long)tilesize
);
833 row_offset
= row
* dst_rowsize
;
834 col_offset
= ((col
* bps
* spp
) + 7)/ 8;
835 bufp
= buf
+ row_offset
+ col_offset
;
837 if (col
+ tw
> imagewidth
)
838 ncol
= imagewidth
- col
;
842 /* Each tile scanline will start on a byte boundary but it
843 * has to be merged into the scanline for the entire
844 * image buffer and the previous segment may not have
845 * ended on a byte boundary
847 /* Optimization for common bit depths, all samples */
848 if (((bps
% 8) == 0) && (count
== spp
))
850 for (trow
= 0; trow
< nrow
; trow
++)
852 src_offset
= trow
* tile_rowsize
;
853 _TIFFmemcpy (bufp
, tilebuf
+ src_offset
, (ncol
* spp
* bps
) / 8);
854 bufp
+= (imagewidth
* bps
* spp
) / 8;
859 /* Bit depths not a multiple of 8 and/or extract fewer than spp samples */
860 prev_trailing_bits
= trailing_bits
= 0;
861 trailing_bits
= (ncol
* bps
* spp
) % 8;
863 /* for (trow = 0; tl < nrow; trow++) */
864 for (trow
= 0; trow
< nrow
; trow
++)
866 src_offset
= trow
* tile_rowsize
;
867 src
= tilebuf
+ src_offset
;
868 dst_offset
= (row
+ trow
) * dst_rowsize
;
869 dst
= buf
+ dst_offset
+ col_offset
;
872 case 0: if (extractContigSamplesBytes (src
, dst
, ncol
, sample
,
873 spp
, bps
, count
, 0, ncol
))
875 TIFFError("readContigTilesIntoBuffer",
876 "Unable to extract row %d from tile %lu",
877 row
, (unsigned long)TIFFCurrentTile(in
));
881 case 1: if (bps
== 1)
883 if (extractContigSamplesShifted8bits (src
, dst
, ncol
,
889 TIFFError("readContigTilesIntoBuffer",
890 "Unable to extract row %d from tile %lu",
891 row
, (unsigned long)TIFFCurrentTile(in
));
897 if (extractContigSamplesShifted16bits (src
, dst
, ncol
,
903 TIFFError("readContigTilesIntoBuffer",
904 "Unable to extract row %d from tile %lu",
905 row
, (unsigned long)TIFFCurrentTile(in
));
909 case 2: if (extractContigSamplesShifted24bits (src
, dst
, ncol
,
915 TIFFError("readContigTilesIntoBuffer",
916 "Unable to extract row %d from tile %lu",
917 row
, (unsigned long)TIFFCurrentTile(in
));
923 case 5: if (extractContigSamplesShifted32bits (src
, dst
, ncol
,
929 TIFFError("readContigTilesIntoBuffer",
930 "Unable to extract row %d from tile %lu",
931 row
, (unsigned long)TIFFCurrentTile(in
));
935 default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %d", bps
);
939 prev_trailing_bits
+= trailing_bits
;
940 if (prev_trailing_bits
> 7)
941 prev_trailing_bits
-= 8;
950 static int readSeparateTilesIntoBuffer (TIFF
* in
, uint8
*obuf
,
951 uint32 imagelength
, uint32 imagewidth
,
952 uint32 tw
, uint32 tl
,
953 uint16 spp
, uint16 bps
)
955 int i
, status
= 1, sample
;
956 int shift_width
, bytes_per_pixel
;
957 uint16 bytes_per_sample
;
958 uint32 row
, col
; /* Current row and col of image */
959 uint32 nrow
, ncol
; /* Number of rows and cols in current tile */
960 uint32 row_offset
, col_offset
; /* Output buffer offsets */
961 tsize_t tbytes
= 0, tilesize
= TIFFTileSize(in
);
963 uint8
* bufp
= (uint8
*)obuf
;
964 unsigned char *srcbuffs
[MAX_SAMPLES
];
965 unsigned char *tbuff
= NULL
;
967 bytes_per_sample
= (bps
+ 7) / 8;
969 for (sample
= 0; (sample
< spp
) && (sample
< MAX_SAMPLES
); sample
++)
971 srcbuffs
[sample
] = NULL
;
972 tbuff
= (unsigned char *)_TIFFmalloc(tilesize
+ 8);
975 TIFFError ("readSeparateTilesIntoBuffer",
976 "Unable to allocate tile read buffer for sample %d", sample
);
977 for (i
= 0; i
< sample
; i
++)
978 _TIFFfree (srcbuffs
[i
]);
981 srcbuffs
[sample
] = tbuff
;
983 /* Each tile contains only the data for a single plane
984 * arranged in scanlines of tw * bytes_per_sample bytes.
986 for (row
= 0; row
< imagelength
; row
+= tl
)
988 nrow
= (row
+ tl
> imagelength
) ? imagelength
- row
: tl
;
989 for (col
= 0; col
< imagewidth
; col
+= tw
)
991 for (s
= 0; s
< spp
; s
++)
992 { /* Read each plane of a tile set into srcbuffs[s] */
993 tbytes
= TIFFReadTile(in
, srcbuffs
[s
], col
, row
, 0, s
);
994 if (tbytes
< 0 && !ignore
)
996 TIFFError(TIFFFileName(in
),
997 "Error, can't read tile for row %lu col %lu, "
999 (unsigned long) col
, (unsigned long) row
,
1002 for (sample
= 0; (sample
< spp
) && (sample
< MAX_SAMPLES
); sample
++)
1004 tbuff
= srcbuffs
[sample
];
1011 /* Tiles on the right edge may be padded out to tw
1012 * which must be a multiple of 16.
1013 * Ncol represents the visible (non padding) portion.
1015 if (col
+ tw
> imagewidth
)
1016 ncol
= imagewidth
- col
;
1020 row_offset
= row
* (((imagewidth
* spp
* bps
) + 7) / 8);
1021 col_offset
= ((col
* spp
* bps
) + 7) / 8;
1022 bufp
= obuf
+ row_offset
+ col_offset
;
1026 if (combineSeparateTileSamplesBytes(srcbuffs
, bufp
, ncol
, nrow
, imagewidth
,
1027 tw
, spp
, bps
, NULL
, 0, 0))
1035 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
1036 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
1037 shift_width
= bytes_per_pixel
;
1039 shift_width
= bytes_per_sample
+ 1;
1041 switch (shift_width
)
1043 case 1: if (combineSeparateTileSamples8bits (srcbuffs
, bufp
, ncol
, nrow
,
1044 imagewidth
, tw
, spp
, bps
,
1051 case 2: if (combineSeparateTileSamples16bits (srcbuffs
, bufp
, ncol
, nrow
,
1052 imagewidth
, tw
, spp
, bps
,
1059 case 3: if (combineSeparateTileSamples24bits (srcbuffs
, bufp
, ncol
, nrow
,
1060 imagewidth
, tw
, spp
, bps
,
1071 case 8: if (combineSeparateTileSamples32bits (srcbuffs
, bufp
, ncol
, nrow
,
1072 imagewidth
, tw
, spp
, bps
,
1079 default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps
);
1087 for (sample
= 0; (sample
< spp
) && (sample
< MAX_SAMPLES
); sample
++)
1089 tbuff
= srcbuffs
[sample
];
1097 static int writeBufferToContigStrips(TIFF
* out
, uint8
* buf
, uint32 imagelength
)
1099 uint32 row
, nrows
, rowsperstrip
;
1103 TIFFGetFieldDefaulted(out
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
1104 for (row
= 0; row
< imagelength
; row
+= rowsperstrip
)
1106 nrows
= (row
+ rowsperstrip
> imagelength
) ?
1107 imagelength
- row
: rowsperstrip
;
1108 stripsize
= TIFFVStripSize(out
, nrows
);
1109 if (TIFFWriteEncodedStrip(out
, strip
++, buf
, stripsize
) < 0)
1111 TIFFError(TIFFFileName(out
), "Error, can't write strip %u", strip
- 1);
1120 /* Abandon plans to modify code so that plannar orientation separate images
1121 * do not have all samples for each channel written before all samples
1122 * for the next channel have been abandoned.
1123 * Libtiff internals seem to depend on all data for a given sample
1124 * being contiguous within a strip or tile when PLANAR_CONFIG is
1125 * separate. All strips or tiles of a given plane are written
1126 * before any strips or tiles of a different plane are stored.
1129 writeBufferToSeparateStrips (TIFF
* out
, uint8
* buf
,
1130 uint32 length
, uint32 width
, uint16 spp
,
1131 struct dump_opts
*dump
)
1135 uint32 row
, nrows
, rowsize
, rowsperstrip
;
1136 uint32 bytes_per_sample
;
1139 tsize_t stripsize
= TIFFStripSize(out
);
1140 tsize_t rowstripsize
, scanlinesize
= TIFFScanlineSize(out
);
1141 tsize_t total_bytes
= 0;
1144 (void) TIFFGetFieldDefaulted(out
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
1145 (void) TIFFGetField(out
, TIFFTAG_BITSPERSAMPLE
, &bps
);
1146 bytes_per_sample
= (bps
+ 7) / 8;
1147 rowsize
= ((bps
* spp
* width
) + 7) / 8; /* source has interleaved samples */
1148 rowstripsize
= rowsperstrip
* bytes_per_sample
* (width
+ 1);
1150 obuf
= _TIFFmalloc (rowstripsize
);
1154 for (s
= 0; s
< spp
; s
++)
1156 for (row
= 0; row
< length
; row
+= rowsperstrip
)
1158 nrows
= (row
+ rowsperstrip
> length
) ? length
- row
: rowsperstrip
;
1160 stripsize
= TIFFVStripSize(out
, nrows
);
1161 src
= buf
+ (row
* rowsize
);
1162 total_bytes
+= stripsize
;
1163 memset (obuf
, '\0', rowstripsize
);
1164 if (extractContigSamplesToBuffer(obuf
, src
, nrows
, width
, s
, spp
, bps
, dump
))
1169 if ((dump
->outfile
!= NULL
) && (dump
->level
== 1))
1171 dump_info(dump
->outfile
, dump
->format
,"",
1172 "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d",
1173 s
+ 1, strip
+ 1, stripsize
, row
+ 1, scanlinesize
, src
- buf
);
1174 dump_buffer(dump
->outfile
, dump
->format
, nrows
, scanlinesize
, row
, obuf
);
1177 if (TIFFWriteEncodedStrip(out
, strip
++, obuf
, stripsize
) < 0)
1179 TIFFError(TIFFFileName(out
), "Error, can't write strip %u", strip
- 1);
1190 /* Extract all planes from contiguous buffer into a single tile buffer
1191 * to be written out as a tile.
1193 static int writeBufferToContigTiles (TIFF
* out
, uint8
* buf
, uint32 imagelength
,
1194 uint32 imagewidth
, tsample_t spp
,
1195 struct dump_opts
* dump
)
1199 uint32 row
, col
, nrow
, ncol
;
1200 uint32 src_rowsize
, col_offset
;
1201 uint32 tile_rowsize
= TIFFTileRowSize(out
);
1202 uint8
* bufp
= (uint8
*) buf
;
1203 tsize_t tile_buffsize
= 0;
1204 tsize_t tilesize
= TIFFTileSize(out
);
1205 unsigned char *tilebuf
= NULL
;
1207 TIFFGetField(out
, TIFFTAG_TILELENGTH
, &tl
);
1208 TIFFGetField(out
, TIFFTAG_TILEWIDTH
, &tw
);
1209 TIFFGetField(out
, TIFFTAG_BITSPERSAMPLE
, &bps
);
1211 tile_buffsize
= tilesize
;
1212 if (tilesize
< (tsize_t
)(tl
* tile_rowsize
))
1215 TIFFError("writeBufferToContigTiles",
1216 "Tilesize %lu is too small, using alternate calculation %u",
1217 tilesize
, tl
* tile_rowsize
);
1219 tile_buffsize
= tl
* tile_rowsize
;
1222 tilebuf
= _TIFFmalloc(tile_buffsize
);
1226 src_rowsize
= ((imagewidth
* spp
* bps
) + 7) / 8;
1227 for (row
= 0; row
< imagelength
; row
+= tl
)
1229 nrow
= (row
+ tl
> imagelength
) ? imagelength
- row
: tl
;
1230 for (col
= 0; col
< imagewidth
; col
+= tw
)
1232 /* Calculate visible portion of tile. */
1233 if (col
+ tw
> imagewidth
)
1234 ncol
= imagewidth
- col
;
1238 col_offset
= (((col
* bps
* spp
) + 7) / 8);
1239 bufp
= buf
+ (row
* src_rowsize
) + col_offset
;
1240 if (extractContigSamplesToTileBuffer(tilebuf
, bufp
, nrow
, ncol
, imagewidth
,
1241 tw
, 0, spp
, spp
, bps
, dump
) > 0)
1243 TIFFError("writeBufferToContigTiles",
1244 "Unable to extract data to tile for row %lu, col %lu",
1245 (unsigned long) row
, (unsigned long)col
);
1250 if (TIFFWriteTile(out
, tilebuf
, col
, row
, 0, 0) < 0)
1252 TIFFError("writeBufferToContigTiles",
1253 "Cannot write tile at %lu %lu",
1254 (unsigned long) col
, (unsigned long) row
);
1263 } /* end writeBufferToContigTiles */
1265 /* Extract each plane from contiguous buffer into a single tile buffer
1266 * to be written out as a tile.
1268 static int writeBufferToSeparateTiles (TIFF
* out
, uint8
* buf
, uint32 imagelength
,
1269 uint32 imagewidth
, tsample_t spp
,
1270 struct dump_opts
* dump
)
1272 tdata_t obuf
= _TIFFmalloc(TIFFTileSize(out
));
1274 uint32 row
, col
, nrow
, ncol
;
1275 uint32 src_rowsize
, col_offset
;
1278 uint8
* bufp
= (uint8
*) buf
;
1283 TIFFGetField(out
, TIFFTAG_TILELENGTH
, &tl
);
1284 TIFFGetField(out
, TIFFTAG_TILEWIDTH
, &tw
);
1285 TIFFGetField(out
, TIFFTAG_BITSPERSAMPLE
, &bps
);
1286 src_rowsize
= ((imagewidth
* spp
* bps
) + 7) / 8;
1288 for (row
= 0; row
< imagelength
; row
+= tl
)
1290 nrow
= (row
+ tl
> imagelength
) ? imagelength
- row
: tl
;
1291 for (col
= 0; col
< imagewidth
; col
+= tw
)
1293 /* Calculate visible portion of tile. */
1294 if (col
+ tw
> imagewidth
)
1295 ncol
= imagewidth
- col
;
1299 col_offset
= (((col
* bps
* spp
) + 7) / 8);
1300 bufp
= buf
+ (row
* src_rowsize
) + col_offset
;
1302 for (s
= 0; s
< spp
; s
++)
1304 if (extractContigSamplesToTileBuffer(obuf
, bufp
, nrow
, ncol
, imagewidth
,
1305 tw
, s
, 1, spp
, bps
, dump
) > 0)
1307 TIFFError("writeBufferToSeparateTiles",
1308 "Unable to extract data to tile for row %lu, col %lu sample %d",
1309 (unsigned long) row
, (unsigned long)col
, (int)s
);
1314 if (TIFFWriteTile(out
, obuf
, col
, row
, 0, s
) < 0)
1316 TIFFError("writeBufferToseparateTiles",
1317 "Cannot write tile at %lu %lu sample %lu",
1318 (unsigned long) col
, (unsigned long) row
,
1329 } /* end writeBufferToSeparateTiles */
1332 processG3Options(char* cp
)
1334 if( (cp
= strchr(cp
, ':')) ) {
1335 if (defg3opts
== (uint32
) -1)
1339 if (strneq(cp
, "1d", 2))
1340 defg3opts
&= ~GROUP3OPT_2DENCODING
;
1341 else if (strneq(cp
, "2d", 2))
1342 defg3opts
|= GROUP3OPT_2DENCODING
;
1343 else if (strneq(cp
, "fill", 4))
1344 defg3opts
|= GROUP3OPT_FILLBITS
;
1347 } while( (cp
= strchr(cp
, ':')) );
1352 processCompressOptions(char* opt
)
1356 if (strneq(opt
, "none",4))
1358 defcompression
= COMPRESSION_NONE
;
1360 else if (streq(opt
, "packbits"))
1362 defcompression
= COMPRESSION_PACKBITS
;
1364 else if (strneq(opt
, "jpeg", 4))
1366 cp
= strchr(opt
, ':');
1367 defcompression
= COMPRESSION_JPEG
;
1371 if (isdigit((int)cp
[1]))
1372 quality
= atoi(cp
+ 1);
1373 else if (strneq(cp
+ 1, "raw", 3 ))
1374 jpegcolormode
= JPEGCOLORMODE_RAW
;
1375 else if (strneq(cp
+ 1, "rgb", 3 ))
1376 jpegcolormode
= JPEGCOLORMODE_RGB
;
1379 cp
= strchr(cp
+ 1, ':');
1382 else if (strneq(opt
, "g3", 2))
1384 processG3Options(opt
);
1385 defcompression
= COMPRESSION_CCITTFAX3
;
1387 else if (streq(opt
, "g4"))
1389 defcompression
= COMPRESSION_CCITTFAX4
;
1391 else if (strneq(opt
, "lzw", 3))
1393 cp
= strchr(opt
, ':');
1395 defpredictor
= atoi(cp
+1);
1396 defcompression
= COMPRESSION_LZW
;
1398 else if (strneq(opt
, "zip", 3))
1400 cp
= strchr(opt
, ':');
1402 defpredictor
= atoi(cp
+1);
1403 defcompression
= COMPRESSION_ADOBE_DEFLATE
;
1416 fprintf(stderr
, "\n%s\n", TIFFGetVersion());
1417 for (i
= 0; usage_info
[i
] != NULL
; i
++)
1418 fprintf(stderr
, "%s\n", usage_info
[i
]);
1422 #define CopyField(tag, v) \
1423 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
1424 #define CopyField2(tag, v1, v2) \
1425 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
1426 #define CopyField3(tag, v1, v2, v3) \
1427 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
1428 #define CopyField4(tag, v1, v2, v3, v4) \
1429 if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
1432 cpTag(TIFF
* in
, TIFF
* out
, uint16 tag
, uint16 count
, TIFFDataType type
)
1438 CopyField(tag
, shortv
);
1439 } else if (count
== 2) {
1440 uint16 shortv1
, shortv2
;
1441 CopyField2(tag
, shortv1
, shortv2
);
1442 } else if (count
== 4) {
1443 uint16
*tr
, *tg
, *tb
, *ta
;
1444 CopyField4(tag
, tr
, tg
, tb
, ta
);
1445 } else if (count
== (uint16
) -1) {
1448 CopyField2(tag
, shortv1
, shortav
);
1453 CopyField(tag
, longv
);
1459 CopyField(tag
, floatv
);
1460 } else if (count
== (uint16
) -1) {
1462 CopyField(tag
, floatav
);
1467 CopyField(tag
, stringv
);
1473 CopyField(tag
, doublev
);
1474 } else if (count
== (uint16
) -1) {
1476 CopyField(tag
, doubleav
);
1480 TIFFError(TIFFFileName(in
),
1481 "Data type %d is not supported, tag %d skipped",
1486 static struct cpTag
{
1491 { TIFFTAG_SUBFILETYPE
, 1, TIFF_LONG
},
1492 { TIFFTAG_THRESHHOLDING
, 1, TIFF_SHORT
},
1493 { TIFFTAG_DOCUMENTNAME
, 1, TIFF_ASCII
},
1494 { TIFFTAG_IMAGEDESCRIPTION
, 1, TIFF_ASCII
},
1495 { TIFFTAG_MAKE
, 1, TIFF_ASCII
},
1496 { TIFFTAG_MODEL
, 1, TIFF_ASCII
},
1497 { TIFFTAG_MINSAMPLEVALUE
, 1, TIFF_SHORT
},
1498 { TIFFTAG_MAXSAMPLEVALUE
, 1, TIFF_SHORT
},
1499 { TIFFTAG_XRESOLUTION
, 1, TIFF_RATIONAL
},
1500 { TIFFTAG_YRESOLUTION
, 1, TIFF_RATIONAL
},
1501 { TIFFTAG_PAGENAME
, 1, TIFF_ASCII
},
1502 { TIFFTAG_XPOSITION
, 1, TIFF_RATIONAL
},
1503 { TIFFTAG_YPOSITION
, 1, TIFF_RATIONAL
},
1504 { TIFFTAG_RESOLUTIONUNIT
, 1, TIFF_SHORT
},
1505 { TIFFTAG_SOFTWARE
, 1, TIFF_ASCII
},
1506 { TIFFTAG_DATETIME
, 1, TIFF_ASCII
},
1507 { TIFFTAG_ARTIST
, 1, TIFF_ASCII
},
1508 { TIFFTAG_HOSTCOMPUTER
, 1, TIFF_ASCII
},
1509 { TIFFTAG_WHITEPOINT
, (uint16
) -1, TIFF_RATIONAL
},
1510 { TIFFTAG_PRIMARYCHROMATICITIES
,(uint16
) -1,TIFF_RATIONAL
},
1511 { TIFFTAG_HALFTONEHINTS
, 2, TIFF_SHORT
},
1512 { TIFFTAG_INKSET
, 1, TIFF_SHORT
},
1513 { TIFFTAG_DOTRANGE
, 2, TIFF_SHORT
},
1514 { TIFFTAG_TARGETPRINTER
, 1, TIFF_ASCII
},
1515 { TIFFTAG_SAMPLEFORMAT
, 1, TIFF_SHORT
},
1516 { TIFFTAG_YCBCRCOEFFICIENTS
, (uint16
) -1,TIFF_RATIONAL
},
1517 { TIFFTAG_YCBCRSUBSAMPLING
, 2, TIFF_SHORT
},
1518 { TIFFTAG_YCBCRPOSITIONING
, 1, TIFF_SHORT
},
1519 { TIFFTAG_REFERENCEBLACKWHITE
, (uint16
) -1,TIFF_RATIONAL
},
1520 { TIFFTAG_EXTRASAMPLES
, (uint16
) -1, TIFF_SHORT
},
1521 { TIFFTAG_SMINSAMPLEVALUE
, 1, TIFF_DOUBLE
},
1522 { TIFFTAG_SMAXSAMPLEVALUE
, 1, TIFF_DOUBLE
},
1523 { TIFFTAG_STONITS
, 1, TIFF_DOUBLE
},
1525 #define NTAGS (sizeof (tags) / sizeof (tags[0]))
1527 #define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
1529 /* Functions written by Richard Nolde, with exceptions noted. */
1530 void process_command_opts (int argc
, char *argv
[], char *mp
, char *mode
, uint32
*dirnum
,
1531 uint16
*defconfig
, uint16
*deffillorder
, uint32
*deftilewidth
,
1532 uint32
*deftilelength
, uint32
*defrowsperstrip
,
1533 struct crop_mask
*crop_data
, struct pagedef
*page
,
1534 struct dump_opts
*dump
,
1535 unsigned int *imagelist
, unsigned int *image_count
)
1537 int c
, good_args
= 0;
1538 char *opt_offset
= NULL
; /* Position in string of value sought */
1539 char *opt_ptr
= NULL
; /* Pointer to next token in option set */
1540 char *sep
= NULL
; /* Pointer to a token separator */
1541 unsigned int i
, j
, start
, end
;
1543 extern char* optarg
;
1547 while ((c
= getopt(argc
, argv
,
1548 "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)
1552 case 'a': mode
[0] = 'a'; /* append to output */
1554 case 'c': if (!processCompressOptions(optarg
)) /* compression scheme */
1556 TIFFError ("Unknown compression option", "%s", optarg
);
1557 TIFFError ("For valid options type", "tiffcrop -h");
1561 case 'd': start
= strtoul(optarg
, NULL
, 0); /* initial IFD offset */
1564 TIFFError ("","Directory offset must be greater than zero");
1565 TIFFError ("For valid options type", "tiffcrop -h");
1568 *dirnum
= start
- 1;
1570 case 'e': switch (tolower(optarg
[0])) /* image export modes*/
1572 case 'c': crop_data
->exp_mode
= ONE_FILE_COMPOSITE
;
1573 crop_data
->img_mode
= COMPOSITE_IMAGES
;
1574 break; /* Composite */
1575 case 'd': crop_data
->exp_mode
= ONE_FILE_SEPARATED
;
1576 crop_data
->img_mode
= SEPARATED_IMAGES
;
1577 break; /* Divided */
1578 case 'i': crop_data
->exp_mode
= FILE_PER_IMAGE_COMPOSITE
;
1579 crop_data
->img_mode
= COMPOSITE_IMAGES
;
1581 case 'm': crop_data
->exp_mode
= FILE_PER_IMAGE_SEPARATED
;
1582 crop_data
->img_mode
= SEPARATED_IMAGES
;
1583 break; /* Multiple */
1584 case 's': crop_data
->exp_mode
= FILE_PER_SELECTION
;
1585 crop_data
->img_mode
= SEPARATED_IMAGES
;
1586 break; /* Sections */
1587 default: TIFFError ("Unknown export mode","%s", optarg
);
1588 TIFFError ("For valid options type", "tiffcrop -h");
1592 case 'f': if (streq(optarg
, "lsb2msb")) /* fill order */
1593 *deffillorder
= FILLORDER_LSB2MSB
;
1594 else if (streq(optarg
, "msb2lsb"))
1595 *deffillorder
= FILLORDER_MSB2LSB
;
1598 TIFFError ("Unknown fill order", "%s", optarg
);
1599 TIFFError ("For valid options type", "tiffcrop -h");
1605 case 'i': ignore
= TRUE
; /* ignore errors */
1607 case 'l': outtiled
= TRUE
; /* tile length */
1608 *deftilelength
= atoi(optarg
);
1610 case 'p': /* planar configuration */
1611 if (streq(optarg
, "separate"))
1612 *defconfig
= PLANARCONFIG_SEPARATE
;
1613 else if (streq(optarg
, "contig"))
1614 *defconfig
= PLANARCONFIG_CONTIG
;
1617 TIFFError ("Unkown planar configuration", "%s", optarg
);
1618 TIFFError ("For valid options type", "tiffcrop -h");
1622 case 'r': /* rows/strip */
1623 *defrowsperstrip
= atol(optarg
);
1625 case 's': /* generate stripped output */
1628 case 't': /* generate tiled output */
1631 case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
1632 TIFFError ("Tiffcrop version", "%s, last updated: %s",
1633 tiffcrop_version_id
, tiffcrop_rev_date
);
1634 TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
1635 TIFFError (" ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
1636 TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
1639 case 'w': /* tile width */
1641 *deftilewidth
= atoi(optarg
);
1643 case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
1644 crop_data
->crop_mode
|= CROP_REGIONS
;
1645 for (i
= 0, opt_ptr
= strtok (optarg
, ":");
1646 ((opt_ptr
!= NULL
) && (i
< MAX_REGIONS
));
1647 (opt_ptr
= strtok (NULL
, ":")), i
++)
1649 crop_data
->regions
++;
1650 if (sscanf(opt_ptr
, "%lf,%lf,%lf,%lf",
1651 &crop_data
->corners
[i
].X1
, &crop_data
->corners
[i
].Y1
,
1652 &crop_data
->corners
[i
].X2
, &crop_data
->corners
[i
].Y2
) != 4)
1654 TIFFError ("Unable to parse coordinates for region", "%d %s", i
, optarg
);
1655 TIFFError ("For valid options type", "tiffcrop -h");
1659 /* check for remaining elements over MAX_REGIONS */
1660 if ((opt_ptr
!= NULL
) && (i
>= MAX_REGIONS
))
1662 TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS
, optarg
);
1663 TIFFError ("For valid options type", "tiffcrop -h");
1667 /* options for file open modes */
1668 case 'B': *mp
++ = 'b'; *mp
= '\0';
1670 case 'L': *mp
++ = 'l'; *mp
= '\0';
1672 case 'M': *mp
++ = 'm'; *mp
= '\0';
1674 case 'C': *mp
++ = 'c'; *mp
= '\0';
1676 /* options for Debugging / data dump */
1677 case 'D': for (i
= 0, opt_ptr
= strtok (optarg
, ",");
1679 (opt_ptr
= strtok (NULL
, ",")), i
++)
1681 opt_offset
= strpbrk(opt_ptr
, ":=");
1682 if (opt_offset
== NULL
)
1684 TIFFError("Invalid dump option", "%s", optarg
);
1685 TIFFError ("For valid options type", "tiffcrop -h");
1690 /* convert option to lowercase */
1691 end
= strlen (opt_ptr
);
1692 for (i
= 0; i
< end
; i
++)
1693 *(opt_ptr
+ i
) = tolower(*(opt_ptr
+ i
));
1694 /* Look for dump format specification */
1695 if (strncmp(opt_ptr
, "for", 3) == 0)
1697 /* convert value to lowercase */
1698 end
= strlen (opt_offset
+ 1);
1699 for (i
= 1; i
<= end
; i
++)
1700 *(opt_offset
+ i
) = tolower(*(opt_offset
+ i
));
1701 /* check dump format value */
1702 if (strncmp (opt_offset
+ 1, "txt", 3) == 0)
1704 dump
->format
= DUMP_TEXT
;
1705 strcpy (dump
->mode
, "w");
1709 if (strncmp(opt_offset
+ 1, "raw", 3) == 0)
1711 dump
->format
= DUMP_RAW
;
1712 strcpy (dump
->mode
, "wb");
1716 TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset
+ 1);
1717 TIFFError ("For valid options type", "tiffcrop -h");
1723 { /* Look for dump level specification */
1724 if (strncmp (opt_ptr
, "lev", 3) == 0)
1725 dump
->level
= atoi(opt_offset
+ 1);
1726 /* Look for input data dump file name */
1727 if (strncmp (opt_ptr
, "in", 2) == 0)
1729 strncpy (dump
->infilename
, opt_offset
+ 1, PATH_MAX
- 20);
1730 dump
->infilename
[PATH_MAX
- 20] = '\0';
1732 /* Look for output data dump file name */
1733 if (strncmp (opt_ptr
, "out", 3) == 0)
1735 strncpy (dump
->outfilename
, opt_offset
+ 1, PATH_MAX
- 20);
1736 dump
->outfilename
[PATH_MAX
- 20] = '\0';
1738 if (strncmp (opt_ptr
, "deb", 3) == 0)
1739 dump
->debug
= atoi(opt_offset
+ 1);
1742 if ((strlen(dump
->infilename
)) || (strlen(dump
->outfilename
)))
1744 if (dump
->level
== 1)
1745 TIFFError("","Defaulting to dump level 1, no data.");
1746 if (dump
->format
== DUMP_NONE
)
1748 TIFFError("", "You must specify a dump format for dump files");
1749 TIFFError ("For valid options type", "tiffcrop -h");
1755 /* image manipulation routine options */
1756 case 'm': /* margins to exclude from selection, uppercase M was already used */
1757 /* order of values must be TOP, LEFT, BOTTOM, RIGHT */
1758 crop_data
->crop_mode
|= CROP_MARGINS
;
1759 for (i
= 0, opt_ptr
= strtok (optarg
, ",:");
1760 ((opt_ptr
!= NULL
) && (i
< 4));
1761 (opt_ptr
= strtok (NULL
, ",:")), i
++)
1763 crop_data
->margins
[i
] = atof(opt_ptr
);
1766 case 'E': /* edge reference */
1767 switch (tolower(optarg
[0]))
1769 case 't': crop_data
->edge_ref
= EDGE_TOP
;
1771 case 'b': crop_data
->edge_ref
= EDGE_BOTTOM
;
1773 case 'l': crop_data
->edge_ref
= EDGE_LEFT
;
1775 case 'r': crop_data
->edge_ref
= EDGE_RIGHT
;
1777 default: TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg
);
1778 TIFFError ("For valid options type", "tiffcrop -h");
1782 case 'F': /* flip eg mirror image or cropped segment, M was already used */
1783 crop_data
->crop_mode
|= CROP_MIRROR
;
1784 switch (tolower(optarg
[0]))
1786 case 'h': crop_data
->mirror
= MIRROR_HORIZ
;
1788 case 'v': crop_data
->mirror
= MIRROR_VERT
;
1790 case 'b': crop_data
->mirror
= MIRROR_BOTH
;
1792 default: TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg
);
1793 TIFFError ("For valid options type", "tiffcrop -h");
1797 case 'H': /* set horizontal resolution to new value */
1798 page
->hres
= atof (optarg
);
1799 page
->mode
|= PAGE_MODE_RESOLUTION
;
1801 case 'I': /* invert the color space, eg black to white */
1802 crop_data
->crop_mode
|= CROP_INVERT
;
1803 /* The PHOTOMETIC_INTERPRETATION tag may be updated */
1804 if (streq(optarg
, "black"))
1806 crop_data
->photometric
= PHOTOMETRIC_MINISBLACK
;
1809 if (streq(optarg
, "white"))
1811 crop_data
->photometric
= PHOTOMETRIC_MINISWHITE
;
1814 if (streq(optarg
, "data"))
1816 crop_data
->photometric
= INVERT_DATA_ONLY
;
1819 if (streq(optarg
, "both"))
1821 crop_data
->photometric
= INVERT_DATA_AND_TAG
;
1825 TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg
);
1826 TIFFError ("For valid options type", "tiffcrop -h");
1829 case 'J': /* horizontal margin for sectioned ouput pages */
1830 page
->hmargin
= atof(optarg
);
1831 page
->mode
|= PAGE_MODE_MARGINS
;
1833 case 'K': /* vertical margin for sectioned ouput pages*/
1834 page
->vmargin
= atof(optarg
);
1835 page
->mode
|= PAGE_MODE_MARGINS
;
1837 case 'N': /* list of images to process */
1838 for (i
= 0, opt_ptr
= strtok (optarg
, ",");
1839 ((opt_ptr
!= NULL
) && (i
< MAX_IMAGES
));
1840 (opt_ptr
= strtok (NULL
, ",")))
1841 { /* We do not know how many images are in file yet
1842 * so we build a list to include the maximum allowed
1843 * and follow it until we hit the end of the file.
1844 * Image count is not accurate for odd, even, last
1845 * so page numbers won't be valid either.
1847 if (streq(opt_ptr
, "odd"))
1849 for (j
= 1; j
<= MAX_IMAGES
; j
+= 2)
1851 *image_count
= (MAX_IMAGES
- 1) / 2;
1856 if (streq(opt_ptr
, "even"))
1858 for (j
= 2; j
<= MAX_IMAGES
; j
+= 2)
1860 *image_count
= MAX_IMAGES
/ 2;
1865 if (streq(opt_ptr
, "last"))
1866 imagelist
[i
++] = MAX_IMAGES
;
1867 else /* single value between commas */
1869 sep
= strpbrk(opt_ptr
, ":-");
1871 imagelist
[i
++] = atoi(opt_ptr
);
1875 start
= atoi (opt_ptr
);
1876 if (!strcmp((sep
+ 1), "last"))
1879 end
= atoi (sep
+ 1);
1880 for (j
= start
; j
<= end
&& j
- start
+ i
< MAX_IMAGES
; j
++)
1889 case 'O': /* page orientation */
1890 switch (tolower(optarg
[0]))
1892 case 'a': page
->orient
= ORIENTATION_AUTO
;
1894 case 'p': page
->orient
= ORIENTATION_PORTRAIT
;
1896 case 'l': page
->orient
= ORIENTATION_LANDSCAPE
;
1898 default: TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg
);
1899 TIFFError ("For valid options type", "tiffcrop -h");
1903 case 'P': /* page size selection */
1904 if (sscanf(optarg
, "%lfx%lf", &page
->width
, &page
->length
) == 2)
1906 strcpy (page
->name
, "Custom");
1907 page
->mode
|= PAGE_MODE_PAPERSIZE
;
1910 if (get_page_geometry (optarg
, page
))
1912 if (!strcmp(optarg
, "list"))
1914 TIFFError("", "Name Width Length (in inches)");
1915 for (i
= 0; i
< MAX_PAPERNAMES
- 1; i
++)
1916 TIFFError ("", "%-15.15s %5.2f %5.2f",
1917 PaperTable
[i
].name
, PaperTable
[i
].width
,
1918 PaperTable
[i
].length
);
1922 TIFFError ("Invalid paper size", "%s", optarg
);
1923 TIFFError ("", "Select one of:");
1924 TIFFError("", "Name Width Length (in inches)");
1925 for (i
= 0; i
< MAX_PAPERNAMES
- 1; i
++)
1926 TIFFError ("", "%-15.15s %5.2f %5.2f",
1927 PaperTable
[i
].name
, PaperTable
[i
].width
,
1928 PaperTable
[i
].length
);
1933 page
->mode
|= PAGE_MODE_PAPERSIZE
;
1936 case 'R': /* rotate image or cropped segment */
1937 crop_data
->crop_mode
|= CROP_ROTATE
;
1938 switch (strtoul(optarg
, NULL
, 0))
1940 case 90: crop_data
->rotation
= (uint16
)90;
1942 case 180: crop_data
->rotation
= (uint16
)180;
1944 case 270: crop_data
->rotation
= (uint16
)270;
1946 default: TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg
);
1947 TIFFError ("For valid options type", "tiffcrop -h");
1951 case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
1952 sep
= strpbrk(optarg
, ",:");
1956 page
->cols
= atoi(optarg
);
1957 page
->rows
= atoi(sep
+1);
1961 page
->cols
= atoi(optarg
);
1962 page
->rows
= atoi(optarg
);
1964 if ((page
->cols
* page
->rows
) > MAX_SECTIONS
)
1966 TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS
);
1969 page
->mode
|= PAGE_MODE_ROWSCOLS
;
1971 case 'U': /* units for measurements and offsets */
1972 if (streq(optarg
, "in"))
1974 crop_data
->res_unit
= RESUNIT_INCH
;
1975 page
->res_unit
= RESUNIT_INCH
;
1977 else if (streq(optarg
, "cm"))
1979 crop_data
->res_unit
= RESUNIT_CENTIMETER
;
1980 page
->res_unit
= RESUNIT_CENTIMETER
;
1982 else if (streq(optarg
, "px"))
1984 crop_data
->res_unit
= RESUNIT_NONE
;
1985 page
->res_unit
= RESUNIT_NONE
;
1989 TIFFError ("Illegal unit of measure","%s", optarg
);
1990 TIFFError ("For valid options type", "tiffcrop -h");
1994 case 'V': /* set vertical resolution to new value */
1995 page
->vres
= atof (optarg
);
1996 page
->mode
|= PAGE_MODE_RESOLUTION
;
1998 case 'X': /* selection width */
1999 crop_data
->crop_mode
|= CROP_WIDTH
;
2000 crop_data
->width
= atof(optarg
);
2002 case 'Y': /* selection length */
2003 crop_data
->crop_mode
|= CROP_LENGTH
;
2004 crop_data
->length
= atof(optarg
);
2006 case 'Z': /* zones of an image X:Y read as zone X of Y */
2007 crop_data
->crop_mode
|= CROP_ZONES
;
2008 for (i
= 0, opt_ptr
= strtok (optarg
, ",");
2009 ((opt_ptr
!= NULL
) && (i
< MAX_REGIONS
));
2010 (opt_ptr
= strtok (NULL
, ",")), i
++)
2013 opt_offset
= strchr(opt_ptr
, ':');
2015 crop_data
->zonelist
[i
].position
= atoi(opt_ptr
);
2016 crop_data
->zonelist
[i
].total
= atoi(opt_offset
+ 1);
2018 /* check for remaining elements over MAX_REGIONS */
2019 if ((opt_ptr
!= NULL
) && (i
>= MAX_REGIONS
))
2021 TIFFError("Zone list exceeds region limit", "%d", MAX_REGIONS
);
2025 case '?': TIFFError ("For valid options type", "tiffcrop -h");
2030 } /* end process_command_opts */
2032 /* Start a new output file if one has not been previously opened or
2033 * autoindex is set to non-zero. Update page and file counters
2034 * so TIFFTAG PAGENUM will be correct in image.
2037 update_output_file (TIFF
**tiffout
, char *mode
, int autoindex
,
2038 char *outname
, unsigned int *page
)
2040 static int findex
= 0; /* file sequence indicator */
2043 char export_ext
[16];
2044 char exportname
[PATH_MAX
];
2046 if (autoindex
&& (*tiffout
!= NULL
))
2048 /* Close any export file that was previously opened */
2049 TIFFClose (*tiffout
);
2053 strcpy (export_ext
, ".tiff");
2054 memset (exportname
, '\0', PATH_MAX
);
2056 /* Leave room for page number portion of the new filename */
2057 strncpy (exportname
, outname
, PATH_MAX
- 16);
2058 if (*tiffout
== NULL
) /* This is a new export file */
2061 { /* create a new filename for each export */
2063 if ((sep
= strstr(exportname
, ".tif")) || (sep
= strstr(exportname
, ".TIF")))
2065 strncpy (export_ext
, sep
, 5);
2069 strncpy (export_ext
, ".tiff", 5);
2070 export_ext
[5] = '\0';
2072 /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
2073 if (findex
> MAX_EXPORT_PAGES
)
2075 TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES
);
2079 sprintf (filenum
, "-%03d%s", findex
, export_ext
);
2081 strncat (exportname
, filenum
, 15);
2083 exportname
[PATH_MAX
- 1] = '\0';
2085 *tiffout
= TIFFOpen(exportname
, mode
);
2086 if (*tiffout
== NULL
)
2088 TIFFError("update_output_file", "Unable to open output file %s", exportname
);
2099 } /* end update_output_file */
2103 main(int argc
, char* argv
[])
2106 uint16 defconfig
= (uint16
) -1;
2107 uint16 deffillorder
= 0;
2108 uint32 deftilewidth
= (uint32
) 0;
2109 uint32 deftilelength
= (uint32
) 0;
2110 uint32 defrowsperstrip
= (uint32
) 0;
2118 /** RJN additions **/
2119 struct image_data image
; /* Image parameters for one image */
2120 struct crop_mask crop
; /* Cropping parameters for all images */
2121 struct pagedef page
; /* Page definition for output pages */
2122 struct pageseg sections
[MAX_SECTIONS
]; /* Sections of one output page */
2123 struct buffinfo seg_buffs
[MAX_SECTIONS
]; /* Segment buffer sizes and pointers */
2124 struct dump_opts dump
; /* Data dump options */
2125 unsigned char *read_buff
= NULL
; /* Input image data buffer */
2126 unsigned char *crop_buff
= NULL
; /* Crop area buffer */
2127 unsigned char *sect_buff
= NULL
; /* Image section buffer */
2128 unsigned char *sect_src
= NULL
; /* Image section buffer pointer */
2129 unsigned int imagelist
[MAX_IMAGES
+ 1]; /* individually specified images */
2130 unsigned int image_count
= 0;
2131 unsigned int dump_images
= 0;
2132 unsigned int next_image
= 0;
2133 unsigned int next_page
= 0;
2134 unsigned int total_pages
= 0;
2135 unsigned int total_images
= 0;
2136 unsigned int end_of_input
= FALSE
;
2138 char temp_filename
[PATH_MAX
+ 1];
2140 little_endian
= *((unsigned char *)&little_endian
) & '1';
2142 initImageData(&image
);
2143 initCropMasks(&crop
);
2144 initPageSetup(&page
, sections
, seg_buffs
);
2145 initDumpOptions(&dump
);
2147 process_command_opts (argc
, argv
, mp
, mode
, &dirnum
, &defconfig
,
2148 &deffillorder
, &deftilewidth
, &deftilelength
, &defrowsperstrip
,
2149 &crop
, &page
, &dump
, imagelist
, &image_count
);
2151 if (argc
- optind
< 2)
2154 if ((argc
- optind
) == 2)
2158 /* read multiple input files and write to output file(s) */
2159 while (optind
< argc
- 1)
2161 in
= TIFFOpen (argv
[optind
], "r");
2165 /* If only one input file is specified, we can use directory count */
2166 total_images
= TIFFNumberOfDirectories(in
);
2167 if (image_count
== 0)
2170 total_pages
= total_images
; /* Only valid with single input file */
2174 dirnum
= (tdir_t
)(imagelist
[next_image
] - 1);
2177 /* Total pages only valid for enumerated list of pages not derived
2178 * using odd, even, or last keywords.
2180 if (image_count
> total_images
)
2181 image_count
= total_images
;
2183 total_pages
= image_count
;
2186 /* MAX_IMAGES is used for special case "last" in selection list */
2187 if (dirnum
== (MAX_IMAGES
- 1))
2188 dirnum
= total_images
- 1;
2190 if (dirnum
> (total_images
))
2192 TIFFError (TIFFFileName(in
),
2193 "Invalid image number %d, File contains only %d images",
2194 (int)dirnum
+ 1, total_images
);
2196 (void) TIFFClose(out
);
2200 if (dirnum
!= 0 && !TIFFSetDirectory(in
, (tdir_t
)dirnum
))
2202 TIFFError(TIFFFileName(in
),"Error, setting subdirectory at %d", dirnum
);
2204 (void) TIFFClose(out
);
2208 end_of_input
= FALSE
;
2209 while (end_of_input
== FALSE
)
2212 compression
= defcompression
;
2213 predictor
= defpredictor
;
2214 fillorder
= deffillorder
;
2215 rowsperstrip
= defrowsperstrip
;
2216 tilewidth
= deftilewidth
;
2217 tilelength
= deftilelength
;
2220 if (dump
.format
!= DUMP_NONE
)
2222 /* manage input and/or output dump files here */
2224 length
= strlen(dump
.infilename
);
2227 if (dump
.infile
!= NULL
)
2228 fclose (dump
.infile
);
2230 /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes
2231 fewer than PATH_MAX */
2232 memset (temp_filename
, '\0', PATH_MAX
+ 1);
2233 sprintf (temp_filename
, "%s-read-%03d.%s", dump
.infilename
, dump_images
,
2234 (dump
.format
== DUMP_TEXT
) ? "txt" : "raw");
2235 if ((dump
.infile
= fopen(temp_filename
, dump
.mode
)) == NULL
)
2237 TIFFError ("Unable to open dump file for writing", "%s", temp_filename
);
2240 dump_info(dump
.infile
, dump
.format
, "Reading image","%d from %s",
2241 dump_images
, TIFFFileName(in
));
2243 length
= strlen(dump
.outfilename
);
2246 if (dump
.outfile
!= NULL
)
2247 fclose (dump
.outfile
);
2249 /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes
2250 fewer than PATH_MAX */
2251 memset (temp_filename
, '\0', PATH_MAX
+ 1);
2252 sprintf (temp_filename
, "%s-write-%03d.%s", dump
.outfilename
, dump_images
,
2253 (dump
.format
== DUMP_TEXT
) ? "txt" : "raw");
2254 if ((dump
.outfile
= fopen(temp_filename
, dump
.mode
)) == NULL
)
2256 TIFFError ("Unable to open dump file for writing", "%s", temp_filename
);
2259 dump_info(dump
.outfile
, dump
.format
, "Writing image","%d from %s",
2260 dump_images
, TIFFFileName(in
));
2265 TIFFError("main", "Reading image %4d of %4d total pages.", dirnum
+ 1, total_pages
);
2267 if (loadImage(in
, &image
, &dump
, &read_buff
))
2269 TIFFError("main", "Unable to load source image");
2273 /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
2275 if (image
.adjustments
!= 0)
2277 if (correct_orientation(&image
, &read_buff
))
2278 TIFFError("main", "Unable to correct image orientation");
2281 if (getCropOffsets(&image
, &crop
, &dump
))
2283 TIFFError("main", "Unable to define crop regions");
2287 if (crop
.selections
> 0)
2289 if (processCropSelections(&image
, &crop
, &read_buff
, seg_buffs
))
2291 TIFFError("main", "Unable to process image selections");
2295 else /* Single image segment without zones or regions */
2297 if (createCroppedImage(&image
, &crop
, &read_buff
, &crop_buff
))
2299 TIFFError("main", "Unable to create output image");
2303 if (page
.mode
== PAGE_MODE_NONE
)
2304 { /* Whole image or sections not based on output page size */
2305 if (crop
.selections
> 0)
2307 writeSelections(in
, &out
, &crop
, &image
, &dump
, seg_buffs
,
2308 mp
, argv
[argc
- 1], &next_page
, total_pages
);
2310 else /* One file all images and sections */
2312 if (update_output_file (&out
, mp
, crop
.exp_mode
, argv
[argc
- 1],
2315 if (writeCroppedImage(in
, out
, &image
, &dump
,crop
.combined_width
,
2316 crop
.combined_length
, crop_buff
, next_page
, total_pages
))
2318 TIFFError("main", "Unable to write new image");
2325 /* If we used a crop buffer, our data is there, otherwise it is
2326 * in the read_buffer
2328 if (crop_buff
!= NULL
)
2329 sect_src
= crop_buff
;
2331 sect_src
= read_buff
;
2332 /* Break input image into pages or rows and columns */
2333 if (computeOutputPixelOffsets(&crop
, &image
, &page
, sections
, &dump
))
2335 TIFFError("main", "Unable to compute output section data");
2338 /* If there are multiple files on the command line, the final one is assumed
2339 * to be the output filename into which the images are written.
2341 if (update_output_file (&out
, mp
, crop
.exp_mode
, argv
[argc
- 1], &next_page
))
2344 if (writeImageSections(in
, out
, &image
, &page
, sections
, &dump
, sect_src
, §_buff
))
2346 TIFFError("main", "Unable to write image sections");
2351 /* No image list specified, just read the next image */
2352 if (image_count
== 0)
2356 dirnum
= (tdir_t
)(imagelist
[next_image
] - 1);
2360 if (dirnum
== MAX_IMAGES
- 1)
2361 dirnum
= TIFFNumberOfDirectories(in
) - 1;
2363 if (!TIFFSetDirectory(in
, (tdir_t
)dirnum
))
2364 end_of_input
= TRUE
;
2370 /* If we did not use the read buffer as the crop buffer */
2372 _TIFFfree(read_buff
);
2375 _TIFFfree(crop_buff
);
2378 _TIFFfree(sect_buff
);
2380 /* Clean up any segment buffers used for zones or regions */
2381 for (seg
= 0; seg
< crop
.selections
; seg
++)
2382 _TIFFfree (seg_buffs
[seg
].buffer
);
2384 if (dump
.format
!= DUMP_NONE
)
2386 if (dump
.infile
!= NULL
)
2387 fclose (dump
.infile
);
2389 if (dump
.outfile
!= NULL
)
2391 dump_info (dump
.outfile
, dump
.format
, "", "Completed run for %s", TIFFFileName(out
));
2392 fclose (dump
.outfile
);
2402 /* Debugging functions */
2403 static int dump_data (FILE *dumpfile
, int format
, char *dump_tag
, unsigned char *data
, uint32 count
)
2407 char dump_array
[10];
2408 unsigned char bitset
;
2410 if (dumpfile
== NULL
)
2412 TIFFError ("", "Invalid FILE pointer for dump file");
2416 if (format
== DUMP_TEXT
)
2418 fprintf (dumpfile
," %s ", dump_tag
);
2419 for (i
= 0; i
< count
; i
++)
2421 for (j
= 0, k
= 7; j
< 8; j
++, k
--)
2423 bitset
= (*(data
+ i
)) & (((unsigned char)1 << k
)) ? 1 : 0;
2424 sprintf(&dump_array
[j
], (bitset
) ? "1" : "0");
2426 dump_array
[8] = '\0';
2427 fprintf (dumpfile
," %s", dump_array
);
2429 fprintf (dumpfile
,"\n");
2433 if ((fwrite (data
, 1, count
, dumpfile
)) != count
)
2435 TIFFError ("", "Unable to write binary data to dump file");
2443 static int dump_byte (FILE *dumpfile
, int format
, char *dump_tag
, unsigned char data
)
2446 char dump_array
[10];
2447 unsigned char bitset
;
2449 if (dumpfile
== NULL
)
2451 TIFFError ("", "Invalid FILE pointer for dump file");
2455 if (format
== DUMP_TEXT
)
2457 fprintf (dumpfile
," %s ", dump_tag
);
2458 for (j
= 0, k
= 7; j
< 8; j
++, k
--)
2460 bitset
= data
& (((unsigned char)1 << k
)) ? 1 : 0;
2461 sprintf(&dump_array
[j
], (bitset
) ? "1" : "0");
2463 dump_array
[8] = '\0';
2464 fprintf (dumpfile
," %s\n", dump_array
);
2468 if ((fwrite (&data
, 1, 1, dumpfile
)) != 1)
2470 TIFFError ("", "Unable to write binary data to dump file");
2478 static int dump_short (FILE *dumpfile
, int format
, char *dump_tag
, uint16 data
)
2481 char dump_array
[20];
2482 unsigned char bitset
;
2484 if (dumpfile
== NULL
)
2486 TIFFError ("", "Invalid FILE pointer for dump file");
2490 if (format
== DUMP_TEXT
)
2492 fprintf (dumpfile
," %s ", dump_tag
);
2493 for (j
= 0, k
= 15; k
>= 0; j
++, k
--)
2495 bitset
= data
& (((unsigned char)1 << k
)) ? 1 : 0;
2496 sprintf(&dump_array
[j
], (bitset
) ? "1" : "0");
2498 sprintf(&dump_array
[++j
], " ");
2500 dump_array
[17] = '\0';
2501 fprintf (dumpfile
," %s\n", dump_array
);
2505 if ((fwrite (&data
, 2, 1, dumpfile
)) != 2)
2507 TIFFError ("", "Unable to write binary data to dump file");
2515 static int dump_long (FILE *dumpfile
, int format
, char *dump_tag
, uint32 data
)
2518 char dump_array
[40];
2519 unsigned char bitset
;
2521 if (dumpfile
== NULL
)
2523 TIFFError ("", "Invalid FILE pointer for dump file");
2527 if (format
== DUMP_TEXT
)
2529 fprintf (dumpfile
," %s ", dump_tag
);
2530 for (j
= 0, k
= 31; k
>= 0; j
++, k
--)
2532 bitset
= data
& (((uint32
)1 << k
)) ? 1 : 0;
2533 sprintf(&dump_array
[j
], (bitset
) ? "1" : "0");
2535 sprintf(&dump_array
[++j
], " ");
2537 dump_array
[35] = '\0';
2538 fprintf (dumpfile
," %s\n", dump_array
);
2542 if ((fwrite (&data
, 4, 1, dumpfile
)) != 4)
2544 TIFFError ("", "Unable to write binary data to dump file");
2551 static int dump_wide (FILE *dumpfile
, int format
, char *dump_tag
, uint64 data
)
2554 char dump_array
[80];
2555 unsigned char bitset
;
2557 if (dumpfile
== NULL
)
2559 TIFFError ("", "Invalid FILE pointer for dump file");
2563 if (format
== DUMP_TEXT
)
2565 fprintf (dumpfile
," %s ", dump_tag
);
2566 for (j
= 0, k
= 63; k
>= 0; j
++, k
--)
2568 bitset
= data
& (((uint64
)1 << k
)) ? 1 : 0;
2569 sprintf(&dump_array
[j
], (bitset
) ? "1" : "0");
2571 sprintf(&dump_array
[++j
], " ");
2573 dump_array
[71] = '\0';
2574 fprintf (dumpfile
," %s\n", dump_array
);
2578 if ((fwrite (&data
, 8, 1, dumpfile
)) != 8)
2580 TIFFError ("", "Unable to write binary data to dump file");
2588 static void dump_info(FILE *dumpfile
, int format
, char *prefix
, char *msg
, ...)
2590 if (format
== DUMP_TEXT
)
2594 fprintf(dumpfile
, "%s ", prefix
);
2595 vfprintf(dumpfile
, msg
, ap
);
2596 fprintf(dumpfile
, "\n");
2600 static int dump_buffer (FILE* dumpfile
, int format
, uint32 rows
, uint32 width
,
2601 uint32 row
, unsigned char *buff
)
2605 unsigned char * dump_ptr
;
2607 if (dumpfile
== NULL
)
2609 TIFFError ("", "Invalid FILE pointer for dump file");
2613 for (i
= 0; i
< rows
; i
++)
2615 dump_ptr
= buff
+ (i
* width
);
2616 if (format
== DUMP_TEXT
)
2617 dump_info (dumpfile
, format
, "",
2618 "Row %4d, %d bytes at offset %d",
2619 row
+ i
+ 1, width
, row
* width
);
2621 for (j
= 0, k
= width
; k
>= 10; j
+= 10, k
-= 10, dump_ptr
+= 10)
2622 dump_data (dumpfile
, format
, "", dump_ptr
, 10);
2624 dump_data (dumpfile
, format
, "", dump_ptr
, k
);
2629 /* Extract one or more samples from an interleaved buffer. If count == 1,
2630 * only the sample plane indicated by sample will be extracted. If count > 1,
2631 * count samples beginning at sample will be extracted. Portions of a
2632 * scanline can be extracted by specifying a start and end value.
2636 extractContigSamplesBytes (uint8
*in
, uint8
*out
, uint32 cols
,
2637 tsample_t sample
, uint16 spp
, uint16 bps
,
2638 tsample_t count
, uint32 start
, uint32 end
)
2640 int i
, bytes_per_sample
, sindex
;
2641 uint32 col
, dst_rowsize
, bit_offset
;
2642 uint32 src_byte
, src_bit
;
2646 if ((src
== NULL
) || (dst
== NULL
))
2648 TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
2652 if ((start
> end
) || (start
> cols
))
2654 TIFFError ("extractContigSamplesBytes",
2655 "Invalid start column value %d ignored", start
);
2658 if ((end
== 0) || (end
> cols
))
2660 TIFFError ("extractContigSamplesBytes",
2661 "Invalid end column value %d ignored", end
);
2665 dst_rowsize
= (bps
* (end
- start
) * count
) / 8;
2667 bytes_per_sample
= (bps
+ 7) / 8;
2668 /* Optimize case for copying all samples */
2671 src
= in
+ (start
* spp
* bytes_per_sample
);
2672 _TIFFmemcpy (dst
, src
, dst_rowsize
);
2676 for (col
= start
; col
< end
; col
++)
2678 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
2680 bit_offset
= col
* bps
* spp
;
2683 src_byte
= bit_offset
/ 8;
2684 src_bit
= bit_offset
% 8;
2688 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
2689 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
2691 src
= in
+ src_byte
;
2692 for (i
= 0; i
< bytes_per_sample
; i
++)
2699 } /* end extractContigSamplesBytes */
2702 extractContigSamples8bits (uint8
*in
, uint8
*out
, uint32 cols
,
2703 tsample_t sample
, uint16 spp
, uint16 bps
,
2704 tsample_t count
, uint32 start
, uint32 end
)
2706 int ready_bits
= 0, sindex
= 0;
2707 uint32 col
, src_byte
, src_bit
, bit_offset
;
2708 uint8 maskbits
= 0, matchbits
= 0;
2709 uint8 buff1
= 0, buff2
= 0;
2713 if ((src
== NULL
) || (dst
== NULL
))
2715 TIFFError("extractContigSamples8bits","Invalid input or output buffer");
2719 if ((start
> end
) || (start
> cols
))
2721 TIFFError ("extractContigSamples8bits",
2722 "Invalid start column value %d ignored", start
);
2725 if ((end
== 0) || (end
> cols
))
2727 TIFFError ("extractContigSamples8bits",
2728 "Invalid end column value %d ignored", end
);
2733 maskbits
= (uint8
)-1 >> ( 8 - bps
);
2735 for (col
= start
; col
< end
; col
++)
2736 { /* Compute src byte(s) and bits within byte(s) */
2737 bit_offset
= col
* bps
* spp
;
2738 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
2742 src_byte
= bit_offset
/ 8;
2743 src_bit
= bit_offset
% 8;
2747 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
2748 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
2751 src
= in
+ src_byte
;
2752 matchbits
= maskbits
<< (8 - src_bit
- bps
);
2753 buff1
= ((*src
) & matchbits
) << (src_bit
);
2755 /* If we have a full buffer's worth, write it out */
2756 if (ready_bits
>= 8)
2763 buff2
= (buff2
| (buff1
>> ready_bits
));
2768 while (ready_bits
> 0)
2770 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
2776 } /* end extractContigSamples8bits */
2779 extractContigSamples16bits (uint8
*in
, uint8
*out
, uint32 cols
,
2780 tsample_t sample
, uint16 spp
, uint16 bps
,
2781 tsample_t count
, uint32 start
, uint32 end
)
2783 int ready_bits
= 0, sindex
= 0;
2784 uint32 col
, src_byte
, src_bit
, bit_offset
;
2785 uint16 maskbits
= 0, matchbits
= 0;
2786 uint16 buff1
= 0, buff2
= 0;
2791 if ((src
== NULL
) || (dst
== NULL
))
2793 TIFFError("extractContigSamples16bits","Invalid input or output buffer");
2797 if ((start
> end
) || (start
> cols
))
2799 TIFFError ("extractContigSamples16bits",
2800 "Invalid start column value %d ignored", start
);
2803 if ((end
== 0) || (end
> cols
))
2805 TIFFError ("extractContigSamples16bits",
2806 "Invalid end column value %d ignored", end
);
2811 maskbits
= (uint16
)-1 >> (16 - bps
);
2813 for (col
= start
; col
< end
; col
++)
2814 { /* Compute src byte(s) and bits within byte(s) */
2815 bit_offset
= col
* bps
* spp
;
2816 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
2820 src_byte
= bit_offset
/ 8;
2821 src_bit
= bit_offset
% 8;
2825 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
2826 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
2829 src
= in
+ src_byte
;
2830 matchbits
= maskbits
<< (16 - src_bit
- bps
);
2833 buff1
= (src
[0] << 8) | src
[1];
2835 buff1
= (src
[1] << 8) | src
[0];
2837 buff1
= (buff1
& matchbits
) << (src_bit
);
2838 if (ready_bits
< 8) /* add another bps bits to the buffer */
2841 buff2
= (buff2
| (buff1
>> ready_bits
));
2843 else /* If we have a full buffer's worth, write it out */
2845 bytebuff
= (buff2
>> 8);
2848 /* shift in new bits */
2849 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
2855 /* catch any trailing bits at the end of the line */
2856 while (ready_bits
> 0)
2858 bytebuff
= (buff2
>> 8);
2864 } /* end extractContigSamples16bits */
2868 extractContigSamples24bits (uint8
*in
, uint8
*out
, uint32 cols
,
2869 tsample_t sample
, uint16 spp
, uint16 bps
,
2870 tsample_t count
, uint32 start
, uint32 end
)
2872 int ready_bits
= 0, sindex
= 0;
2873 uint32 col
, src_byte
, src_bit
, bit_offset
;
2874 uint32 maskbits
= 0, matchbits
= 0;
2875 uint32 buff1
= 0, buff2
= 0;
2876 uint8 bytebuff1
= 0, bytebuff2
= 0;
2880 if ((in
== NULL
) || (out
== NULL
))
2882 TIFFError("extractContigSamples24bits","Invalid input or output buffer");
2886 if ((start
> end
) || (start
> cols
))
2888 TIFFError ("extractContigSamples24bits",
2889 "Invalid start column value %d ignored", start
);
2892 if ((end
== 0) || (end
> cols
))
2894 TIFFError ("extractContigSamples24bits",
2895 "Invalid end column value %d ignored", end
);
2900 maskbits
= (uint32
)-1 >> ( 32 - bps
);
2901 for (col
= start
; col
< end
; col
++)
2903 /* Compute src byte(s) and bits within byte(s) */
2904 bit_offset
= col
* bps
* spp
;
2905 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
2909 src_byte
= bit_offset
/ 8;
2910 src_bit
= bit_offset
% 8;
2914 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
2915 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
2918 src
= in
+ src_byte
;
2919 matchbits
= maskbits
<< (32 - src_bit
- bps
);
2921 buff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
2923 buff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
2924 buff1
= (buff1
& matchbits
) << (src_bit
);
2926 if (ready_bits
< 16) /* add another bps bits to the buffer */
2928 bytebuff1
= bytebuff2
= 0;
2929 buff2
= (buff2
| (buff1
>> ready_bits
));
2931 else /* If we have a full buffer's worth, write it out */
2933 bytebuff1
= (buff2
>> 24);
2935 bytebuff2
= (buff2
>> 16);
2939 /* shift in new bits */
2940 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
2946 /* catch any trailing bits at the end of the line */
2947 while (ready_bits
> 0)
2949 bytebuff1
= (buff2
>> 24);
2952 buff2
= (buff2
<< 8);
2953 bytebuff2
= bytebuff1
;
2958 } /* end extractContigSamples24bits */
2961 extractContigSamples32bits (uint8
*in
, uint8
*out
, uint32 cols
,
2962 tsample_t sample
, uint16 spp
, uint16 bps
,
2963 tsample_t count
, uint32 start
, uint32 end
)
2965 int ready_bits
= 0, sindex
= 0, shift_width
= 0;
2966 uint32 col
, src_byte
, src_bit
, bit_offset
;
2967 uint32 longbuff1
= 0, longbuff2
= 0;
2968 uint64 maskbits
= 0, matchbits
= 0;
2969 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
2970 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
2974 if ((in
== NULL
) || (out
== NULL
))
2976 TIFFError("extractContigSamples32bits","Invalid input or output buffer");
2981 if ((start
> end
) || (start
> cols
))
2983 TIFFError ("extractContigSamples32bits",
2984 "Invalid start column value %d ignored", start
);
2987 if ((end
== 0) || (end
> cols
))
2989 TIFFError ("extractContigSamples32bits",
2990 "Invalid end column value %d ignored", end
);
2994 shift_width
= ((bps
+ 7) / 8) + 1;
2996 maskbits
= (uint64
)-1 >> ( 64 - bps
);
2997 for (col
= start
; col
< end
; col
++)
2999 /* Compute src byte(s) and bits within byte(s) */
3000 bit_offset
= col
* bps
* spp
;
3001 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
3005 src_byte
= bit_offset
/ 8;
3006 src_bit
= bit_offset
% 8;
3010 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
3011 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
3014 src
= in
+ src_byte
;
3015 matchbits
= maskbits
<< (64 - src_bit
- bps
);
3018 longbuff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
3019 longbuff2
= longbuff1
;
3023 longbuff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
3024 longbuff2
= longbuff1
;
3027 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
3028 buff1
= (buff3
& matchbits
) << (src_bit
);
3030 /* If we have a full buffer's worth, write it out */
3031 if (ready_bits
>= 32)
3033 bytebuff1
= (buff2
>> 56);
3035 bytebuff2
= (buff2
>> 48);
3037 bytebuff3
= (buff2
>> 40);
3039 bytebuff4
= (buff2
>> 32);
3043 /* shift in new bits */
3044 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
3047 { /* add another bps bits to the buffer */
3048 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
3049 buff2
= (buff2
| (buff1
>> ready_bits
));
3054 while (ready_bits
> 0)
3056 bytebuff1
= (buff2
>> 56);
3058 buff2
= (buff2
<< 8);
3063 } /* end extractContigSamples32bits */
3066 extractContigSamplesShifted8bits (uint8
*in
, uint8
*out
, uint32 cols
,
3067 tsample_t sample
, uint16 spp
, uint16 bps
,
3068 tsample_t count
, uint32 start
, uint32 end
,
3071 int ready_bits
= 0, sindex
= 0;
3072 uint32 col
, src_byte
, src_bit
, bit_offset
;
3073 uint8 maskbits
= 0, matchbits
= 0;
3074 uint8 buff1
= 0, buff2
= 0;
3078 if ((src
== NULL
) || (dst
== NULL
))
3080 TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
3084 if ((start
> end
) || (start
> cols
))
3086 TIFFError ("extractContigSamplesShifted8bits",
3087 "Invalid start column value %d ignored", start
);
3090 if ((end
== 0) || (end
> cols
))
3092 TIFFError ("extractContigSamplesShifted8bits",
3093 "Invalid end column value %d ignored", end
);
3098 maskbits
= (uint8
)-1 >> ( 8 - bps
);
3100 for (col
= start
; col
< end
; col
++)
3101 { /* Compute src byte(s) and bits within byte(s) */
3102 bit_offset
= col
* bps
* spp
;
3103 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
3107 src_byte
= bit_offset
/ 8;
3108 src_bit
= bit_offset
% 8;
3112 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
3113 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
3116 src
= in
+ src_byte
;
3117 matchbits
= maskbits
<< (8 - src_bit
- bps
);
3118 buff1
= ((*src
) & matchbits
) << (src_bit
);
3119 if ((col
== start
) && (sindex
== sample
))
3120 buff2
= *src
& ((uint8
)-1) << (shift
);
3122 /* If we have a full buffer's worth, write it out */
3123 if (ready_bits
>= 8)
3130 buff2
= buff2
| (buff1
>> ready_bits
);
3135 while (ready_bits
> 0)
3137 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
3143 } /* end extractContigSamplesShifted8bits */
3146 extractContigSamplesShifted16bits (uint8
*in
, uint8
*out
, uint32 cols
,
3147 tsample_t sample
, uint16 spp
, uint16 bps
,
3148 tsample_t count
, uint32 start
, uint32 end
,
3151 int ready_bits
= 0, sindex
= 0;
3152 uint32 col
, src_byte
, src_bit
, bit_offset
;
3153 uint16 maskbits
= 0, matchbits
= 0;
3154 uint16 buff1
= 0, buff2
= 0;
3159 if ((src
== NULL
) || (dst
== NULL
))
3161 TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
3165 if ((start
> end
) || (start
> cols
))
3167 TIFFError ("extractContigSamplesShifted16bits",
3168 "Invalid start column value %d ignored", start
);
3171 if ((end
== 0) || (end
> cols
))
3173 TIFFError ("extractContigSamplesShifted16bits",
3174 "Invalid end column value %d ignored", end
);
3179 maskbits
= (uint16
)-1 >> (16 - bps
);
3180 for (col
= start
; col
< end
; col
++)
3181 { /* Compute src byte(s) and bits within byte(s) */
3182 bit_offset
= col
* bps
* spp
;
3183 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
3187 src_byte
= bit_offset
/ 8;
3188 src_bit
= bit_offset
% 8;
3192 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
3193 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
3196 src
= in
+ src_byte
;
3197 matchbits
= maskbits
<< (16 - src_bit
- bps
);
3199 buff1
= (src
[0] << 8) | src
[1];
3201 buff1
= (src
[1] << 8) | src
[0];
3203 if ((col
== start
) && (sindex
== sample
))
3204 buff2
= buff1
& ((uint16
)-1) << (8 - shift
);
3206 buff1
= (buff1
& matchbits
) << (src_bit
);
3208 if (ready_bits
< 8) /* add another bps bits to the buffer */
3209 buff2
= buff2
| (buff1
>> ready_bits
);
3210 else /* If we have a full buffer's worth, write it out */
3212 bytebuff
= (buff2
>> 8);
3215 /* shift in new bits */
3216 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
3223 /* catch any trailing bits at the end of the line */
3224 while (ready_bits
> 0)
3226 bytebuff
= (buff2
>> 8);
3232 } /* end extractContigSamplesShifted16bits */
3236 extractContigSamplesShifted24bits (uint8
*in
, uint8
*out
, uint32 cols
,
3237 tsample_t sample
, uint16 spp
, uint16 bps
,
3238 tsample_t count
, uint32 start
, uint32 end
,
3241 int ready_bits
= 0, sindex
= 0;
3242 uint32 col
, src_byte
, src_bit
, bit_offset
;
3243 uint32 maskbits
= 0, matchbits
= 0;
3244 uint32 buff1
= 0, buff2
= 0;
3245 uint8 bytebuff1
= 0, bytebuff2
= 0;
3249 if ((in
== NULL
) || (out
== NULL
))
3251 TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
3255 if ((start
> end
) || (start
> cols
))
3257 TIFFError ("extractContigSamplesShifted24bits",
3258 "Invalid start column value %d ignored", start
);
3261 if ((end
== 0) || (end
> cols
))
3263 TIFFError ("extractContigSamplesShifted24bits",
3264 "Invalid end column value %d ignored", end
);
3269 maskbits
= (uint32
)-1 >> ( 32 - bps
);
3270 for (col
= start
; col
< end
; col
++)
3272 /* Compute src byte(s) and bits within byte(s) */
3273 bit_offset
= col
* bps
* spp
;
3274 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
3278 src_byte
= bit_offset
/ 8;
3279 src_bit
= bit_offset
% 8;
3283 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
3284 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
3287 src
= in
+ src_byte
;
3288 matchbits
= maskbits
<< (32 - src_bit
- bps
);
3290 buff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
3292 buff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
3294 if ((col
== start
) && (sindex
== sample
))
3295 buff2
= buff1
& ((uint32
)-1) << (16 - shift
);
3297 buff1
= (buff1
& matchbits
) << (src_bit
);
3299 if (ready_bits
< 16) /* add another bps bits to the buffer */
3301 bytebuff1
= bytebuff2
= 0;
3302 buff2
= (buff2
| (buff1
>> ready_bits
));
3304 else /* If we have a full buffer's worth, write it out */
3306 bytebuff1
= (buff2
>> 24);
3308 bytebuff2
= (buff2
>> 16);
3312 /* shift in new bits */
3313 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
3319 /* catch any trailing bits at the end of the line */
3320 while (ready_bits
> 0)
3322 bytebuff1
= (buff2
>> 24);
3325 buff2
= (buff2
<< 8);
3326 bytebuff2
= bytebuff1
;
3331 } /* end extractContigSamplesShifted24bits */
3334 extractContigSamplesShifted32bits (uint8
*in
, uint8
*out
, uint32 cols
,
3335 tsample_t sample
, uint16 spp
, uint16 bps
,
3336 tsample_t count
, uint32 start
, uint32 end
,
3339 int ready_bits
= 0, sindex
= 0, shift_width
= 0;
3340 uint32 col
, src_byte
, src_bit
, bit_offset
;
3341 uint32 longbuff1
= 0, longbuff2
= 0;
3342 uint64 maskbits
= 0, matchbits
= 0;
3343 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
3344 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
3348 if ((in
== NULL
) || (out
== NULL
))
3350 TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
3355 if ((start
> end
) || (start
> cols
))
3357 TIFFError ("extractContigSamplesShifted32bits",
3358 "Invalid start column value %d ignored", start
);
3361 if ((end
== 0) || (end
> cols
))
3363 TIFFError ("extractContigSamplesShifted32bits",
3364 "Invalid end column value %d ignored", end
);
3368 shift_width
= ((bps
+ 7) / 8) + 1;
3370 maskbits
= (uint64
)-1 >> ( 64 - bps
);
3371 for (col
= start
; col
< end
; col
++)
3373 /* Compute src byte(s) and bits within byte(s) */
3374 bit_offset
= col
* bps
* spp
;
3375 for (sindex
= sample
; (sindex
< spp
) && (sindex
< (sample
+ count
)); sindex
++)
3379 src_byte
= bit_offset
/ 8;
3380 src_bit
= bit_offset
% 8;
3384 src_byte
= (bit_offset
+ (sindex
* bps
)) / 8;
3385 src_bit
= (bit_offset
+ (sindex
* bps
)) % 8;
3388 src
= in
+ src_byte
;
3389 matchbits
= maskbits
<< (64 - src_bit
- bps
);
3392 longbuff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
3393 longbuff2
= longbuff1
;
3397 longbuff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
3398 longbuff2
= longbuff1
;
3401 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
3402 if ((col
== start
) && (sindex
== sample
))
3403 buff2
= buff3
& ((uint64
)-1) << (32 - shift
);
3405 buff1
= (buff3
& matchbits
) << (src_bit
);
3407 if (ready_bits
< 32)
3408 { /* add another bps bits to the buffer */
3409 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
3410 buff2
= (buff2
| (buff1
>> ready_bits
));
3412 else /* If we have a full buffer's worth, write it out */
3414 bytebuff1
= (buff2
>> 56);
3416 bytebuff2
= (buff2
>> 48);
3418 bytebuff3
= (buff2
>> 40);
3420 bytebuff4
= (buff2
>> 32);
3424 /* shift in new bits */
3425 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
3430 while (ready_bits
> 0)
3432 bytebuff1
= (buff2
>> 56);
3434 buff2
= (buff2
<< 8);
3439 } /* end extractContigSamplesShifted32bits */
3442 extractContigSamplesToBuffer(uint8
*out
, uint8
*in
, uint32 rows
, uint32 cols
,
3443 tsample_t sample
, uint16 spp
, uint16 bps
,
3444 struct dump_opts
*dump
)
3446 int shift_width
, bytes_per_sample
, bytes_per_pixel
;
3447 uint32 src_rowsize
, src_offset
, row
, first_col
= 0;
3448 uint32 dst_rowsize
, dst_offset
;
3449 tsample_t count
= 1;
3452 bytes_per_sample
= (bps
+ 7) / 8;
3453 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
3458 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
3459 shift_width
= bytes_per_pixel
;
3461 shift_width
= bytes_per_sample
+ 1;
3463 src_rowsize
= ((bps
* spp
* cols
) + 7) / 8;
3464 dst_rowsize
= ((bps
* cols
) + 7) / 8;
3466 if ((dump
->outfile
!= NULL
) && (dump
->level
== 4))
3468 dump_info (dump
->outfile
, dump
->format
, "extractContigSamplesToBuffer",
3469 "Sample %d, %d rows", sample
+ 1, rows
+ 1);
3471 for (row
= 0; row
< rows
; row
++)
3473 src_offset
= row
* src_rowsize
;
3474 dst_offset
= row
* dst_rowsize
;
3475 src
= in
+ src_offset
;
3476 dst
= out
+ dst_offset
;
3478 /* pack the data into the scanline */
3479 switch (shift_width
)
3481 case 0: if (extractContigSamplesBytes (src
, dst
, cols
, sample
,
3482 spp
, bps
, count
, first_col
, cols
))
3485 case 1: if (bps
== 1)
3487 if (extractContigSamples8bits (src
, dst
, cols
, sample
,
3488 spp
, bps
, count
, first_col
, cols
))
3493 if (extractContigSamples16bits (src
, dst
, cols
, sample
,
3494 spp
, bps
, count
, first_col
, cols
))
3497 case 2: if (extractContigSamples24bits (src
, dst
, cols
, sample
,
3498 spp
, bps
, count
, first_col
, cols
))
3503 case 5: if (extractContigSamples32bits (src
, dst
, cols
, sample
,
3504 spp
, bps
, count
, first_col
, cols
))
3507 default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps
);
3510 if ((dump
->outfile
!= NULL
) && (dump
->level
== 4))
3511 dump_buffer(dump
->outfile
, dump
->format
, 1, dst_rowsize
, row
, dst
);
3515 } /* end extractContigSamplesToBuffer */
3518 extractContigSamplesToTileBuffer(uint8
*out
, uint8
*in
, uint32 rows
, uint32 cols
,
3519 uint32 imagewidth
, uint32 tilewidth
, tsample_t sample
,
3520 uint16 count
, uint16 spp
, uint16 bps
, struct dump_opts
*dump
)
3522 int shift_width
, bytes_per_sample
, bytes_per_pixel
;
3523 uint32 src_rowsize
, src_offset
, row
;
3524 uint32 dst_rowsize
, dst_offset
;
3527 bytes_per_sample
= (bps
+ 7) / 8;
3528 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
3533 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
3534 shift_width
= bytes_per_pixel
;
3536 shift_width
= bytes_per_sample
+ 1;
3539 if ((dump
->outfile
!= NULL
) && (dump
->level
== 4))
3541 dump_info (dump
->outfile
, dump
->format
, "extractContigSamplesToTileBuffer",
3542 "Sample %d, %d rows", sample
+ 1, rows
+ 1);
3545 src_rowsize
= ((bps
* spp
* imagewidth
) + 7) / 8;
3546 dst_rowsize
= ((bps
* tilewidth
* count
) + 7) / 8;
3548 for (row
= 0; row
< rows
; row
++)
3550 src_offset
= row
* src_rowsize
;
3551 dst_offset
= row
* dst_rowsize
;
3552 src
= in
+ src_offset
;
3553 dst
= out
+ dst_offset
;
3555 /* pack the data into the scanline */
3556 switch (shift_width
)
3558 case 0: if (extractContigSamplesBytes (src
, dst
, cols
, sample
,
3559 spp
, bps
, count
, 0, cols
))
3562 case 1: if (bps
== 1)
3564 if (extractContigSamples8bits (src
, dst
, cols
, sample
,
3565 spp
, bps
, count
, 0, cols
))
3570 if (extractContigSamples16bits (src
, dst
, cols
, sample
,
3571 spp
, bps
, count
, 0, cols
))
3574 case 2: if (extractContigSamples24bits (src
, dst
, cols
, sample
,
3575 spp
, bps
, count
, 0, cols
))
3580 case 5: if (extractContigSamples32bits (src
, dst
, cols
, sample
,
3581 spp
, bps
, count
, 0, cols
))
3584 default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps
);
3587 if ((dump
->outfile
!= NULL
) && (dump
->level
== 4))
3588 dump_buffer(dump
->outfile
, dump
->format
, 1, dst_rowsize
, row
, dst
);
3592 } /* end extractContigSamplesToTileBuffer */
3594 static int readContigStripsIntoBuffer (TIFF
* in
, uint8
* buf
)
3597 int32 bytes_read
= 0;
3598 uint16 strip
, nstrips
= TIFFNumberOfStrips(in
);
3599 uint32 stripsize
= TIFFStripSize(in
);
3601 uint32 rps
= TIFFGetFieldDefaulted(in
, TIFFTAG_ROWSPERSTRIP
, &rps
);
3602 tsize_t scanline_size
= TIFFScanlineSize(in
);
3604 for (strip
= 0; strip
< nstrips
; strip
++)
3606 bytes_read
= TIFFReadEncodedStrip (in
, strip
, bufp
, -1);
3607 rows
= bytes_read
/ scanline_size
;
3608 if ((strip
< (nstrips
- 1)) && (bytes_read
!= (int32
)stripsize
))
3609 TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
3610 (int)strip
+ 1, (unsigned long) bytes_read
, (unsigned long)stripsize
);
3612 if (bytes_read
< 0 && !ignore
)
3614 TIFFError("", "Error reading strip %lu after %lu rows",
3615 (unsigned long) strip
, (unsigned long)rows
);
3622 } /* end readContigStripsIntoBuffer */
3625 combineSeparateSamplesBytes (unsigned char *srcbuffs
[], unsigned char *out
,
3626 uint32 cols
, uint32 rows
, uint16 spp
, uint16 bps
,
3627 FILE *dumpfile
, int format
, int level
)
3629 int i
, bytes_per_sample
;
3630 uint32 row
, col
, col_offset
, src_rowsize
, dst_rowsize
, row_offset
;
3637 if ((src
== NULL
) || (dst
== NULL
))
3639 TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
3643 bytes_per_sample
= (bps
+ 7) / 8;
3645 src_rowsize
= ((bps
* cols
) + 7) / 8;
3646 dst_rowsize
= ((bps
* spp
* cols
) + 7) / 8;
3647 for (row
= 0; row
< rows
; row
++)
3649 if ((dumpfile
!= NULL
) && (level
== 2))
3651 for (s
= 0; s
< spp
; s
++)
3653 dump_info (dumpfile
, format
, "combineSeparateSamplesBytes","Input data, Sample %d", s
);
3654 dump_buffer(dumpfile
, format
, 1, cols
, row
, srcbuffs
[s
] + (row
* src_rowsize
));
3657 dst
= out
+ (row
* dst_rowsize
);
3658 row_offset
= row
* src_rowsize
;
3659 for (col
= 0; col
< cols
; col
++)
3661 col_offset
= row_offset
+ (col
* (bps
/ 8));
3662 for (s
= 0; (s
< spp
) && (s
< MAX_SAMPLES
); s
++)
3664 src
= srcbuffs
[s
] + col_offset
;
3665 for (i
= 0; i
< bytes_per_sample
; i
++)
3666 *(dst
+ i
) = *(src
+ i
);
3667 src
+= bytes_per_sample
;
3668 dst
+= bytes_per_sample
;
3672 if ((dumpfile
!= NULL
) && (level
== 2))
3674 dump_info (dumpfile
, format
, "combineSeparateSamplesBytes","Output data, combined samples");
3675 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
3680 } /* end combineSeparateSamplesBytes */
3683 combineSeparateSamples8bits (uint8
*in
[], uint8
*out
, uint32 cols
,
3684 uint32 rows
, uint16 spp
, uint16 bps
,
3685 FILE *dumpfile
, int format
, int level
)
3688 int bytes_per_sample
= 0;
3689 uint32 src_rowsize
, dst_rowsize
, src_offset
;
3691 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
3692 uint8 maskbits
= 0, matchbits
= 0;
3693 uint8 buff1
= 0, buff2
= 0;
3695 unsigned char *src
= in
[0];
3696 unsigned char *dst
= out
;
3699 if ((src
== NULL
) || (dst
== NULL
))
3701 TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
3705 bytes_per_sample
= (bps
+ 7) / 8;
3706 src_rowsize
= ((bps
* cols
) + 7) / 8;
3707 dst_rowsize
= ((bps
* cols
* spp
) + 7) / 8;
3708 maskbits
= (uint8
)-1 >> ( 8 - bps
);
3710 for (row
= 0; row
< rows
; row
++)
3714 dst
= out
+ (row
* dst_rowsize
);
3715 src_offset
= row
* src_rowsize
;
3716 for (col
= 0; col
< cols
; col
++)
3718 /* Compute src byte(s) and bits within byte(s) */
3719 bit_offset
= col
* bps
;
3720 src_byte
= bit_offset
/ 8;
3721 src_bit
= bit_offset
% 8;
3723 matchbits
= maskbits
<< (8 - src_bit
- bps
);
3724 /* load up next sample from each plane */
3725 for (s
= 0; s
< spp
; s
++)
3727 src
= in
[s
] + src_offset
+ src_byte
;
3728 buff1
= ((*src
) & matchbits
) << (src_bit
);
3730 /* If we have a full buffer's worth, write it out */
3731 if (ready_bits
>= 8)
3736 strcpy (action
, "Flush");
3740 buff2
= (buff2
| (buff1
>> ready_bits
));
3741 strcpy (action
, "Update");
3745 if ((dumpfile
!= NULL
) && (level
== 3))
3747 dump_info (dumpfile
, format
, "",
3748 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3749 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
3750 dump_byte (dumpfile
, format
, "Match bits", matchbits
);
3751 dump_byte (dumpfile
, format
, "Src bits", *src
);
3752 dump_byte (dumpfile
, format
, "Buff1 bits", buff1
);
3753 dump_byte (dumpfile
, format
, "Buff2 bits", buff2
);
3754 dump_info (dumpfile
, format
, "","%s", action
);
3761 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
3763 if ((dumpfile
!= NULL
) && (level
== 3))
3765 dump_info (dumpfile
, format
, "",
3766 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3767 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
3768 dump_byte (dumpfile
, format
, "Final bits", buff1
);
3772 if ((dumpfile
!= NULL
) && (level
>= 2))
3774 dump_info (dumpfile
, format
, "combineSeparateSamples8bits","Output data");
3775 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
3780 } /* end combineSeparateSamples8bits */
3783 combineSeparateSamples16bits (uint8
*in
[], uint8
*out
, uint32 cols
,
3784 uint32 rows
, uint16 spp
, uint16 bps
,
3785 FILE *dumpfile
, int format
, int level
)
3787 int ready_bits
= 0, bytes_per_sample
= 0;
3788 uint32 src_rowsize
, dst_rowsize
;
3789 uint32 bit_offset
, src_offset
;
3790 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
3791 uint16 maskbits
= 0, matchbits
= 0;
3792 uint16 buff1
= 0, buff2
= 0;
3795 unsigned char *src
= in
[0];
3796 unsigned char *dst
= out
;
3799 if ((src
== NULL
) || (dst
== NULL
))
3801 TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
3805 bytes_per_sample
= (bps
+ 7) / 8;
3806 src_rowsize
= ((bps
* cols
) + 7) / 8;
3807 dst_rowsize
= ((bps
* cols
* spp
) + 7) / 8;
3808 maskbits
= (uint16
)-1 >> (16 - bps
);
3810 for (row
= 0; row
< rows
; row
++)
3814 dst
= out
+ (row
* dst_rowsize
);
3815 src_offset
= row
* src_rowsize
;
3816 for (col
= 0; col
< cols
; col
++)
3818 /* Compute src byte(s) and bits within byte(s) */
3819 bit_offset
= col
* bps
;
3820 src_byte
= bit_offset
/ 8;
3821 src_bit
= bit_offset
% 8;
3823 matchbits
= maskbits
<< (16 - src_bit
- bps
);
3824 for (s
= 0; s
< spp
; s
++)
3826 src
= in
[s
] + src_offset
+ src_byte
;
3828 buff1
= (src
[0] << 8) | src
[1];
3830 buff1
= (src
[1] << 8) | src
[0];
3832 buff1
= (buff1
& matchbits
) << (src_bit
);
3834 /* If we have a full buffer's worth, write it out */
3835 if (ready_bits
>= 8)
3837 bytebuff
= (buff2
>> 8);
3840 /* shift in new bits */
3841 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
3842 strcpy (action
, "Flush");
3845 { /* add another bps bits to the buffer */
3847 buff2
= (buff2
| (buff1
>> ready_bits
));
3848 strcpy (action
, "Update");
3852 if ((dumpfile
!= NULL
) && (level
== 3))
3854 dump_info (dumpfile
, format
, "",
3855 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3856 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
3858 dump_short (dumpfile
, format
, "Match bits", matchbits
);
3859 dump_data (dumpfile
, format
, "Src bits", src
, 2);
3860 dump_short (dumpfile
, format
, "Buff1 bits", buff1
);
3861 dump_short (dumpfile
, format
, "Buff2 bits", buff2
);
3862 dump_byte (dumpfile
, format
, "Write byte", bytebuff
);
3863 dump_info (dumpfile
, format
, "","Ready bits: %d, %s", ready_bits
, action
);
3868 /* catch any trailing bits at the end of the line */
3871 bytebuff
= (buff2
>> 8);
3873 if ((dumpfile
!= NULL
) && (level
== 3))
3875 dump_info (dumpfile
, format
, "",
3876 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3877 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
3878 dump_byte (dumpfile
, format
, "Final bits", bytebuff
);
3882 if ((dumpfile
!= NULL
) && (level
== 2))
3884 dump_info (dumpfile
, format
, "combineSeparateSamples16bits","Output data");
3885 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
3890 } /* end combineSeparateSamples16bits */
3893 combineSeparateSamples24bits (uint8
*in
[], uint8
*out
, uint32 cols
,
3894 uint32 rows
, uint16 spp
, uint16 bps
,
3895 FILE *dumpfile
, int format
, int level
)
3897 int ready_bits
= 0, bytes_per_sample
= 0;
3898 uint32 src_rowsize
, dst_rowsize
;
3899 uint32 bit_offset
, src_offset
;
3900 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
3901 uint32 maskbits
= 0, matchbits
= 0;
3902 uint32 buff1
= 0, buff2
= 0;
3903 uint8 bytebuff1
= 0, bytebuff2
= 0;
3905 unsigned char *src
= in
[0];
3906 unsigned char *dst
= out
;
3909 if ((src
== NULL
) || (dst
== NULL
))
3911 TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
3915 bytes_per_sample
= (bps
+ 7) / 8;
3916 src_rowsize
= ((bps
* cols
) + 7) / 8;
3917 dst_rowsize
= ((bps
* cols
* spp
) + 7) / 8;
3918 maskbits
= (uint32
)-1 >> ( 32 - bps
);
3920 for (row
= 0; row
< rows
; row
++)
3924 dst
= out
+ (row
* dst_rowsize
);
3925 src_offset
= row
* src_rowsize
;
3926 for (col
= 0; col
< cols
; col
++)
3928 /* Compute src byte(s) and bits within byte(s) */
3929 bit_offset
= col
* bps
;
3930 src_byte
= bit_offset
/ 8;
3931 src_bit
= bit_offset
% 8;
3933 matchbits
= maskbits
<< (32 - src_bit
- bps
);
3934 for (s
= 0; s
< spp
; s
++)
3936 src
= in
[s
] + src_offset
+ src_byte
;
3938 buff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
3940 buff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
3941 buff1
= (buff1
& matchbits
) << (src_bit
);
3943 /* If we have a full buffer's worth, write it out */
3944 if (ready_bits
>= 16)
3946 bytebuff1
= (buff2
>> 24);
3948 bytebuff2
= (buff2
>> 16);
3952 /* shift in new bits */
3953 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
3954 strcpy (action
, "Flush");
3957 { /* add another bps bits to the buffer */
3958 bytebuff1
= bytebuff2
= 0;
3959 buff2
= (buff2
| (buff1
>> ready_bits
));
3960 strcpy (action
, "Update");
3964 if ((dumpfile
!= NULL
) && (level
== 3))
3966 dump_info (dumpfile
, format
, "",
3967 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3968 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
3969 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
3970 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
3971 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
3972 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
3973 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
3974 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
3975 dump_info (dumpfile
, format
, "","Ready bits: %d, %s", ready_bits
, action
);
3980 /* catch any trailing bits at the end of the line */
3981 while (ready_bits
> 0)
3983 bytebuff1
= (buff2
>> 24);
3986 buff2
= (buff2
<< 8);
3987 bytebuff2
= bytebuff1
;
3991 if ((dumpfile
!= NULL
) && (level
== 3))
3993 dump_info (dumpfile
, format
, "",
3994 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3995 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
3997 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
3998 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
3999 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
4000 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
4001 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
4002 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
4003 dump_info (dumpfile
, format
, "", "Ready bits: %2d", ready_bits
);
4006 if ((dumpfile
!= NULL
) && (level
== 2))
4008 dump_info (dumpfile
, format
, "combineSeparateSamples24bits","Output data");
4009 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
4014 } /* end combineSeparateSamples24bits */
4017 combineSeparateSamples32bits (uint8
*in
[], uint8
*out
, uint32 cols
,
4018 uint32 rows
, uint16 spp
, uint16 bps
,
4019 FILE *dumpfile
, int format
, int level
)
4021 int ready_bits
= 0, bytes_per_sample
= 0, shift_width
= 0;
4022 uint32 src_rowsize
, dst_rowsize
, bit_offset
, src_offset
;
4023 uint32 src_byte
= 0, src_bit
= 0;
4025 uint32 longbuff1
= 0, longbuff2
= 0;
4026 uint64 maskbits
= 0, matchbits
= 0;
4027 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
4028 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
4030 unsigned char *src
= in
[0];
4031 unsigned char *dst
= out
;
4034 if ((src
== NULL
) || (dst
== NULL
))
4036 TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
4040 bytes_per_sample
= (bps
+ 7) / 8;
4041 src_rowsize
= ((bps
* cols
) + 7) / 8;
4042 dst_rowsize
= ((bps
* cols
* spp
) + 7) / 8;
4043 maskbits
= (uint64
)-1 >> ( 64 - bps
);
4044 shift_width
= ((bps
+ 7) / 8) + 1;
4046 for (row
= 0; row
< rows
; row
++)
4050 dst
= out
+ (row
* dst_rowsize
);
4051 src_offset
= row
* src_rowsize
;
4052 for (col
= 0; col
< cols
; col
++)
4054 /* Compute src byte(s) and bits within byte(s) */
4055 bit_offset
= col
* bps
;
4056 src_byte
= bit_offset
/ 8;
4057 src_bit
= bit_offset
% 8;
4059 matchbits
= maskbits
<< (64 - src_bit
- bps
);
4060 for (s
= 0; s
< spp
; s
++)
4062 src
= in
[s
] + src_offset
+ src_byte
;
4065 longbuff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
4066 longbuff2
= longbuff1
;
4070 longbuff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
4071 longbuff2
= longbuff1
;
4073 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
4074 buff1
= (buff3
& matchbits
) << (src_bit
);
4076 /* If we have a full buffer's worth, write it out */
4077 if (ready_bits
>= 32)
4079 bytebuff1
= (buff2
>> 56);
4081 bytebuff2
= (buff2
>> 48);
4083 bytebuff3
= (buff2
>> 40);
4085 bytebuff4
= (buff2
>> 32);
4089 /* shift in new bits */
4090 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
4091 strcpy (action
, "Flush");
4094 { /* add another bps bits to the buffer */
4095 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
4096 buff2
= (buff2
| (buff1
>> ready_bits
));
4097 strcpy (action
, "Update");
4101 if ((dumpfile
!= NULL
) && (level
== 3))
4103 dump_info (dumpfile
, format
, "",
4104 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4105 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
4106 dump_wide (dumpfile
, format
, "Match bits ", matchbits
);
4107 dump_data (dumpfile
, format
, "Src bits ", src
, 8);
4108 dump_wide (dumpfile
, format
, "Buff1 bits ", buff1
);
4109 dump_wide (dumpfile
, format
, "Buff2 bits ", buff2
);
4110 dump_info (dumpfile
, format
, "", "Ready bits: %d, %s", ready_bits
, action
);
4114 while (ready_bits
> 0)
4116 bytebuff1
= (buff2
>> 56);
4118 buff2
= (buff2
<< 8);
4122 if ((dumpfile
!= NULL
) && (level
== 3))
4124 dump_info (dumpfile
, format
, "",
4125 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4126 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
4128 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
4129 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
4130 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
4131 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
4132 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
4133 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
4134 dump_info (dumpfile
, format
, "", "Ready bits: %2d", ready_bits
);
4137 if ((dumpfile
!= NULL
) && (level
== 2))
4139 dump_info (dumpfile
, format
, "combineSeparateSamples32bits","Output data");
4140 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
);
4145 } /* end combineSeparateSamples32bits */
4148 combineSeparateTileSamplesBytes (unsigned char *srcbuffs
[], unsigned char *out
,
4149 uint32 cols
, uint32 rows
, uint32 imagewidth
,
4150 uint32 tw
, uint16 spp
, uint16 bps
,
4151 FILE *dumpfile
, int format
, int level
)
4153 int i
, bytes_per_sample
;
4154 uint32 row
, col
, col_offset
, src_rowsize
, dst_rowsize
, src_offset
;
4161 if ((src
== NULL
) || (dst
== NULL
))
4163 TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
4167 bytes_per_sample
= (bps
+ 7) / 8;
4168 src_rowsize
= ((bps
* tw
) + 7) / 8;
4169 dst_rowsize
= imagewidth
* bytes_per_sample
* spp
;
4170 for (row
= 0; row
< rows
; row
++)
4172 if ((dumpfile
!= NULL
) && (level
== 2))
4174 for (s
= 0; s
< spp
; s
++)
4176 dump_info (dumpfile
, format
, "combineSeparateTileSamplesBytes","Input data, Sample %d", s
);
4177 dump_buffer(dumpfile
, format
, 1, cols
, row
, srcbuffs
[s
] + (row
* src_rowsize
));
4180 dst
= out
+ (row
* dst_rowsize
);
4181 src_offset
= row
* src_rowsize
;
4183 TIFFError("","Tile row %4d, Src offset %6d Dst offset %6d",
4184 row
, src_offset
, dst
- out
);
4186 for (col
= 0; col
< cols
; col
++)
4188 col_offset
= src_offset
+ (col
* (bps
/ 8));
4189 for (s
= 0; (s
< spp
) && (s
< MAX_SAMPLES
); s
++)
4191 src
= srcbuffs
[s
] + col_offset
;
4192 for (i
= 0; i
< bytes_per_sample
; i
++)
4193 *(dst
+ i
) = *(src
+ i
);
4194 dst
+= bytes_per_sample
;
4198 if ((dumpfile
!= NULL
) && (level
== 2))
4200 dump_info (dumpfile
, format
, "combineSeparateTileSamplesBytes","Output data, combined samples");
4201 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
4206 } /* end combineSeparateTileSamplesBytes */
4209 combineSeparateTileSamples8bits (uint8
*in
[], uint8
*out
, uint32 cols
,
4210 uint32 rows
, uint32 imagewidth
,
4211 uint32 tw
, uint16 spp
, uint16 bps
,
4212 FILE *dumpfile
, int format
, int level
)
4215 uint32 src_rowsize
, dst_rowsize
, src_offset
;
4217 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
4218 uint8 maskbits
= 0, matchbits
= 0;
4219 uint8 buff1
= 0, buff2
= 0;
4221 unsigned char *src
= in
[0];
4222 unsigned char *dst
= out
;
4225 if ((src
== NULL
) || (dst
== NULL
))
4227 TIFFError("combineSeparateTileSamples8bits","Invalid input or output buffer");
4231 src_rowsize
= ((bps
* tw
) + 7) / 8;
4232 dst_rowsize
= ((imagewidth
* bps
* spp
) + 7) / 8;
4233 maskbits
= (uint8
)-1 >> ( 8 - bps
);
4235 for (row
= 0; row
< rows
; row
++)
4239 dst
= out
+ (row
* dst_rowsize
);
4240 src_offset
= row
* src_rowsize
;
4241 for (col
= 0; col
< cols
; col
++)
4243 /* Compute src byte(s) and bits within byte(s) */
4244 bit_offset
= col
* bps
;
4245 src_byte
= bit_offset
/ 8;
4246 src_bit
= bit_offset
% 8;
4248 matchbits
= maskbits
<< (8 - src_bit
- bps
);
4249 /* load up next sample from each plane */
4250 for (s
= 0; s
< spp
; s
++)
4252 src
= in
[s
] + src_offset
+ src_byte
;
4253 buff1
= ((*src
) & matchbits
) << (src_bit
);
4255 /* If we have a full buffer's worth, write it out */
4256 if (ready_bits
>= 8)
4261 strcpy (action
, "Flush");
4265 buff2
= (buff2
| (buff1
>> ready_bits
));
4266 strcpy (action
, "Update");
4270 if ((dumpfile
!= NULL
) && (level
== 3))
4272 dump_info (dumpfile
, format
, "",
4273 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4274 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
4275 dump_byte (dumpfile
, format
, "Match bits", matchbits
);
4276 dump_byte (dumpfile
, format
, "Src bits", *src
);
4277 dump_byte (dumpfile
, format
, "Buff1 bits", buff1
);
4278 dump_byte (dumpfile
, format
, "Buff2 bits", buff2
);
4279 dump_info (dumpfile
, format
, "","%s", action
);
4286 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
4288 if ((dumpfile
!= NULL
) && (level
== 3))
4290 dump_info (dumpfile
, format
, "",
4291 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4292 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
4293 dump_byte (dumpfile
, format
, "Final bits", buff1
);
4297 if ((dumpfile
!= NULL
) && (level
>= 2))
4299 dump_info (dumpfile
, format
, "combineSeparateTileSamples8bits","Output data");
4300 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
4305 } /* end combineSeparateTileSamples8bits */
4308 combineSeparateTileSamples16bits (uint8
*in
[], uint8
*out
, uint32 cols
,
4309 uint32 rows
, uint32 imagewidth
,
4310 uint32 tw
, uint16 spp
, uint16 bps
,
4311 FILE *dumpfile
, int format
, int level
)
4314 uint32 src_rowsize
, dst_rowsize
;
4315 uint32 bit_offset
, src_offset
;
4316 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
4317 uint16 maskbits
= 0, matchbits
= 0;
4318 uint16 buff1
= 0, buff2
= 0;
4321 unsigned char *src
= in
[0];
4322 unsigned char *dst
= out
;
4325 if ((src
== NULL
) || (dst
== NULL
))
4327 TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
4331 src_rowsize
= ((bps
* tw
) + 7) / 8;
4332 dst_rowsize
= ((imagewidth
* bps
* spp
) + 7) / 8;
4333 maskbits
= (uint16
)-1 >> (16 - bps
);
4335 for (row
= 0; row
< rows
; row
++)
4339 dst
= out
+ (row
* dst_rowsize
);
4340 src_offset
= row
* src_rowsize
;
4341 for (col
= 0; col
< cols
; col
++)
4343 /* Compute src byte(s) and bits within byte(s) */
4344 bit_offset
= col
* bps
;
4345 src_byte
= bit_offset
/ 8;
4346 src_bit
= bit_offset
% 8;
4348 matchbits
= maskbits
<< (16 - src_bit
- bps
);
4349 for (s
= 0; s
< spp
; s
++)
4351 src
= in
[s
] + src_offset
+ src_byte
;
4353 buff1
= (src
[0] << 8) | src
[1];
4355 buff1
= (src
[1] << 8) | src
[0];
4356 buff1
= (buff1
& matchbits
) << (src_bit
);
4358 /* If we have a full buffer's worth, write it out */
4359 if (ready_bits
>= 8)
4361 bytebuff
= (buff2
>> 8);
4364 /* shift in new bits */
4365 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
4366 strcpy (action
, "Flush");
4369 { /* add another bps bits to the buffer */
4371 buff2
= (buff2
| (buff1
>> ready_bits
));
4372 strcpy (action
, "Update");
4376 if ((dumpfile
!= NULL
) && (level
== 3))
4378 dump_info (dumpfile
, format
, "",
4379 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4380 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
4382 dump_short (dumpfile
, format
, "Match bits", matchbits
);
4383 dump_data (dumpfile
, format
, "Src bits", src
, 2);
4384 dump_short (dumpfile
, format
, "Buff1 bits", buff1
);
4385 dump_short (dumpfile
, format
, "Buff2 bits", buff2
);
4386 dump_byte (dumpfile
, format
, "Write byte", bytebuff
);
4387 dump_info (dumpfile
, format
, "","Ready bits: %d, %s", ready_bits
, action
);
4392 /* catch any trailing bits at the end of the line */
4395 bytebuff
= (buff2
>> 8);
4397 if ((dumpfile
!= NULL
) && (level
== 3))
4399 dump_info (dumpfile
, format
, "",
4400 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4401 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
4402 dump_byte (dumpfile
, format
, "Final bits", bytebuff
);
4406 if ((dumpfile
!= NULL
) && (level
== 2))
4408 dump_info (dumpfile
, format
, "combineSeparateTileSamples16bits","Output data");
4409 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
4414 } /* end combineSeparateTileSamples16bits */
4417 combineSeparateTileSamples24bits (uint8
*in
[], uint8
*out
, uint32 cols
,
4418 uint32 rows
, uint32 imagewidth
,
4419 uint32 tw
, uint16 spp
, uint16 bps
,
4420 FILE *dumpfile
, int format
, int level
)
4423 uint32 src_rowsize
, dst_rowsize
;
4424 uint32 bit_offset
, src_offset
;
4425 uint32 row
, col
, src_byte
= 0, src_bit
= 0;
4426 uint32 maskbits
= 0, matchbits
= 0;
4427 uint32 buff1
= 0, buff2
= 0;
4428 uint8 bytebuff1
= 0, bytebuff2
= 0;
4430 unsigned char *src
= in
[0];
4431 unsigned char *dst
= out
;
4434 if ((src
== NULL
) || (dst
== NULL
))
4436 TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
4440 src_rowsize
= ((bps
* tw
) + 7) / 8;
4441 dst_rowsize
= ((imagewidth
* bps
* spp
) + 7) / 8;
4442 maskbits
= (uint32
)-1 >> ( 32 - bps
);
4444 for (row
= 0; row
< rows
; row
++)
4448 dst
= out
+ (row
* dst_rowsize
);
4449 src_offset
= row
* src_rowsize
;
4450 for (col
= 0; col
< cols
; col
++)
4452 /* Compute src byte(s) and bits within byte(s) */
4453 bit_offset
= col
* bps
;
4454 src_byte
= bit_offset
/ 8;
4455 src_bit
= bit_offset
% 8;
4457 matchbits
= maskbits
<< (32 - src_bit
- bps
);
4458 for (s
= 0; s
< spp
; s
++)
4460 src
= in
[s
] + src_offset
+ src_byte
;
4462 buff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
4464 buff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
4465 buff1
= (buff1
& matchbits
) << (src_bit
);
4467 /* If we have a full buffer's worth, write it out */
4468 if (ready_bits
>= 16)
4470 bytebuff1
= (buff2
>> 24);
4472 bytebuff2
= (buff2
>> 16);
4476 /* shift in new bits */
4477 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
4478 strcpy (action
, "Flush");
4481 { /* add another bps bits to the buffer */
4482 bytebuff1
= bytebuff2
= 0;
4483 buff2
= (buff2
| (buff1
>> ready_bits
));
4484 strcpy (action
, "Update");
4488 if ((dumpfile
!= NULL
) && (level
== 3))
4490 dump_info (dumpfile
, format
, "",
4491 "Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4492 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
4493 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
4494 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
4495 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
4496 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
4497 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
4498 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
4499 dump_info (dumpfile
, format
, "","Ready bits: %d, %s", ready_bits
, action
);
4504 /* catch any trailing bits at the end of the line */
4505 while (ready_bits
> 0)
4507 bytebuff1
= (buff2
>> 24);
4510 buff2
= (buff2
<< 8);
4511 bytebuff2
= bytebuff1
;
4515 if ((dumpfile
!= NULL
) && (level
== 3))
4517 dump_info (dumpfile
, format
, "",
4518 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4519 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
4521 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
4522 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
4523 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
4524 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
4525 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
4526 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
4527 dump_info (dumpfile
, format
, "", "Ready bits: %2d", ready_bits
);
4530 if ((dumpfile
!= NULL
) && (level
== 2))
4532 dump_info (dumpfile
, format
, "combineSeparateTileSamples24bits","Output data");
4533 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
+ (row
* dst_rowsize
));
4538 } /* end combineSeparateTileSamples24bits */
4541 combineSeparateTileSamples32bits (uint8
*in
[], uint8
*out
, uint32 cols
,
4542 uint32 rows
, uint32 imagewidth
,
4543 uint32 tw
, uint16 spp
, uint16 bps
,
4544 FILE *dumpfile
, int format
, int level
)
4546 int ready_bits
= 0, shift_width
= 0;
4547 uint32 src_rowsize
, dst_rowsize
, bit_offset
, src_offset
;
4548 uint32 src_byte
= 0, src_bit
= 0;
4550 uint32 longbuff1
= 0, longbuff2
= 0;
4551 uint64 maskbits
= 0, matchbits
= 0;
4552 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
4553 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
4555 unsigned char *src
= in
[0];
4556 unsigned char *dst
= out
;
4559 if ((src
== NULL
) || (dst
== NULL
))
4561 TIFFError("combineSeparateTileSamples32bits","Invalid input or output buffer");
4565 src_rowsize
= ((bps
* tw
) + 7) / 8;
4566 dst_rowsize
= ((imagewidth
* bps
* spp
) + 7) / 8;
4567 maskbits
= (uint64
)-1 >> ( 64 - bps
);
4568 shift_width
= ((bps
+ 7) / 8) + 1;
4570 for (row
= 0; row
< rows
; row
++)
4574 dst
= out
+ (row
* dst_rowsize
);
4575 src_offset
= row
* src_rowsize
;
4576 for (col
= 0; col
< cols
; col
++)
4578 /* Compute src byte(s) and bits within byte(s) */
4579 bit_offset
= col
* bps
;
4580 src_byte
= bit_offset
/ 8;
4581 src_bit
= bit_offset
% 8;
4583 matchbits
= maskbits
<< (64 - src_bit
- bps
);
4584 for (s
= 0; s
< spp
; s
++)
4586 src
= in
[s
] + src_offset
+ src_byte
;
4589 longbuff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
4590 longbuff2
= longbuff1
;
4594 longbuff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
4595 longbuff2
= longbuff1
;
4598 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
4599 buff1
= (buff3
& matchbits
) << (src_bit
);
4601 /* If we have a full buffer's worth, write it out */
4602 if (ready_bits
>= 32)
4604 bytebuff1
= (buff2
>> 56);
4606 bytebuff2
= (buff2
>> 48);
4608 bytebuff3
= (buff2
>> 40);
4610 bytebuff4
= (buff2
>> 32);
4614 /* shift in new bits */
4615 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
4616 strcpy (action
, "Flush");
4619 { /* add another bps bits to the buffer */
4620 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
4621 buff2
= (buff2
| (buff1
>> ready_bits
));
4622 strcpy (action
, "Update");
4626 if ((dumpfile
!= NULL
) && (level
== 3))
4628 dump_info (dumpfile
, format
, "",
4629 "Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
4630 row
+ 1, col
+ 1, s
, src_byte
, src_bit
, dst
- out
);
4631 dump_wide (dumpfile
, format
, "Match bits ", matchbits
);
4632 dump_data (dumpfile
, format
, "Src bits ", src
, 8);
4633 dump_wide (dumpfile
, format
, "Buff1 bits ", buff1
);
4634 dump_wide (dumpfile
, format
, "Buff2 bits ", buff2
);
4635 dump_info (dumpfile
, format
, "", "Ready bits: %d, %s", ready_bits
, action
);
4639 while (ready_bits
> 0)
4641 bytebuff1
= (buff2
>> 56);
4643 buff2
= (buff2
<< 8);
4647 if ((dumpfile
!= NULL
) && (level
== 3))
4649 dump_info (dumpfile
, format
, "",
4650 "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
4651 row
+ 1, col
+ 1, src_byte
, src_bit
, dst
- out
);
4653 dump_long (dumpfile
, format
, "Match bits ", matchbits
);
4654 dump_data (dumpfile
, format
, "Src bits ", src
, 4);
4655 dump_long (dumpfile
, format
, "Buff1 bits ", buff1
);
4656 dump_long (dumpfile
, format
, "Buff2 bits ", buff2
);
4657 dump_byte (dumpfile
, format
, "Write bits1", bytebuff1
);
4658 dump_byte (dumpfile
, format
, "Write bits2", bytebuff2
);
4659 dump_info (dumpfile
, format
, "", "Ready bits: %2d", ready_bits
);
4662 if ((dumpfile
!= NULL
) && (level
== 2))
4664 dump_info (dumpfile
, format
, "combineSeparateTileSamples32bits","Output data");
4665 dump_buffer(dumpfile
, format
, 1, dst_rowsize
, row
, out
);
4670 } /* end combineSeparateTileSamples32bits */
4673 static int readSeparateStripsIntoBuffer (TIFF
*in
, uint8
*obuf
, uint32 length
,
4674 uint32 width
, uint16 spp
,
4675 struct dump_opts
*dump
)
4677 int i
, j
, bytes_per_sample
, bytes_per_pixel
, shift_width
, result
= 1;
4678 int32 bytes_read
= 0;
4679 uint16 bps
, nstrips
, planar
, strips_per_sample
;
4680 uint32 src_rowsize
, dst_rowsize
, rows_processed
, rps
;
4681 uint32 rows_this_strip
= 0;
4684 tsize_t scanlinesize
= TIFFScanlineSize(in
);
4685 tsize_t stripsize
= TIFFStripSize(in
);
4686 unsigned char *srcbuffs
[MAX_SAMPLES
];
4687 unsigned char *buff
= NULL
;
4688 unsigned char *dst
= NULL
;
4692 TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
4696 memset (srcbuffs
, '\0', sizeof(srcbuffs
));
4697 TIFFGetField(in
, TIFFTAG_BITSPERSAMPLE
, &bps
);
4698 TIFFGetFieldDefaulted(in
, TIFFTAG_PLANARCONFIG
, &planar
);
4699 TIFFGetFieldDefaulted(in
, TIFFTAG_ROWSPERSTRIP
, &rps
);
4703 bytes_per_sample
= (bps
+ 7) / 8;
4704 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
4705 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
4706 shift_width
= bytes_per_pixel
;
4708 shift_width
= bytes_per_sample
+ 1;
4710 src_rowsize
= ((bps
* width
) + 7) / 8;
4711 dst_rowsize
= ((bps
* width
* spp
) + 7) / 8;
4714 if ((dump
->infile
!= NULL
) && (dump
->level
== 3))
4716 dump_info (dump
->infile
, dump
->format
, "",
4717 "Image width %d, length %d, Scanline size, %4d bytes",
4718 width
, length
, scanlinesize
);
4719 dump_info (dump
->infile
, dump
->format
, "",
4720 "Bits per sample %d, Samples per pixel %d, Shift width %d",
4721 bps
, spp
, shift_width
);
4724 /* Libtiff seems to assume/require that data for separate planes are
4725 * written one complete plane after another and not interleaved in any way.
4726 * Multiple scanlines and possibly strips of the same plane must be
4727 * written before data for any other plane.
4729 nstrips
= TIFFNumberOfStrips(in
);
4730 strips_per_sample
= nstrips
/spp
;
4732 for (s
= 0; (s
< spp
) && (s
< MAX_SAMPLES
); s
++)
4735 buff
= _TIFFmalloc(stripsize
);
4738 TIFFError ("readSeparateStripsIntoBuffer",
4739 "Unable to allocate strip read buffer for sample %d", s
);
4740 for (i
= 0; i
< s
; i
++)
4741 _TIFFfree (srcbuffs
[i
]);
4748 for (j
= 0; (j
< strips_per_sample
) && (result
== 1); j
++)
4750 for (s
= 0; (s
< spp
) && (s
< MAX_SAMPLES
); s
++)
4753 strip
= (s
* strips_per_sample
) + j
;
4754 bytes_read
= TIFFReadEncodedStrip (in
, strip
, buff
, stripsize
);
4755 rows_this_strip
= bytes_read
/ src_rowsize
;
4756 if (bytes_read
< 0 && !ignore
)
4758 TIFFError(TIFFFileName(in
),
4759 "Error, can't read strip %lu for sample %d",
4760 (unsigned long) strip
, s
+ 1);
4765 TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d",
4766 strip
, bytes_read
, rows_this_strip
, shift_width
);
4770 if (rps
> rows_this_strip
)
4771 rps
= rows_this_strip
;
4772 dst
= obuf
+ (dst_rowsize
* rows_processed
);
4775 if (combineSeparateSamplesBytes (srcbuffs
, dst
, width
, rps
,
4776 spp
, bps
, dump
->infile
,
4777 dump
->format
, dump
->level
))
4785 switch (shift_width
)
4787 case 1: if (combineSeparateSamples8bits (srcbuffs
, dst
, width
, rps
,
4788 spp
, bps
, dump
->infile
,
4789 dump
->format
, dump
->level
))
4795 case 2: if (combineSeparateSamples16bits (srcbuffs
, dst
, width
, rps
,
4796 spp
, bps
, dump
->infile
,
4797 dump
->format
, dump
->level
))
4803 case 3: if (combineSeparateSamples24bits (srcbuffs
, dst
, width
, rps
,
4804 spp
, bps
, dump
->infile
,
4805 dump
->format
, dump
->level
))
4815 case 8: if (combineSeparateSamples32bits (srcbuffs
, dst
, width
, rps
,
4816 spp
, bps
, dump
->infile
,
4817 dump
->format
, dump
->level
))
4823 default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps
);
4829 if ((rows_processed
+ rps
) > length
)
4831 rows_processed
= length
;
4832 rps
= length
- rows_processed
;
4835 rows_processed
+= rps
;
4838 /* free any buffers allocated for each plane or scanline and
4839 * any temporary buffers
4841 for (s
= 0; (s
< spp
) && (s
< MAX_SAMPLES
); s
++)
4849 } /* end readSeparateStripsIntoBuffer */
4852 get_page_geometry (char *name
, struct pagedef
*page
)
4857 for (ptr
= name
; *ptr
; ptr
++)
4858 *ptr
= (char)tolower((int)*ptr
);
4860 for (n
= 0; n
< MAX_PAPERNAMES
; n
++)
4862 if (strcmp(name
, PaperTable
[n
].name
) == 0)
4864 page
->width
= PaperTable
[n
].width
;
4865 page
->length
= PaperTable
[n
].length
;
4866 strncpy (page
->name
, PaperTable
[n
].name
, 15);
4867 page
->name
[15] = '\0';
4877 initPageSetup (struct pagedef
*page
, struct pageseg
*pagelist
,
4878 struct buffinfo seg_buffs
[])
4882 strcpy (page
->name
, "");
4883 page
->mode
= PAGE_MODE_NONE
;
4884 page
->res_unit
= RESUNIT_NONE
;
4889 page
->hmargin
= 0.0;
4890 page
->vmargin
= 0.0;
4893 page
->orient
= ORIENTATION_NONE
;
4895 for (i
= 0; i
< MAX_SECTIONS
; i
++)
4897 pagelist
[i
].x1
= (uint32
)0;
4898 pagelist
[i
].x2
= (uint32
)0;
4899 pagelist
[i
].y1
= (uint32
)0;
4900 pagelist
[i
].y2
= (uint32
)0;
4901 pagelist
[i
].buffsize
= (uint32
)0;
4902 pagelist
[i
].position
= 0;
4903 pagelist
[i
].total
= 0;
4906 for (i
= 0; i
< MAX_OUTBUFFS
; i
++)
4908 seg_buffs
[i
].size
= 0;
4909 seg_buffs
[i
].buffer
= NULL
;
4914 initImageData (struct image_data
*image
)
4920 image
->res_unit
= RESUNIT_NONE
;
4924 image
->photometric
= 0;
4925 image
->orientation
= 0;
4926 image
->compression
= COMPRESSION_NONE
;
4927 image
->adjustments
= 0;
4931 initCropMasks (struct crop_mask
*cps
)
4935 cps
->crop_mode
= CROP_NONE
;
4936 cps
->res_unit
= RESUNIT_NONE
;
4937 cps
->edge_ref
= EDGE_TOP
;
4940 for (i
= 0; i
< 4; i
++)
4941 cps
->margins
[i
] = 0.0;
4942 cps
->bufftotal
= (uint32
)0;
4943 cps
->combined_width
= (uint32
)0;
4944 cps
->combined_length
= (uint32
)0;
4945 cps
->rotation
= (uint16
)0;
4946 cps
->photometric
= INVERT_DATA_AND_TAG
;
4947 cps
->mirror
= (uint16
)0;
4948 cps
->invert
= (uint16
)0;
4949 cps
->zones
= (uint32
)0;
4950 cps
->regions
= (uint32
)0;
4951 for (i
= 0; i
< MAX_REGIONS
; i
++)
4953 cps
->corners
[i
].X1
= 0.0;
4954 cps
->corners
[i
].X2
= 0.0;
4955 cps
->corners
[i
].Y1
= 0.0;
4956 cps
->corners
[i
].Y2
= 0.0;
4957 cps
->regionlist
[i
].x1
= 0;
4958 cps
->regionlist
[i
].x2
= 0;
4959 cps
->regionlist
[i
].y1
= 0;
4960 cps
->regionlist
[i
].y2
= 0;
4961 cps
->regionlist
[i
].width
= 0;
4962 cps
->regionlist
[i
].length
= 0;
4963 cps
->regionlist
[i
].buffsize
= 0;
4964 cps
->regionlist
[i
].buffptr
= NULL
;
4965 cps
->zonelist
[i
].position
= 0;
4966 cps
->zonelist
[i
].total
= 0;
4968 cps
->exp_mode
= ONE_FILE_COMPOSITE
;
4969 cps
->img_mode
= COMPOSITE_IMAGES
;
4972 static void initDumpOptions(struct dump_opts
*dump
)
4975 dump
->format
= DUMP_NONE
;
4977 sprintf (dump
->mode
, "w");
4978 memset (dump
->infilename
, '\0', PATH_MAX
+ 1);
4979 memset (dump
->outfilename
, '\0',PATH_MAX
+ 1);
4980 dump
->infile
= NULL
;
4981 dump
->outfile
= NULL
;
4984 /* Compute pixel offsets into the image for margins and fixed regions */
4986 computeInputPixelOffsets(struct crop_mask
*crop
, struct image_data
*image
,
4991 /* Values for these offsets are in pixels from start of image, not bytes,
4992 * and are indexed from zero to width - 1 or length - 1 */
4993 uint32 tmargin
, bmargin
, lmargin
, rmargin
;
4994 uint32 startx
, endx
; /* offsets of first and last columns to extract */
4995 uint32 starty
, endy
; /* offsets of first and last row to extract */
4996 uint32 width
, length
, crop_width
, crop_length
;
4997 uint32 i
, max_width
, max_length
, zwidth
, zlength
, buffsize
;
4998 uint32 x1
, x2
, y1
, y2
;
5000 if (image
->res_unit
!= RESUNIT_INCH
&& image
->res_unit
!= RESUNIT_CENTIMETER
)
5007 if (((image
->xres
== 0) || (image
->yres
== 0)) &&
5008 (crop
->res_unit
!= RESUNIT_NONE
) &&
5009 ((crop
->crop_mode
& CROP_REGIONS
) || (crop
->crop_mode
& CROP_MARGINS
) ||
5010 (crop
->crop_mode
& CROP_LENGTH
) || (crop
->crop_mode
& CROP_WIDTH
)))
5012 TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
5013 TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
5020 /* Translate user units to image units */
5022 switch (crop
->res_unit
) {
5023 case RESUNIT_CENTIMETER
:
5024 if (image
->res_unit
== RESUNIT_INCH
)
5028 if (image
->res_unit
== RESUNIT_CENTIMETER
)
5031 case RESUNIT_NONE
: /* Dimensions in pixels */
5036 if (crop
->crop_mode
& CROP_REGIONS
)
5038 max_width
= max_length
= 0;
5039 for (i
= 0; i
< crop
->regions
; i
++)
5041 if ((crop
->res_unit
== RESUNIT_INCH
) || (crop
->res_unit
== RESUNIT_CENTIMETER
))
5043 x1
= (uint32
) (crop
->corners
[i
].X1
* scale
* xres
);
5044 x2
= (uint32
) (crop
->corners
[i
].X2
* scale
* xres
);
5045 y1
= (uint32
) (crop
->corners
[i
].Y1
* scale
* yres
);
5046 y2
= (uint32
) (crop
->corners
[i
].Y2
* scale
* yres
);
5050 x1
= (uint32
) (crop
->corners
[i
].X1
);
5051 x2
= (uint32
) (crop
->corners
[i
].X2
);
5052 y1
= (uint32
) (crop
->corners
[i
].Y1
);
5053 y2
= (uint32
) (crop
->corners
[i
].Y2
);
5056 crop
->regionlist
[i
].x1
= 0;
5058 crop
->regionlist
[i
].x1
= (uint32
) (x1
- 1);
5060 if (x2
> image
->width
- 1)
5061 crop
->regionlist
[i
].x2
= image
->width
- 1;
5063 crop
->regionlist
[i
].x2
= (uint32
) (x2
- 1);
5064 zwidth
= crop
->regionlist
[i
].x2
- crop
->regionlist
[i
].x1
+ 1;
5067 crop
->regionlist
[i
].y1
= 0;
5069 crop
->regionlist
[i
].y1
= (uint32
) (y1
- 1);
5071 if (y2
> image
->length
- 1)
5072 crop
->regionlist
[i
].y2
= image
->length
- 1;
5074 crop
->regionlist
[i
].y2
= (uint32
) (y2
- 1);
5076 zlength
= crop
->regionlist
[i
].y2
- crop
->regionlist
[i
].y1
+ 1;
5078 if (zwidth
> max_width
)
5080 if (zlength
> max_length
)
5081 max_length
= zlength
;
5084 (((zwidth
* image
->bps
* image
->spp
+ 7 ) / 8) * (zlength
+ 1));
5086 crop
->regionlist
[i
].buffsize
= buffsize
;
5087 crop
->bufftotal
+= buffsize
;
5088 if (crop
->img_mode
== COMPOSITE_IMAGES
)
5090 switch (crop
->edge_ref
)
5094 crop
->combined_length
= zlength
;
5095 crop
->combined_width
+= zwidth
;
5098 case EDGE_TOP
: /* width from left, length from top */
5100 crop
->combined_width
= zwidth
;
5101 crop
->combined_length
+= zlength
;
5109 /* Convert crop margins into offsets into image
5110 * Margins are expressed as pixel rows and columns, not bytes
5112 if (crop
->crop_mode
& CROP_MARGINS
)
5114 if (crop
->res_unit
!= RESUNIT_INCH
&& crop
->res_unit
!= RESUNIT_CENTIMETER
)
5115 { /* User has specified pixels as reference unit */
5116 tmargin
= (uint32
)(crop
->margins
[0]);
5117 lmargin
= (uint32
)(crop
->margins
[1]);
5118 bmargin
= (uint32
)(crop
->margins
[2]);
5119 rmargin
= (uint32
)(crop
->margins
[3]);
5122 { /* inches or centimeters specified */
5123 tmargin
= (uint32
)(crop
->margins
[0] * scale
* yres
);
5124 lmargin
= (uint32
)(crop
->margins
[1] * scale
* xres
);
5125 bmargin
= (uint32
)(crop
->margins
[2] * scale
* yres
);
5126 rmargin
= (uint32
)(crop
->margins
[3] * scale
* xres
);
5129 if ((lmargin
+ rmargin
) > image
->width
)
5131 TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
5132 lmargin
= (uint32
) 0;
5133 rmargin
= (uint32
) 0;
5136 if ((tmargin
+ bmargin
) > image
->length
)
5138 TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length");
5139 tmargin
= (uint32
) 0;
5140 bmargin
= (uint32
) 0;
5145 { /* no margins requested */
5146 tmargin
= (uint32
) 0;
5147 lmargin
= (uint32
) 0;
5148 bmargin
= (uint32
) 0;
5149 rmargin
= (uint32
) 0;
5152 /* Width, height, and margins are expressed as pixel offsets into image */
5153 if (crop
->res_unit
!= RESUNIT_INCH
&& crop
->res_unit
!= RESUNIT_CENTIMETER
)
5155 if (crop
->crop_mode
& CROP_WIDTH
)
5156 width
= (uint32
)crop
->width
;
5158 width
= image
->width
- lmargin
- rmargin
;
5160 if (crop
->crop_mode
& CROP_LENGTH
)
5161 length
= (uint32
)crop
->length
;
5163 length
= image
->length
- tmargin
- bmargin
;
5167 if (crop
->crop_mode
& CROP_WIDTH
)
5168 width
= (uint32
)(crop
->width
* scale
* image
->xres
);
5170 width
= image
->width
- lmargin
- rmargin
;
5172 if (crop
->crop_mode
& CROP_LENGTH
)
5173 length
= (uint32
)(crop
->length
* scale
* image
->yres
);
5175 length
= image
->length
- tmargin
- bmargin
;
5178 off
->tmargin
= tmargin
;
5179 off
->bmargin
= bmargin
;
5180 off
->lmargin
= lmargin
;
5181 off
->rmargin
= rmargin
;
5183 /* Calculate regions defined by margins, width, and length.
5184 * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
5185 * since they are used to compute offsets into buffers */
5186 switch (crop
->edge_ref
) {
5189 if ((startx
+ width
) >= (image
->width
- rmargin
))
5190 endx
= image
->width
- rmargin
- 1;
5192 endx
= startx
+ width
- 1;
5194 endy
= image
->length
- bmargin
- 1;
5195 if ((endy
- length
) <= tmargin
)
5198 starty
= endy
- length
+ 1;
5201 endx
= image
->width
- rmargin
- 1;
5202 if ((endx
- width
) <= lmargin
)
5205 startx
= endx
- width
+ 1;
5208 if ((starty
+ length
) >= (image
->length
- bmargin
))
5209 endy
= image
->length
- bmargin
- 1;
5211 endy
= starty
+ length
- 1;
5213 case EDGE_TOP
: /* width from left, length from top */
5217 if ((startx
+ width
) >= (image
->width
- rmargin
))
5218 endx
= image
->width
- rmargin
- 1;
5220 endx
= startx
+ width
- 1;
5223 if ((starty
+ length
) >= (image
->length
- bmargin
))
5224 endy
= image
->length
- bmargin
- 1;
5226 endy
= starty
+ length
- 1;
5229 off
->startx
= startx
;
5230 off
->starty
= starty
;
5234 crop_width
= endx
- startx
+ 1;
5235 crop_length
= endy
- starty
+ 1;
5237 if (crop_width
<= 0)
5239 TIFFError("computeInputPixelOffsets",
5240 "Invalid left/right margins and /or image crop width requested");
5243 if (crop_width
> image
->width
)
5244 crop_width
= image
->width
;
5246 if (crop_length
<= 0)
5248 TIFFError("computeInputPixelOffsets",
5249 "Invalid top/bottom margins and /or image crop length requested");
5252 if (crop_length
> image
->length
)
5253 crop_length
= image
->length
;
5255 off
->crop_width
= crop_width
;
5256 off
->crop_length
= crop_length
;
5259 } /* end computeInputPixelOffsets */
5262 * Translate crop options into pixel offsets for one or more regions of the image.
5263 * Options are applied in this order: margins, specific width and length, zones,
5264 * but all are optional. Margins are relative to each edge. Width, length and
5265 * zones are relative to the specified reference edge. Zones are expressed as
5266 * X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
5267 * 2:3 would indicate the middle third of the region qualified by margins and
5268 * any explicit width and length specified. Regions are specified by coordinates
5269 * of the top left and lower right corners with range 1 to width or height.
5273 getCropOffsets(struct image_data
*image
, struct crop_mask
*crop
, struct dump_opts
*dump
)
5275 struct offset offsets
;
5278 uint32 seg
, total
, need_buff
= 0;
5280 uint32 zwidth
, zlength
;
5282 memset(&offsets
, '\0', sizeof(struct offset
));
5283 crop
->bufftotal
= 0;
5284 crop
->combined_width
= (uint32
)0;
5285 crop
->combined_length
= (uint32
)0;
5286 crop
->selections
= 0;
5288 /* Compute pixel offsets if margins or fixed width or length specified */
5289 if ((crop
->crop_mode
& CROP_MARGINS
) ||
5290 (crop
->crop_mode
& CROP_REGIONS
) ||
5291 (crop
->crop_mode
& CROP_LENGTH
) ||
5292 (crop
->crop_mode
& CROP_WIDTH
))
5294 if (computeInputPixelOffsets(crop
, image
, &offsets
))
5296 TIFFError ("getCropOffsets", "Unable to compute crop margins");
5300 crop
->selections
= crop
->regions
;
5301 /* Regions are only calculated from top and left edges with no margins */
5302 if (crop
->crop_mode
& CROP_REGIONS
)
5306 { /* cropped area is the full image */
5307 offsets
.tmargin
= 0;
5308 offsets
.lmargin
= 0;
5309 offsets
.bmargin
= 0;
5310 offsets
.rmargin
= 0;
5311 offsets
.crop_width
= image
->width
;
5312 offsets
.crop_length
= image
->length
;
5314 offsets
.endx
= image
->width
- 1;
5316 offsets
.endy
= image
->length
- 1;
5320 if (dump
->outfile
!= NULL
)
5322 dump_info (dump
->outfile
, dump
->format
, "", "Margins: Top: %d Left: %d Bottom: %d Right: %d",
5323 offsets
.tmargin
, offsets
.lmargin
, offsets
.bmargin
, offsets
.rmargin
);
5324 dump_info (dump
->outfile
, dump
->format
, "", "Crop region within margins: Adjusted Width: %6d Length: %6d",
5325 offsets
.crop_width
, offsets
.crop_length
);
5328 if (!(crop
->crop_mode
& CROP_ZONES
)) /* no crop zones requested */
5330 if (need_buff
== FALSE
) /* No margins or fixed width or length areas */
5332 crop
->selections
= 0;
5333 crop
->combined_width
= image
->width
;
5334 crop
->combined_length
= image
->length
;
5339 /* Use one region for margins and fixed width or length areas
5340 * even though it was not formally declared as a region.
5342 crop
->selections
= 1;
5344 crop
->zonelist
[0].total
= 1;
5345 crop
->zonelist
[0].position
= 1;
5349 crop
->selections
= crop
->zones
;
5351 for (i
= 0; i
< crop
->zones
; i
++)
5353 seg
= crop
->zonelist
[i
].position
;
5354 total
= crop
->zonelist
[i
].total
;
5356 switch (crop
->edge_ref
)
5358 case EDGE_LEFT
: /* zones from left to right, length from top */
5359 zlength
= offsets
.crop_length
;
5360 crop
->regionlist
[i
].y1
= offsets
.starty
;
5361 crop
->regionlist
[i
].y2
= offsets
.endy
;
5363 crop
->regionlist
[i
].x1
= offsets
.startx
+
5364 (uint32
)(offsets
.crop_width
* 1.0 * (seg
- 1) / total
);
5365 test
= (int32
)offsets
.startx
+
5366 (int32
)(offsets
.crop_width
* 1.0 * seg
/ total
);
5368 crop
->regionlist
[i
].x2
= 0;
5371 if (test
> (int32
)(image
->width
- 1))
5372 crop
->regionlist
[i
].x2
= image
->width
- 1;
5374 crop
->regionlist
[i
].x2
= test
- 1;
5376 zwidth
= crop
->regionlist
[i
].x2
- crop
->regionlist
[i
].x1
+ 1;
5378 /* This is passed to extractCropZone or extractCompositeZones */
5379 crop
->combined_length
= (uint32
)zlength
;
5380 if (crop
->exp_mode
== COMPOSITE_IMAGES
)
5381 crop
->combined_width
+= (uint32
)zwidth
;
5383 crop
->combined_width
= (uint32
)zwidth
;
5385 case EDGE_BOTTOM
: /* width from left, zones from bottom to top */
5386 zwidth
= offsets
.crop_width
;
5387 crop
->regionlist
[i
].x1
= offsets
.startx
;
5388 crop
->regionlist
[i
].x2
= offsets
.endx
;
5390 test
= offsets
.endy
- (uint32
)(offsets
.crop_length
* 1.0 * seg
/ total
);
5392 crop
->regionlist
[i
].y1
= 0;
5394 crop
->regionlist
[i
].y1
= test
+ 1;
5396 test
= offsets
.endy
- (offsets
.crop_length
* 1.0 * (seg
- 1) / total
);
5398 crop
->regionlist
[i
].y2
= 0;
5401 if (test
> (int32
)(image
->length
- 1))
5402 crop
->regionlist
[i
].y2
= image
->length
- 1;
5404 crop
->regionlist
[i
].y2
= test
;
5406 zlength
= crop
->regionlist
[i
].y2
- crop
->regionlist
[i
].y1
+ 1;
5408 /* This is passed to extractCropZone or extractCompositeZones */
5409 if (crop
->exp_mode
== COMPOSITE_IMAGES
)
5410 crop
->combined_length
+= (uint32
)zlength
;
5412 crop
->combined_length
= (uint32
)zlength
;
5413 crop
->combined_width
= (uint32
)zwidth
;
5415 case EDGE_RIGHT
: /* zones from right to left, length from top */
5416 zlength
= offsets
.crop_length
;
5417 crop
->regionlist
[i
].y1
= offsets
.starty
;
5418 crop
->regionlist
[i
].y2
= offsets
.endy
;
5420 crop
->regionlist
[i
].x1
= offsets
.startx
+
5421 (uint32
)(offsets
.crop_width
* (total
- seg
) * 1.0 / total
);
5422 test
= offsets
.startx
+
5423 (offsets
.crop_width
* (total
- seg
+ 1) * 1.0 / total
);
5425 crop
->regionlist
[i
].x2
= 0;
5428 if (test
> (int32
)(image
->width
- 1))
5429 crop
->regionlist
[i
].x2
= image
->width
- 1;
5431 crop
->regionlist
[i
].x2
= test
- 1;
5433 zwidth
= crop
->regionlist
[i
].x2
- crop
->regionlist
[i
].x1
+ 1;
5435 /* This is passed to extractCropZone or extractCompositeZones */
5436 crop
->combined_length
= (uint32
)zlength
;
5437 if (crop
->exp_mode
== COMPOSITE_IMAGES
)
5438 crop
->combined_width
+= (uint32
)zwidth
;
5440 crop
->combined_width
= (uint32
)zwidth
;
5442 case EDGE_TOP
: /* width from left, zones from top to bottom */
5444 zwidth
= offsets
.crop_width
;
5445 crop
->regionlist
[i
].x1
= offsets
.startx
;
5446 crop
->regionlist
[i
].x2
= offsets
.endx
;
5448 crop
->regionlist
[i
].y1
= offsets
.starty
+ (uint32
)(offsets
.crop_length
* 1.0 * (seg
- 1) / total
);
5449 test
= offsets
.starty
+ (uint32
)(offsets
.crop_length
* 1.0 * seg
/ total
);
5451 crop
->regionlist
[i
].y2
= 0;
5454 if (test
> (int32
)(image
->length
- 1))
5455 crop
->regionlist
[i
].y2
= image
->length
- 1;
5457 crop
->regionlist
[i
].y2
= test
- 1;
5459 zlength
= crop
->regionlist
[i
].y2
- crop
->regionlist
[i
].y1
+ 1;
5461 /* This is passed to extractCropZone or extractCompositeZones */
5462 if (crop
->exp_mode
== COMPOSITE_IMAGES
)
5463 crop
->combined_length
+= (uint32
)zlength
;
5465 crop
->combined_length
= (uint32
)zlength
;
5466 crop
->combined_width
= (uint32
)zwidth
;
5468 } /* end switch statement */
5471 ((((zwidth
* image
->bps
* image
->spp
) + 7 ) / 8) * (zlength
+ 1));
5472 crop
->regionlist
[i
].width
= (uint32
) zwidth
;
5473 crop
->regionlist
[i
].length
= (uint32
) zlength
;
5474 crop
->regionlist
[i
].buffsize
= buffsize
;
5475 crop
->bufftotal
+= buffsize
;
5478 if (dump
->outfile
!= NULL
)
5479 dump_info (dump
->outfile
, dump
->format
, "", "Zone %d, width: %4d, length: %4d, x1: %4d x2: %4d y1: %4d y2: %4d",
5480 i
+ 1, (uint32
)zwidth
, (uint32
)zlength
,
5481 crop
->regionlist
[i
].x1
, crop
->regionlist
[i
].x2
,
5482 crop
->regionlist
[i
].y1
, crop
->regionlist
[i
].y2
);
5486 } /* end getCropOffsets */
5490 computeOutputPixelOffsets (struct crop_mask
*crop
, struct image_data
*image
,
5491 struct pagedef
*page
, struct pageseg
*sections
,
5492 struct dump_opts
* dump
)
5495 double pwidth
, plength
; /* Output page width and length in user units*/
5496 uint32 iwidth
, ilength
; /* Input image width and length in pixels*/
5497 uint32 owidth
, olength
; /* Output image width and length in pixels*/
5498 uint32 orows
, ocols
; /* rows and cols for output */
5499 uint32 hmargin
, vmargin
; /* Horizontal and vertical margins */
5500 uint32 x1
, x2
, y1
, y2
, line_bytes
;
5501 unsigned int orientation
;
5505 if (page
->res_unit
== RESUNIT_NONE
)
5506 page
->res_unit
= image
->res_unit
;
5508 switch (image
->res_unit
) {
5509 case RESUNIT_CENTIMETER
:
5510 if (page
->res_unit
== RESUNIT_INCH
)
5514 if (page
->res_unit
== RESUNIT_CENTIMETER
)
5517 case RESUNIT_NONE
: /* Dimensions in pixels */
5522 /* get width, height, resolutions of input image selection */
5523 if (crop
->combined_width
> 0)
5524 iwidth
= crop
->combined_width
;
5526 iwidth
= image
->width
;
5527 if (crop
->combined_length
> 0)
5528 ilength
= crop
->combined_length
;
5530 ilength
= image
->length
;
5532 if (page
->hres
<= 1.0)
5533 page
->hres
= image
->xres
;
5534 if (page
->vres
<= 1.0)
5535 page
->vres
= image
->yres
;
5537 if ((page
->hres
< 1.0) || (page
->vres
< 1.0))
5539 TIFFError("computeOutputPixelOffsets",
5540 "Invalid horizontal or vertical resolution specified or read from input image");
5544 /* If no page sizes are being specified, we just use the input image size to
5545 * calculate maximum margins that can be taken from image.
5547 if (page
->width
<= 0)
5550 pwidth
= page
->width
;
5552 if (page
->length
<= 0)
5555 plength
= page
->length
;
5559 TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
5560 "Hmargin: %3.2f, Vmargin: %3.2f",
5561 page
->name
, page
->vres
, page
->hres
,
5562 page
->hmargin
, page
->vmargin
);
5563 TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f",
5564 page
->res_unit
, scale
, pwidth
, plength
);
5567 /* compute margins at specified unit and resolution */
5568 if (page
->mode
& PAGE_MODE_MARGINS
)
5570 if (page
->res_unit
== RESUNIT_INCH
|| page
->res_unit
== RESUNIT_CENTIMETER
)
5571 { /* inches or centimeters specified */
5572 hmargin
= (uint32
)(page
->hmargin
* scale
* page
->hres
* ((image
->bps
+ 7)/ 8));
5573 vmargin
= (uint32
)(page
->vmargin
* scale
* page
->vres
* ((image
->bps
+ 7)/ 8));
5576 { /* Otherwise user has specified pixels as reference unit */
5577 hmargin
= (uint32
)(page
->hmargin
* scale
* ((image
->bps
+ 7)/ 8));
5578 vmargin
= (uint32
)(page
->vmargin
* scale
* ((image
->bps
+ 7)/ 8));
5581 if ((hmargin
* 2.0) > (pwidth
* page
->hres
))
5583 TIFFError("computeOutputPixelOffsets",
5584 "Combined left and right margins exceed page width");
5585 hmargin
= (uint32
) 0;
5588 if ((vmargin
* 2.0) > (plength
* page
->vres
))
5590 TIFFError("computeOutputPixelOffsets",
5591 "Combined top and bottom margins exceed page length");
5592 vmargin
= (uint32
) 0;
5602 if (page
->mode
& PAGE_MODE_ROWSCOLS
)
5604 /* Maybe someday but not for now */
5605 if (page
->mode
& PAGE_MODE_MARGINS
)
5606 TIFFError("computeOutputPixelOffsets",
5607 "Output margins cannot be specified with rows and columns");
5609 owidth
= TIFFhowmany(iwidth
, page
->cols
);
5610 olength
= TIFFhowmany(ilength
, page
->rows
);
5614 if (page
->mode
& PAGE_MODE_PAPERSIZE
)
5616 owidth
= (uint32
)((pwidth
* page
->hres
) - (hmargin
* 2));
5617 olength
= (uint32
)((plength
* page
->vres
) - (vmargin
* 2));
5621 owidth
= (uint32
)(iwidth
- (hmargin
* 2 * page
->hres
));
5622 olength
= (uint32
)(ilength
- (vmargin
* 2 * page
->vres
));
5626 if (owidth
> iwidth
)
5628 if (olength
> ilength
)
5631 /* Compute the number of pages required for Portrait or Landscape */
5632 switch (page
->orient
)
5634 case ORIENTATION_NONE
:
5635 case ORIENTATION_PORTRAIT
:
5636 ocols
= TIFFhowmany(iwidth
, owidth
);
5637 orows
= TIFFhowmany(ilength
, olength
);
5638 orientation
= ORIENTATION_PORTRAIT
;
5641 case ORIENTATION_LANDSCAPE
:
5642 ocols
= TIFFhowmany(iwidth
, olength
);
5643 orows
= TIFFhowmany(ilength
, owidth
);
5647 orientation
= ORIENTATION_LANDSCAPE
;
5650 case ORIENTATION_AUTO
:
5652 x1
= TIFFhowmany(iwidth
, owidth
);
5653 x2
= TIFFhowmany(ilength
, olength
);
5654 y1
= TIFFhowmany(iwidth
, olength
);
5655 y2
= TIFFhowmany(ilength
, owidth
);
5657 if ( (x1
* x2
) < (y1
* y2
))
5661 orientation
= ORIENTATION_PORTRAIT
;
5670 orientation
= ORIENTATION_LANDSCAPE
;
5679 /* If user did not specify rows and cols, set them from calcuation */
5685 line_bytes
= TIFFhowmany8(owidth
* image
->bps
) * image
->spp
;
5687 if ((page
->rows
* page
->cols
) > MAX_SECTIONS
)
5689 TIFFError("computeOutputPixelOffsets",
5690 "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
5694 /* build the list of offsets for each output section */
5695 for (k
= 0, i
= 0 && k
<= MAX_SECTIONS
; i
< orows
; i
++)
5697 y1
= (uint32
)(olength
* i
);
5698 y2
= (uint32
)(olength
* (i
+ 1) - 1);
5701 for (j
= 0; j
< ocols
; j
++, k
++)
5703 x1
= (uint32
)(owidth
* j
);
5704 x2
= (uint32
)(owidth
* (j
+ 1) - 1);
5707 sections
[k
].x1
= x1
;
5708 sections
[k
].x2
= x2
;
5709 sections
[k
].y1
= y1
;
5710 sections
[k
].y2
= y2
;
5711 sections
[k
].buffsize
= line_bytes
* olength
;
5712 sections
[k
].position
= k
+ 1;
5713 sections
[k
].total
= orows
* ocols
;
5717 } /* end computeOutputPixelOffsets */
5720 loadImage(TIFF
* in
, struct image_data
*image
, struct dump_opts
*dump
, unsigned char **read_ptr
)
5723 float xres
= 0.0, yres
= 0.0;
5724 uint16 nstrips
= 0, ntiles
= 0, planar
= 0;
5725 uint16 bps
= 0, spp
= 0, res_unit
= 0;
5726 uint16 orientation
= 0;
5727 uint16 input_compression
= 0, input_photometric
= 0;
5728 uint16 subsampling_horiz
, subsampling_vert
;
5729 uint32 width
= 0, length
= 0;
5730 uint32 stsize
= 0, tlsize
= 0, buffsize
= 0, scanlinesize
= 0;
5731 uint32 tw
= 0, tl
= 0; /* Tile width and length */
5732 uint32 tile_rowsize
= 0;
5733 unsigned char *read_buff
= NULL
;
5734 unsigned char *new_buff
= NULL
;
5736 static uint32 prev_readsize
= 0;
5738 TIFFGetFieldDefaulted(in
, TIFFTAG_BITSPERSAMPLE
, &bps
);
5739 TIFFGetFieldDefaulted(in
, TIFFTAG_SAMPLESPERPIXEL
, &spp
);
5740 TIFFGetFieldDefaulted(in
, TIFFTAG_PLANARCONFIG
, &planar
);
5741 TIFFGetFieldDefaulted(in
, TIFFTAG_ORIENTATION
, &orientation
);
5742 if (! TIFFGetFieldDefaulted(in
, TIFFTAG_PHOTOMETRIC
, &input_photometric
))
5743 TIFFError("loadImage","Image lacks Photometric interpreation tag");
5744 if (! TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &width
))
5745 TIFFError("loadimage","Image lacks image width tag");
5746 if(! TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &length
))
5747 TIFFError("loadimage","Image lacks image length tag");
5748 TIFFGetFieldDefaulted(in
, TIFFTAG_XRESOLUTION
, &xres
);
5749 TIFFGetFieldDefaulted(in
, TIFFTAG_YRESOLUTION
, &yres
);
5750 if (!TIFFGetFieldDefaulted(in
, TIFFTAG_RESOLUTIONUNIT
, &res_unit
))
5751 res_unit
= RESUNIT_INCH
;
5752 if (!TIFFGetField(in
, TIFFTAG_COMPRESSION
, &input_compression
))
5753 input_compression
= COMPRESSION_NONE
;
5756 char compressionid
[16];
5758 switch (input_compression
)
5760 case COMPRESSION_NONE
: /* 1 dump mode */
5761 strcpy (compressionid
, "None/dump");
5763 case COMPRESSION_CCITTRLE
: /* 2 CCITT modified Huffman RLE */
5764 strcpy (compressionid
, "Huffman RLE");
5766 case COMPRESSION_CCITTFAX3
: /* 3 CCITT Group 3 fax encoding */
5767 strcpy (compressionid
, "Group3 Fax");
5769 case COMPRESSION_CCITTFAX4
: /* 4 CCITT Group 4 fax encoding */
5770 strcpy (compressionid
, "Group4 Fax");
5772 case COMPRESSION_LZW
: /* 5 Lempel-Ziv & Welch */
5773 strcpy (compressionid
, "LZW");
5775 case COMPRESSION_OJPEG
: /* 6 !6.0 JPEG */
5776 strcpy (compressionid
, "Old Jpeg");
5778 case COMPRESSION_JPEG
: /* 7 %JPEG DCT compression */
5779 strcpy (compressionid
, "New Jpeg");
5781 case COMPRESSION_NEXT
: /* 32766 NeXT 2-bit RLE */
5782 strcpy (compressionid
, "Next RLE");
5784 case COMPRESSION_CCITTRLEW
: /* 32771 #1 w/ word alignment */
5785 strcpy (compressionid
, "CITTRLEW");
5787 case COMPRESSION_PACKBITS
: /* 32773 Macintosh RLE */
5788 strcpy (compressionid
, "Mac Packbits");
5790 case COMPRESSION_THUNDERSCAN
: /* 32809 ThunderScan RLE */
5791 strcpy (compressionid
, "Thunderscan");
5793 case COMPRESSION_IT8CTPAD
: /* 32895 IT8 CT w/padding */
5794 strcpy (compressionid
, "IT8 padded");
5796 case COMPRESSION_IT8LW
: /* 32896 IT8 Linework RLE */
5797 strcpy (compressionid
, "IT8 RLE");
5799 case COMPRESSION_IT8MP
: /* 32897 IT8 Monochrome picture */
5800 strcpy (compressionid
, "IT8 mono");
5802 case COMPRESSION_IT8BL
: /* 32898 IT8 Binary line art */
5803 strcpy (compressionid
, "IT8 lineart");
5805 case COMPRESSION_PIXARFILM
: /* 32908 Pixar companded 10bit LZW */
5806 strcpy (compressionid
, "Pixar 10 bit");
5808 case COMPRESSION_PIXARLOG
: /* 32909 Pixar companded 11bit ZIP */
5809 strcpy (compressionid
, "Pixar 11bit");
5811 case COMPRESSION_DEFLATE
: /* 32946 Deflate compression */
5812 strcpy (compressionid
, "Deflate");
5814 case COMPRESSION_ADOBE_DEFLATE
: /* 8 Deflate compression */
5815 strcpy (compressionid
, "Adobe deflate");
5818 strcpy (compressionid
, "None/unknown");
5821 TIFFError("loadImage", "Input compression %s", compressionid
);
5824 scanlinesize
= TIFFScanlineSize(in
);
5827 image
->planar
= planar
;
5828 image
->width
= width
;
5829 image
->length
= length
;
5832 image
->res_unit
= res_unit
;
5833 image
->compression
= input_compression
;
5834 image
->photometric
= input_photometric
;
5836 char photometricid
[12];
5838 switch (input_photometric
)
5840 case PHOTOMETRIC_MINISWHITE
:
5841 strcpy (photometricid
, "MinIsWhite");
5843 case PHOTOMETRIC_MINISBLACK
:
5844 strcpy (photometricid
, "MinIsBlack");
5846 case PHOTOMETRIC_RGB
:
5847 strcpy (photometricid
, "RGB");
5849 case PHOTOMETRIC_PALETTE
:
5850 strcpy (photometricid
, "Palette");
5852 case PHOTOMETRIC_MASK
:
5853 strcpy (photometricid
, "Mask");
5855 case PHOTOMETRIC_SEPARATED
:
5856 strcpy (photometricid
, "Separated");
5858 case PHOTOMETRIC_YCBCR
:
5859 strcpy (photometricid
, "YCBCR");
5861 case PHOTOMETRIC_CIELAB
:
5862 strcpy (photometricid
, "CIELab");
5864 case PHOTOMETRIC_ICCLAB
:
5865 strcpy (photometricid
, "ICCLab");
5867 case PHOTOMETRIC_ITULAB
:
5868 strcpy (photometricid
, "ITULab");
5870 case PHOTOMETRIC_LOGL
:
5871 strcpy (photometricid
, "LogL");
5873 case PHOTOMETRIC_LOGLUV
:
5874 strcpy (photometricid
, "LOGLuv");
5877 strcpy (photometricid
, "Unknown");
5880 TIFFError("loadImage", "Input photometric interpretation %s", photometricid
);
5883 image
->orientation
= orientation
;
5884 switch (orientation
)
5887 case ORIENTATION_TOPLEFT
:
5888 image
->adjustments
= 0;
5890 case ORIENTATION_TOPRIGHT
:
5891 image
->adjustments
= MIRROR_HORIZ
;
5893 case ORIENTATION_BOTRIGHT
:
5894 image
->adjustments
= ROTATECW_180
;
5896 case ORIENTATION_BOTLEFT
:
5897 image
->adjustments
= MIRROR_VERT
;
5899 case ORIENTATION_LEFTTOP
:
5900 image
->adjustments
= MIRROR_VERT
| ROTATECW_90
;
5902 case ORIENTATION_RIGHTTOP
:
5903 image
->adjustments
= ROTATECW_90
;
5905 case ORIENTATION_RIGHTBOT
:
5906 image
->adjustments
= MIRROR_VERT
| ROTATECW_270
;
5908 case ORIENTATION_LEFTBOT
:
5909 image
->adjustments
= ROTATECW_270
;
5912 image
->adjustments
= 0;
5913 image
->orientation
= ORIENTATION_TOPLEFT
;
5916 if ((bps
== 0) || (spp
== 0))
5918 TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
5923 if (TIFFIsTiled(in
))
5926 tlsize
= TIFFTileSize(in
);
5927 ntiles
= TIFFNumberOfTiles(in
);
5928 TIFFGetField(in
, TIFFTAG_TILEWIDTH
, &tw
);
5929 TIFFGetField(in
, TIFFTAG_TILELENGTH
, &tl
);
5931 tile_rowsize
= TIFFTileRowSize(in
);
5932 buffsize
= tlsize
* ntiles
;
5935 if (buffsize
< (uint32
)(ntiles
* tl
* tile_rowsize
))
5937 buffsize
= ntiles
* tl
* tile_rowsize
;
5939 TIFFError("loadImage",
5940 "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
5941 tlsize
, (unsigned long)buffsize
);
5945 if (dump
->infile
!= NULL
)
5946 dump_info (dump
->infile
, dump
->format
, "",
5947 "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
5948 tlsize
, ntiles
, tile_rowsize
);
5953 TIFFGetFieldDefaulted(in
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
5954 stsize
= TIFFStripSize(in
);
5955 nstrips
= TIFFNumberOfStrips(in
);
5956 buffsize
= stsize
* nstrips
;
5958 if (buffsize
< (uint32
) (((length
* width
* spp
* bps
) + 7) / 8))
5960 buffsize
= ((length
* width
* spp
* bps
) + 7) / 8;
5962 TIFFError("loadImage",
5963 "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
5964 stsize
, (unsigned long)buffsize
);
5968 if (dump
->infile
!= NULL
)
5969 dump_info (dump
->infile
, dump
->format
, "",
5970 "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
5971 stsize
, nstrips
, rowsperstrip
, scanlinesize
);
5974 if (input_compression
== COMPRESSION_JPEG
)
5975 { /* Force conversion to RGB */
5976 jpegcolormode
= JPEGCOLORMODE_RGB
;
5977 TIFFSetField(in
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
5979 /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
5981 { /* Otherwise, can't handle subsampled input */
5982 if (input_photometric
== PHOTOMETRIC_YCBCR
)
5984 TIFFGetFieldDefaulted(in
, TIFFTAG_YCBCRSUBSAMPLING
,
5985 &subsampling_horiz
, &subsampling_vert
);
5986 if (subsampling_horiz
!= 1 || subsampling_vert
!= 1)
5988 TIFFError("loadImage",
5989 "Can't copy/convert subsampled image with subsampling %d horiz %d vert",
5990 subsampling_horiz
, subsampling_vert
);
5996 read_buff
= *read_ptr
;
5998 read_buff
= (unsigned char *)_TIFFmalloc(buffsize
);
6001 if (prev_readsize
< buffsize
)
6003 new_buff
= _TIFFrealloc(read_buff
, buffsize
);
6007 read_buff
= (unsigned char *)_TIFFmalloc(buffsize
);
6010 read_buff
= new_buff
;
6016 TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
6020 prev_readsize
= buffsize
;
6021 *read_ptr
= read_buff
;
6023 /* N.B. The read functions used copy separate plane data into a buffer as interleaved
6024 * samples rather than separate planes so the same logic works to extract regions
6025 * regardless of the way the data are organized in the input file.
6029 if (planar
== PLANARCONFIG_CONTIG
)
6031 if (!(readContigStripsIntoBuffer(in
, read_buff
)))
6033 TIFFError("loadImage", "Unable to read contiguous strips into buffer");
6039 if (!(readSeparateStripsIntoBuffer(in
, read_buff
, length
, width
, spp
, dump
)))
6041 TIFFError("loadImage", "Unable to read separate strips into buffer");
6048 if (planar
== PLANARCONFIG_CONTIG
)
6050 if (!(readContigTilesIntoBuffer(in
, read_buff
, length
, width
, tw
, tl
, spp
, bps
)))
6052 TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
6058 if (!(readSeparateTilesIntoBuffer(in
, read_buff
, length
, width
, tw
, tl
, spp
, bps
)))
6060 TIFFError("loadImage", "Unable to read separate tiles into buffer");
6065 default: TIFFError("loadImage", "Unsupported image file format");
6069 if ((dump
->infile
!= NULL
) && (dump
->level
== 2))
6071 dump_info (dump
->infile
, dump
->format
, "loadImage",
6072 "Image width %d, length %d, Raw image data, %4d bytes",
6073 width
, length
, buffsize
);
6074 dump_info (dump
->infile
, dump
->format
, "",
6075 "Bits per sample %d, Samples per pixel %d", bps
, spp
);
6077 for (i
= 0; i
< length
; i
++)
6078 dump_buffer(dump
->infile
, dump
->format
, 1, scanlinesize
,
6079 i
, read_buff
+ (i
* scanlinesize
));
6082 } /* end loadImage */
6084 static int correct_orientation(struct image_data
*image
, unsigned char **work_buff_ptr
)
6086 uint16 mirror
, rotation
;
6087 unsigned char *work_buff
;
6089 work_buff
= *work_buff_ptr
;
6090 if ((image
== NULL
) || (work_buff
== NULL
))
6092 TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
6096 if ((image
->adjustments
& MIRROR_HORIZ
) || (image
->adjustments
& MIRROR_VERT
))
6098 mirror
= (uint16
)(image
->adjustments
& MIRROR_BOTH
);
6099 if (mirrorImage(image
->spp
, image
->bps
, mirror
,
6100 image
->width
, image
->length
, work_buff
))
6102 TIFFError ("correct_orientation", "Unable to mirror image");
6107 if (image
->adjustments
& ROTATE_ANY
)
6109 if (image
->adjustments
& ROTATECW_90
)
6110 rotation
= (uint16
) 90;
6112 if (image
->adjustments
& ROTATECW_180
)
6113 rotation
= (uint16
) 180;
6115 if (image
->adjustments
& ROTATECW_270
)
6116 rotation
= (uint16
) 270;
6119 TIFFError ("correct_orientation", "Invalid rotation value: %d",
6120 image
->adjustments
& ROTATE_ANY
);
6124 if (rotateImage(rotation
, image
, &image
->width
, &image
->length
, work_buff_ptr
))
6126 TIFFError ("correct_orientation", "Unable to rotate image");
6129 image
->orientation
= ORIENTATION_TOPLEFT
;
6133 } /* end correct_orientation */
6136 /* Extract multiple zones from an image and combine into a single composite image */
6138 extractCompositeRegions(struct image_data
*image
, struct crop_mask
*crop
,
6139 unsigned char *read_buff
, unsigned char *crop_buff
)
6141 int shift_width
, bytes_per_sample
, bytes_per_pixel
;
6142 uint32 i
, trailing_bits
, prev_trailing_bits
;
6143 uint32 row
, first_row
, last_row
, first_col
, last_col
;
6144 uint32 src_rowsize
, dst_rowsize
, src_offset
, dst_offset
;
6145 uint32 crop_width
, crop_length
, img_width
, img_length
;
6146 uint32 prev_length
, prev_width
, composite_width
;
6149 tsample_t count
, sample
= 0; /* Update to extract one or more samples */
6151 img_width
= image
->width
;
6152 img_length
= image
->length
;
6157 bytes_per_sample
= (bps
+ 7) / 8;
6158 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
6163 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
6164 shift_width
= bytes_per_pixel
;
6166 shift_width
= bytes_per_sample
+ 1;
6171 /* These are setup for adding additional sections */
6172 prev_width
= prev_length
= 0;
6173 prev_trailing_bits
= trailing_bits
= 0;
6174 composite_width
= crop
->combined_width
;
6175 crop
->combined_width
= 0;
6176 crop
->combined_length
= 0;
6178 for (i
= 0; i
< crop
->selections
; i
++)
6180 /* rows, columns, width, length are expressed in pixels */
6181 first_row
= crop
->regionlist
[i
].y1
;
6182 last_row
= crop
->regionlist
[i
].y2
;
6183 first_col
= crop
->regionlist
[i
].x1
;
6184 last_col
= crop
->regionlist
[i
].x2
;
6186 crop_width
= last_col
- first_col
+ 1;
6187 crop_length
= last_row
- first_row
+ 1;
6189 /* These should not be needed for composite images */
6190 crop
->regionlist
[i
].width
= crop_width
;
6191 crop
->regionlist
[i
].length
= crop_length
;
6192 crop
->regionlist
[i
].buffptr
= crop_buff
;
6194 src_rowsize
= ((img_width
* bps
* spp
) + 7) / 8;
6195 dst_rowsize
= (((crop_width
* bps
* count
) + 7) / 8);
6197 switch (crop
->edge_ref
)
6202 if ((i
> 0) && (crop_width
!= crop
->regionlist
[i
- 1].width
))
6204 TIFFError ("extractCompositeRegions",
6205 "Only equal width regions can be combined for -E top or bottom");
6209 crop
->combined_width
= crop_width
;
6210 crop
->combined_length
+= crop_length
;
6212 for (row
= first_row
; row
<= last_row
; row
++)
6214 src_offset
= row
* src_rowsize
;
6215 dst_offset
= (row
- first_row
) * dst_rowsize
;
6216 src
= read_buff
+ src_offset
;
6217 dst
= crop_buff
+ dst_offset
+ (prev_length
* dst_rowsize
);
6218 switch (shift_width
)
6220 case 0: if (extractContigSamplesBytes (src
, dst
, img_width
, sample
,
6221 spp
, bps
, count
, first_col
,
6224 TIFFError("extractCompositeRegions",
6225 "Unable to extract row %d", row
);
6229 case 1: if (bps
== 1)
6231 if (extractContigSamplesShifted8bits (src
, dst
, img_width
,
6232 sample
, spp
, bps
, count
,
6233 first_col
, last_col
+ 1,
6234 prev_trailing_bits
))
6236 TIFFError("extractCompositeRegions",
6237 "Unable to extract row %d", row
);
6243 if (extractContigSamplesShifted16bits (src
, dst
, img_width
,
6244 sample
, spp
, bps
, count
,
6245 first_col
, last_col
+ 1,
6246 prev_trailing_bits
))
6248 TIFFError("extractCompositeRegions",
6249 "Unable to extract row %d", row
);
6253 case 2: if (extractContigSamplesShifted24bits (src
, dst
, img_width
,
6254 sample
, spp
, bps
, count
,
6255 first_col
, last_col
+ 1,
6256 prev_trailing_bits
))
6258 TIFFError("extractCompositeRegions",
6259 "Unable to extract row %d", row
);
6265 case 5: if (extractContigSamplesShifted32bits (src
, dst
, img_width
,
6266 sample
, spp
, bps
, count
,
6267 first_col
, last_col
+ 1,
6268 prev_trailing_bits
))
6270 TIFFError("extractCompositeRegions",
6271 "Unable to extract row %d", row
);
6275 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps
);
6279 prev_length
+= crop_length
;
6281 case EDGE_LEFT
: /* splice the pieces of each row together, side by side */
6283 if ((i
> 0) && (crop_length
!= crop
->regionlist
[i
- 1].length
))
6285 TIFFError ("extractCompositeRegions",
6286 "Only equal length regions can be combined for -E left or right");
6289 crop
->combined_width
+= crop_width
;
6290 crop
->combined_length
= crop_length
;
6291 dst_rowsize
= (((composite_width
* bps
* count
) + 7) / 8);
6292 trailing_bits
= (crop_width
* bps
* count
) % 8;
6293 for (row
= first_row
; row
<= last_row
; row
++)
6295 src_offset
= row
* src_rowsize
;
6296 dst_offset
= (row
- first_row
) * dst_rowsize
;
6297 src
= read_buff
+ src_offset
;
6298 dst
= crop_buff
+ dst_offset
+ prev_width
;
6300 switch (shift_width
)
6302 case 0: if (extractContigSamplesBytes (src
, dst
, img_width
,
6303 sample
, spp
, bps
, count
,
6304 first_col
, last_col
+ 1))
6306 TIFFError("extractCompositeRegions",
6307 "Unable to extract row %d", row
);
6311 case 1: if (bps
== 1)
6313 if (extractContigSamplesShifted8bits (src
, dst
, img_width
,
6314 sample
, spp
, bps
, count
,
6315 first_col
, last_col
+ 1,
6316 prev_trailing_bits
))
6318 TIFFError("extractCompositeRegions",
6319 "Unable to extract row %d", row
);
6325 if (extractContigSamplesShifted16bits (src
, dst
, img_width
,
6326 sample
, spp
, bps
, count
,
6327 first_col
, last_col
+ 1,
6328 prev_trailing_bits
))
6330 TIFFError("extractCompositeRegions",
6331 "Unable to extract row %d", row
);
6335 case 2: if (extractContigSamplesShifted24bits (src
, dst
, img_width
,
6336 sample
, spp
, bps
, count
,
6337 first_col
, last_col
+ 1,
6338 prev_trailing_bits
))
6340 TIFFError("extractCompositeRegions",
6341 "Unable to extract row %d", row
);
6347 case 5: if (extractContigSamplesShifted32bits (src
, dst
, img_width
,
6348 sample
, spp
, bps
, count
,
6349 first_col
, last_col
+ 1,
6350 prev_trailing_bits
))
6352 TIFFError("extractCompositeRegions",
6353 "Unable to extract row %d", row
);
6357 default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps
);
6361 prev_width
+= (crop_width
* bps
* count
) / 8;
6362 prev_trailing_bits
+= trailing_bits
;
6363 if (prev_trailing_bits
> 7)
6364 prev_trailing_bits
-= 8;
6368 if (crop
->combined_width
!= composite_width
)
6369 TIFFError("combineSeparateRegions","Combined width does not match composite width");
6372 } /* end extractCompositeRegions */
6374 /* Copy a single region of input buffer to an output buffer.
6375 * The read functions used copy separate plane data into a buffer
6376 * as interleaved samples rather than separate planes so the same
6377 * logic works to extract regions regardless of the way the data
6378 * are organized in the input file. This function can be used to
6379 * extract one or more samples from the input image by updating the
6380 * parameters for starting sample and number of samples to copy in the
6381 * fifth and eighth arguments of the call to extractContigSamples.
6382 * They would be passed as new elements of the crop_mask struct.
6386 extractSeparateRegion(struct image_data
*image
, struct crop_mask
*crop
,
6387 unsigned char *read_buff
, unsigned char *crop_buff
,
6390 int shift_width
, prev_trailing_bits
= 0;
6391 uint32 bytes_per_sample
, bytes_per_pixel
;
6392 uint32 src_rowsize
, dst_rowsize
;
6393 uint32 row
, first_row
, last_row
, first_col
, last_col
;
6394 uint32 src_offset
, dst_offset
;
6395 uint32 crop_width
, crop_length
, img_width
, img_length
;
6398 tsample_t count
, sample
= 0; /* Update to extract more or more samples */
6400 img_width
= image
->width
;
6401 img_length
= image
->length
;
6406 bytes_per_sample
= (bps
+ 7) / 8;
6407 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
6409 shift_width
= 0; /* Byte aligned data only */
6412 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
6413 shift_width
= bytes_per_pixel
;
6415 shift_width
= bytes_per_sample
+ 1;
6418 /* rows, columns, width, length are expressed in pixels */
6419 first_row
= crop
->regionlist
[region
].y1
;
6420 last_row
= crop
->regionlist
[region
].y2
;
6421 first_col
= crop
->regionlist
[region
].x1
;
6422 last_col
= crop
->regionlist
[region
].x2
;
6424 crop_width
= last_col
- first_col
+ 1;
6425 crop_length
= last_row
- first_row
+ 1;
6427 crop
->regionlist
[region
].width
= crop_width
;
6428 crop
->regionlist
[region
].length
= crop_length
;
6429 crop
->regionlist
[region
].buffptr
= crop_buff
;
6433 src_rowsize
= ((img_width
* bps
* spp
) + 7) / 8;
6434 dst_rowsize
= (((crop_width
* bps
* spp
) + 7) / 8);
6436 for (row
= first_row
; row
<= last_row
; row
++)
6438 src_offset
= row
* src_rowsize
;
6439 dst_offset
= (row
- first_row
) * dst_rowsize
;
6440 src
= read_buff
+ src_offset
;
6441 dst
= crop_buff
+ dst_offset
;
6443 switch (shift_width
)
6445 case 0: if (extractContigSamplesBytes (src
, dst
, img_width
, sample
,
6446 spp
, bps
, count
, first_col
,
6449 TIFFError("extractSeparateRegion",
6450 "Unable to extract row %d", row
);
6454 case 1: if (bps
== 1)
6456 if (extractContigSamplesShifted8bits (src
, dst
, img_width
,
6457 sample
, spp
, bps
, count
,
6458 first_col
, last_col
+ 1,
6459 prev_trailing_bits
))
6461 TIFFError("extractSeparateRegion",
6462 "Unable to extract row %d", row
);
6468 if (extractContigSamplesShifted16bits (src
, dst
, img_width
,
6469 sample
, spp
, bps
, count
,
6470 first_col
, last_col
+ 1,
6471 prev_trailing_bits
))
6473 TIFFError("extractSeparateRegion",
6474 "Unable to extract row %d", row
);
6478 case 2: if (extractContigSamplesShifted24bits (src
, dst
, img_width
,
6479 sample
, spp
, bps
, count
,
6480 first_col
, last_col
+ 1,
6481 prev_trailing_bits
))
6483 TIFFError("extractSeparateRegion",
6484 "Unable to extract row %d", row
);
6490 case 5: if (extractContigSamplesShifted32bits (src
, dst
, img_width
,
6491 sample
, spp
, bps
, count
,
6492 first_col
, last_col
+ 1,
6493 prev_trailing_bits
))
6495 TIFFError("extractSeparateRegion",
6496 "Unable to extract row %d", row
);
6500 default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps
);
6506 } /* end extractSeparateRegion */
6509 extractImageSection(struct image_data
*image
, struct pageseg
*section
,
6510 unsigned char *src_buff
, unsigned char *sect_buff
)
6512 unsigned char bytebuff1
, bytebuff2
;
6513 unsigned char *src
, *dst
;
6515 uint32 img_width
, img_length
, img_rowsize
;
6516 uint32 j
, shift1
, shift2
, trailing_bits
;
6517 uint32 row
, first_row
, last_row
, first_col
, last_col
;
6518 uint32 src_offset
, dst_offset
, row_offset
, col_offset
;
6519 uint32 offset1
, offset2
, full_bytes
;
6520 uint32 sect_width
, sect_length
;
6525 unsigned char bitset
;
6526 static char *bitarray
= NULL
;
6529 img_width
= image
->width
;
6530 img_length
= image
->length
;
6540 if (bitarray
== NULL
)
6542 if ((bitarray
= (char *)malloc(img_width
)) == NULL
)
6544 TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
6550 /* rows, columns, width, length are expressed in pixels */
6551 first_row
= section
->y1
;
6552 last_row
= section
->y2
;
6553 first_col
= section
->x1
;
6554 last_col
= section
->x2
;
6556 sect_width
= last_col
- first_col
+ 1;
6557 sect_length
= last_row
- first_row
+ 1;
6558 img_rowsize
= ((img_width
* bps
+ 7) / 8) * spp
;
6559 full_bytes
= (sect_width
* spp
* bps
) / 8; /* number of COMPLETE bytes per row in section */
6560 trailing_bits
= (sect_width
* bps
) % 8;
6563 TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
6564 first_row
, last_row
, first_col
, last_col
);
6565 TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
6566 img_width
, img_length
, bps
, spp
);
6567 TIFFError ("", "Sect width: %d, Sect length: %d, full bytes: %d trailing bits %d\n",
6568 sect_width
, sect_length
, full_bytes
, trailing_bits
);
6573 col_offset
= first_col
* spp
* bps
/ 8;
6574 for (row
= first_row
; row
<= last_row
; row
++)
6576 /* row_offset = row * img_width * spp * bps / 8; */
6577 row_offset
= row
* img_rowsize
;
6578 src_offset
= row_offset
+ col_offset
;
6581 TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset
, dst_offset
);
6583 _TIFFmemcpy (sect_buff
+ dst_offset
, src_buff
+ src_offset
, full_bytes
);
6584 dst_offset
+= full_bytes
;
6589 shift1
= spp
* ((first_col
* bps
) % 8);
6590 shift2
= spp
* ((last_col
* bps
) % 8);
6591 for (row
= first_row
; row
<= last_row
; row
++)
6593 /* pull out the first byte */
6594 row_offset
= row
* img_rowsize
;
6595 offset1
= row_offset
+ (first_col
* bps
/ 8);
6596 offset2
= row_offset
+ (last_col
* bps
/ 8);
6599 for (j
= 0, k
= 7; j
< 8; j
++, k
--)
6601 bitset
= *(src_buff
+ offset1
) & (((unsigned char)1 << k
)) ? 1 : 0;
6602 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6604 sprintf(&bitarray
[8], " ");
6605 sprintf(&bitarray
[9], " ");
6606 for (j
= 10, k
= 7; j
< 18; j
++, k
--)
6608 bitset
= *(src_buff
+ offset2
) & (((unsigned char)1 << k
)) ? 1 : 0;
6609 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6611 bitarray
[18] = '\0';
6612 TIFFError ("", "Row: %3d Offset1: %d, Shift1: %d, Offset2: %d, Shift2: %d\n",
6613 row
, offset1
, shift1
, offset2
, shift2
);
6616 bytebuff1
= bytebuff2
= 0;
6617 if (shift1
== 0) /* the region is byte and sample alligned */
6619 _TIFFmemcpy (sect_buff
+ dst_offset
, src_buff
+ offset1
, full_bytes
);
6622 TIFFError ("", " Alligned data src offset1: %8d, Dst offset: %8d\n", offset1
, dst_offset
);
6623 sprintf(&bitarray
[18], "\n");
6624 sprintf(&bitarray
[19], "\t");
6625 for (j
= 20, k
= 7; j
< 28; j
++, k
--)
6627 bitset
= *(sect_buff
+ dst_offset
) & (((unsigned char)1 << k
)) ? 1 : 0;
6628 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6633 dst_offset
+= full_bytes
;
6635 if (trailing_bits
!= 0)
6637 bytebuff2
= src_buff
[offset2
] & ((unsigned char)255 << (7 - shift2
));
6638 sect_buff
[dst_offset
] = bytebuff2
;
6640 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n",
6641 offset2
, dst_offset
);
6642 for (j
= 30, k
= 7; j
< 38; j
++, k
--)
6644 bitset
= *(sect_buff
+ dst_offset
) & (((unsigned char)1 << k
)) ? 1 : 0;
6645 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6647 bitarray
[38] = '\0';
6648 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray
);
6653 else /* each destination byte will have to be built from two source bytes*/
6656 TIFFError ("", " Unalligned data src offset: %8d, Dst offset: %8d\n", offset1
, dst_offset
);
6658 for (j
= 0; j
<= full_bytes
; j
++)
6660 bytebuff1
= src_buff
[offset1
+ j
] & ((unsigned char)255 >> shift1
);
6661 bytebuff2
= src_buff
[offset1
+ j
+ 1] & ((unsigned char)255 << (7 - shift1
));
6662 sect_buff
[dst_offset
+ j
] = (bytebuff1
<< shift1
) | (bytebuff2
>> (8 - shift1
));
6665 sprintf(&bitarray
[18], "\n");
6666 sprintf(&bitarray
[19], "\t");
6667 for (j
= 20, k
= 7; j
< 28; j
++, k
--)
6669 bitset
= *(sect_buff
+ dst_offset
) & (((unsigned char)1 << k
)) ? 1 : 0;
6670 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6675 dst_offset
+= full_bytes
;
6677 if (trailing_bits
!= 0)
6680 TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n", offset1
+ full_bytes
, dst_offset
);
6682 if (shift2
> shift1
)
6684 bytebuff1
= src_buff
[offset1
+ full_bytes
] & ((unsigned char)255 << (7 - shift2
));
6685 bytebuff2
= bytebuff1
& ((unsigned char)255 << shift1
);
6686 sect_buff
[dst_offset
] = bytebuff2
;
6688 TIFFError ("", " Shift2 > Shift1\n");
6693 if (shift2
< shift1
)
6695 bytebuff2
= ((unsigned char)255 << (shift1
- shift2
- 1));
6696 sect_buff
[dst_offset
] &= bytebuff2
;
6698 TIFFError ("", " Shift2 < Shift1\n");
6703 TIFFError ("", " Shift2 == Shift1\n");
6708 sprintf(&bitarray
[28], " ");
6709 sprintf(&bitarray
[29], " ");
6710 for (j
= 30, k
= 7; j
< 38; j
++, k
--)
6712 bitset
= *(sect_buff
+ dst_offset
) & (((unsigned char)1 << k
)) ? 1 : 0;
6713 sprintf(&bitarray
[j
], (bitset
) ? "1" : "0");
6715 bitarray
[38] = '\0';
6716 TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray
);
6724 } /* end extractImageSection */
6727 writeSelections(TIFF
*in
, TIFF
**out
, struct crop_mask
*crop
,
6728 struct image_data
*image
, struct dump_opts
*dump
,
6729 struct buffinfo seg_buffs
[], char *mp
, char *filename
,
6730 unsigned int *page
, unsigned int total_pages
)
6734 unsigned char *crop_buff
= NULL
;
6736 /* Where we open a new file depends on the export mode */
6737 switch (crop
->exp_mode
)
6739 case ONE_FILE_COMPOSITE
: /* Regions combined into single image */
6741 crop_buff
= seg_buffs
[0].buffer
;
6742 if (update_output_file (out
, mp
, autoindex
, filename
, page
))
6744 page_count
= total_pages
;
6745 if (writeCroppedImage(in
, *out
, image
, dump
,
6746 crop
->combined_width
,
6747 crop
->combined_length
,
6748 crop_buff
, *page
, total_pages
))
6750 TIFFError("writeRegions", "Unable to write new image");
6754 case ONE_FILE_SEPARATED
: /* Regions as separated images */
6756 if (update_output_file (out
, mp
, autoindex
, filename
, page
))
6758 page_count
= crop
->selections
* total_pages
;
6759 for (i
= 0; i
< crop
->selections
; i
++)
6761 crop_buff
= seg_buffs
[i
].buffer
;
6762 if (writeCroppedImage(in
, *out
, image
, dump
,
6763 crop
->regionlist
[i
].width
,
6764 crop
->regionlist
[i
].length
,
6765 crop_buff
, *page
, page_count
))
6767 TIFFError("writeRegions", "Unable to write new image");
6772 case FILE_PER_IMAGE_COMPOSITE
: /* Regions as composite image */
6774 if (update_output_file (out
, mp
, autoindex
, filename
, page
))
6777 crop_buff
= seg_buffs
[0].buffer
;
6778 if (writeCroppedImage(in
, *out
, image
, dump
,
6779 crop
->combined_width
,
6780 crop
->combined_length
,
6781 crop_buff
, *page
, total_pages
))
6783 TIFFError("writeRegions", "Unable to write new image");
6787 case FILE_PER_IMAGE_SEPARATED
: /* Regions as separated images */
6789 page_count
= crop
->selections
;
6790 if (update_output_file (out
, mp
, autoindex
, filename
, page
))
6793 for (i
= 0; i
< crop
->selections
; i
++)
6795 crop_buff
= seg_buffs
[i
].buffer
;
6796 /* Write the current region to the current file */
6797 if (writeCroppedImage(in
, *out
, image
, dump
,
6798 crop
->regionlist
[i
].width
,
6799 crop
->regionlist
[i
].length
,
6800 crop_buff
, *page
, page_count
))
6802 TIFFError("writeRegions", "Unable to write new image");
6807 case FILE_PER_SELECTION
:
6810 for (i
= 0; i
< crop
->selections
; i
++)
6812 if (update_output_file (out
, mp
, autoindex
, filename
, page
))
6815 crop_buff
= seg_buffs
[i
].buffer
;
6816 /* Write the current region to the current file */
6817 if (writeCroppedImage(in
, *out
, image
, dump
,
6818 crop
->regionlist
[i
].width
,
6819 crop
->regionlist
[i
].length
,
6820 crop_buff
, *page
, page_count
))
6822 TIFFError("writeRegions", "Unable to write new image");
6827 default: return (1);
6831 } /* end writeRegions */
6834 writeImageSections(TIFF
*in
, TIFF
*out
, struct image_data
*image
,
6835 struct pagedef
*page
, struct pageseg
*sections
,
6836 struct dump_opts
* dump
, unsigned char *src_buff
,
6837 unsigned char **sect_buff_ptr
)
6840 uint32 i
, k
, width
, length
, sectsize
;
6841 unsigned char *sect_buff
= *sect_buff_ptr
;
6846 k
= page
->cols
* page
->rows
;
6847 if ((k
< 1) || (k
> MAX_SECTIONS
))
6849 TIFFError("writeImageSections",
6850 "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k
);
6854 for (i
= 0; i
< k
; i
++)
6856 width
= sections
[i
].x2
- sections
[i
].x1
+ 1;
6857 length
= sections
[i
].y2
- sections
[i
].y1
+ 1;
6859 ceil((width
* image
->bps
+ 7) / (double)8) * image
->spp
* length
;
6860 /* allocate a buffer if we don't have one already */
6861 if (createImageSection(sectsize
, sect_buff_ptr
))
6863 TIFFError("writeImageSections", "Unable to allocate section buffer");
6866 sect_buff
= *sect_buff_ptr
;
6868 if (extractImageSection (image
, §ions
[i
], src_buff
, sect_buff
))
6870 TIFFError("writeImageSections", "Unable to extract image sections");
6874 /* call the write routine here instead of outside the loop */
6875 if (writeSingleSection(in
, out
, image
, dump
, width
, length
, hres
, vres
, sect_buff
))
6877 TIFFError("writeImageSections", "Unable to write image section");
6883 } /* end writeImageSections */
6885 /* Code in this function is heavily indebted to code in tiffcp
6886 * with modifications by Richard Nolde to handle orientation correctly.
6887 * It will have to be updated significantly if support is added to
6888 * extract one or more samples from original image since the
6889 * original code assumes we are always copying all samples.
6892 writeSingleSection(TIFF
*in
, TIFF
*out
, struct image_data
*image
,
6893 struct dump_opts
*dump
, uint32 width
, uint32 length
,
6894 double hres
, double vres
,
6895 unsigned char *sect_buff
)
6898 uint16 input_compression
, input_photometric
;
6899 uint16 input_planar
;
6902 /* Calling this seems to reset the compression mode on the TIFF *in file.
6903 TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
6905 input_compression
= image
->compression
;
6906 input_photometric
= image
->photometric
;
6910 TIFFSetField(out
, TIFFTAG_IMAGEWIDTH
, width
);
6911 TIFFSetField(out
, TIFFTAG_IMAGELENGTH
, length
);
6912 TIFFSetField(out
, TIFFTAG_BITSPERSAMPLE
, bps
);
6913 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, spp
);
6916 TIFFError("writeSingleSection", "Input compression: %s",
6917 (input_compression
== COMPRESSION_OJPEG
) ? "Old Jpeg" :
6918 ((input_compression
== COMPRESSION_JPEG
) ? "New Jpeg" : "Non Jpeg"));
6920 /* This is the global variable compression which is set
6921 * if the user has specified a command line option for
6922 * a compression option. Should be passed around in one
6923 * of the parameters instead of as a global. If no user
6924 * option specified it will still be (uint16) -1. */
6925 if (compression
!= (uint16
)-1)
6926 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
6928 { /* OJPEG is no longer supported for writing so upgrade to JPEG */
6929 if (input_compression
== COMPRESSION_OJPEG
)
6931 compression
= COMPRESSION_JPEG
;
6932 jpegcolormode
= JPEGCOLORMODE_RAW
;
6933 TIFFSetField(out
, TIFFTAG_COMPRESSION
, COMPRESSION_JPEG
);
6935 else /* Use the compression from the input file */
6936 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
6939 if (compression
== COMPRESSION_JPEG
)
6941 if ((input_photometric
== PHOTOMETRIC_PALETTE
) || /* color map indexed */
6942 (input_photometric
== PHOTOMETRIC_MASK
)) /* holdout mask */
6944 TIFFError ("writeSingleSection",
6945 "JPEG compression cannot be used with %s image data",
6946 (input_photometric
== PHOTOMETRIC_PALETTE
) ?
6947 "palette" : "mask");
6950 if ((input_photometric
== PHOTOMETRIC_RGB
) &&
6951 (jpegcolormode
== JPEGCOLORMODE_RGB
))
6952 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_YCBCR
);
6954 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, input_photometric
);
6958 if (compression
== COMPRESSION_SGILOG
|| compression
== COMPRESSION_SGILOG24
)
6959 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, spp
== 1 ?
6960 PHOTOMETRIC_LOGL
: PHOTOMETRIC_LOGLUV
);
6962 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, image
->photometric
);
6966 TIFFError("writeSingleSection", "Input photometric: %s",
6967 (input_photometric
== PHOTOMETRIC_RGB
) ? "RGB" :
6968 ((input_photometric
== PHOTOMETRIC_YCBCR
) ? "YCbCr" : "Not RGB or YCbCr"));
6971 if (((input_photometric
== PHOTOMETRIC_LOGL
) ||
6972 (input_photometric
== PHOTOMETRIC_LOGLUV
)) &&
6973 ((compression
!= COMPRESSION_SGILOG
) &&
6974 (compression
!= COMPRESSION_SGILOG24
)))
6976 TIFFError("writeSingleSection",
6977 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
6982 TIFFSetField(out
, TIFFTAG_FILLORDER
, fillorder
);
6984 CopyTag(TIFFTAG_FILLORDER
, 1, TIFF_SHORT
);
6986 /* The loadimage function reads input orientation and sets
6987 * image->orientation. The correct_image_orientation function
6988 * applies the required rotation and mirror operations to
6989 * present the data in TOPLEFT orientation and updates
6990 * image->orientation if any transforms are performed,
6991 * as per EXIF standard.
6993 TIFFSetField(out
, TIFFTAG_ORIENTATION
, image
->orientation
);
6996 * Choose tiles/strip for the output image according to
6997 * the command line arguments (-tiles, -strips) and the
6998 * structure of the input image.
7001 outtiled
= TIFFIsTiled(in
);
7004 * Setup output file's tile width&height. If either
7005 * is not specified, use either the value from the
7006 * input image or, if nothing is defined, use the
7009 if (tilewidth
== (uint32
) 0)
7010 TIFFGetField(in
, TIFFTAG_TILEWIDTH
, &tilewidth
);
7011 if (tilelength
== (uint32
) 0)
7012 TIFFGetField(in
, TIFFTAG_TILELENGTH
, &tilelength
);
7014 if (tilewidth
== 0 || tilelength
== 0)
7015 TIFFDefaultTileSize(out
, &tilewidth
, &tilelength
);
7016 TIFFDefaultTileSize(out
, &tilewidth
, &tilelength
);
7017 TIFFSetField(out
, TIFFTAG_TILEWIDTH
, tilewidth
);
7018 TIFFSetField(out
, TIFFTAG_TILELENGTH
, tilelength
);
7021 * RowsPerStrip is left unspecified: use either the
7022 * value from the input image or, if nothing is defined,
7023 * use the library default.
7025 if (rowsperstrip
== (uint32
) 0)
7027 if (!TIFFGetField(in
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
))
7028 rowsperstrip
= TIFFDefaultStripSize(out
, rowsperstrip
);
7029 if (compression
!= COMPRESSION_JPEG
)
7031 if (rowsperstrip
> length
)
7032 rowsperstrip
= length
;
7036 if (rowsperstrip
== (uint32
) -1)
7037 rowsperstrip
= length
;
7038 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
, rowsperstrip
);
7041 TIFFGetFieldDefaulted(in
, TIFFTAG_PLANARCONFIG
, &input_planar
);
7042 if (config
!= (uint16
) -1)
7043 TIFFSetField(out
, TIFFTAG_PLANARCONFIG
, config
);
7045 CopyField(TIFFTAG_PLANARCONFIG
, config
);
7047 CopyTag(TIFFTAG_TRANSFERFUNCTION
, 4, TIFF_SHORT
);
7048 CopyTag(TIFFTAG_COLORMAP
, 4, TIFF_SHORT
);
7050 /* SMinSampleValue & SMaxSampleValue */
7051 switch (compression
) {
7052 /* These are references to GLOBAL variables set by defaults
7053 * and /or the compression flag
7055 case COMPRESSION_JPEG
:
7056 if (((bps
% 8) == 0) || ((bps
% 12) == 0))
7058 TIFFSetField(out
, TIFFTAG_JPEGQUALITY
, quality
);
7059 TIFFSetField(out
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
7063 TIFFError("writeSingleSection",
7064 "JPEG compression requires 8 or 12 bits per sample");
7068 case COMPRESSION_LZW
:
7069 case COMPRESSION_ADOBE_DEFLATE
:
7070 case COMPRESSION_DEFLATE
:
7071 if (predictor
!= (uint16
)-1)
7072 TIFFSetField(out
, TIFFTAG_PREDICTOR
, predictor
);
7074 CopyField(TIFFTAG_PREDICTOR
, predictor
);
7076 case COMPRESSION_CCITTFAX3
:
7077 case COMPRESSION_CCITTFAX4
:
7078 if (compression
== COMPRESSION_CCITTFAX3
) {
7079 if (g3opts
!= (uint32
) -1)
7080 TIFFSetField(out
, TIFFTAG_GROUP3OPTIONS
, g3opts
);
7082 CopyField(TIFFTAG_GROUP3OPTIONS
, g3opts
);
7084 CopyTag(TIFFTAG_GROUP4OPTIONS
, 1, TIFF_LONG
);
7085 CopyTag(TIFFTAG_BADFAXLINES
, 1, TIFF_LONG
);
7086 CopyTag(TIFFTAG_CLEANFAXDATA
, 1, TIFF_LONG
);
7087 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES
, 1, TIFF_LONG
);
7088 CopyTag(TIFFTAG_FAXRECVPARAMS
, 1, TIFF_LONG
);
7089 CopyTag(TIFFTAG_FAXRECVTIME
, 1, TIFF_LONG
);
7090 CopyTag(TIFFTAG_FAXSUBADDRESS
, 1, TIFF_ASCII
);
7095 if (TIFFGetField(in
, TIFFTAG_ICCPROFILE
, &len32
, &data
))
7096 TIFFSetField(out
, TIFFTAG_ICCPROFILE
, len32
, data
);
7099 const char* inknames
;
7100 if (TIFFGetField(in
, TIFFTAG_NUMBEROFINKS
, &ninks
)) {
7101 TIFFSetField(out
, TIFFTAG_NUMBEROFINKS
, ninks
);
7102 if (TIFFGetField(in
, TIFFTAG_INKNAMES
, &inknames
)) {
7103 int inknameslen
= strlen(inknames
) + 1;
7104 const char* cp
= inknames
;
7106 cp
= strchr(cp
, '\0');
7109 inknameslen
+= (strlen(cp
) + 1);
7113 TIFFSetField(out
, TIFFTAG_INKNAMES
, inknameslen
, inknames
);
7118 unsigned short pg0
, pg1
;
7119 if (TIFFGetField(in
, TIFFTAG_PAGENUMBER
, &pg0
, &pg1
)) {
7120 if (pageNum
< 0) /* only one input file */
7121 TIFFSetField(out
, TIFFTAG_PAGENUMBER
, pg0
, pg1
);
7123 TIFFSetField(out
, TIFFTAG_PAGENUMBER
, pageNum
++, 0);
7127 for (p
= tags
; p
< &tags
[NTAGS
]; p
++)
7128 CopyTag(p
->tag
, p
->count
, p
->type
);
7130 /* Update these since they are overwritten from input res by loop above */
7131 TIFFSetField(out
, TIFFTAG_XRESOLUTION
, (float)hres
);
7132 TIFFSetField(out
, TIFFTAG_YRESOLUTION
, (float)vres
);
7134 /* Compute the tile or strip dimensions and write to disk */
7137 if (config
== PLANARCONFIG_CONTIG
)
7138 writeBufferToContigTiles (out
, sect_buff
, length
, width
, spp
, dump
);
7140 writeBufferToSeparateTiles (out
, sect_buff
, length
, width
, spp
, dump
);
7144 if (config
== PLANARCONFIG_CONTIG
)
7145 writeBufferToContigStrips (out
, sect_buff
, length
);
7147 writeBufferToSeparateStrips(out
, sect_buff
, length
, width
, spp
, dump
);
7150 if (!TIFFWriteDirectory(out
))
7157 } /* end writeSingleSection */
7160 /* Create a buffer to write one section at a time */
7162 createImageSection(uint32 sectsize
, unsigned char **sect_buff_ptr
)
7164 unsigned char *sect_buff
= NULL
;
7165 unsigned char *new_buff
= NULL
;
7166 static uint32 prev_sectsize
= 0;
7168 sect_buff
= *sect_buff_ptr
;
7172 sect_buff
= (unsigned char *)_TIFFmalloc(sectsize
);
7173 *sect_buff_ptr
= sect_buff
;
7174 _TIFFmemset(sect_buff
, 0, sectsize
);
7178 if (prev_sectsize
< sectsize
)
7180 new_buff
= _TIFFrealloc(sect_buff
, sectsize
);
7184 sect_buff
= (unsigned char *)_TIFFmalloc(sectsize
);
7187 sect_buff
= new_buff
;
7189 _TIFFmemset(sect_buff
, 0, sectsize
);
7195 TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
7198 prev_sectsize
= sectsize
;
7199 *sect_buff_ptr
= sect_buff
;
7202 } /* end createImageSection */
7205 /* Process selections defined by regions, zones, margins, or fixed sized areas */
7207 processCropSelections(struct image_data
*image
, struct crop_mask
*crop
,
7208 unsigned char **read_buff_ptr
, struct buffinfo seg_buffs
[])
7211 uint32 width
, length
, total_width
, total_length
;
7213 unsigned char *crop_buff
= NULL
;
7214 unsigned char *read_buff
= NULL
;
7215 unsigned char *next_buff
= NULL
;
7216 tsize_t prev_cropsize
= 0;
7218 read_buff
= *read_buff_ptr
;
7220 if (crop
->img_mode
== COMPOSITE_IMAGES
)
7222 cropsize
= crop
->bufftotal
;
7223 crop_buff
= seg_buffs
[0].buffer
;
7225 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7228 prev_cropsize
= seg_buffs
[0].size
;
7229 if (prev_cropsize
< cropsize
)
7231 next_buff
= _TIFFrealloc(crop_buff
, cropsize
);
7234 _TIFFfree (crop_buff
);
7235 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7238 crop_buff
= next_buff
;
7244 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7248 _TIFFmemset(crop_buff
, 0, cropsize
);
7249 seg_buffs
[0].buffer
= crop_buff
;
7250 seg_buffs
[0].size
= cropsize
;
7252 /* Checks for matching width or length as required */
7253 if (extractCompositeRegions(image
, crop
, read_buff
, crop_buff
) != 0)
7256 if (crop
->crop_mode
& CROP_INVERT
)
7258 switch (crop
->photometric
)
7260 /* Just change the interpretation */
7261 case PHOTOMETRIC_MINISWHITE
:
7262 case PHOTOMETRIC_MINISBLACK
:
7263 image
->photometric
= crop
->photometric
;
7265 case INVERT_DATA_ONLY
:
7266 case INVERT_DATA_AND_TAG
:
7267 if (invertImage(image
->photometric
, image
->spp
, image
->bps
,
7268 crop
->combined_width
, crop
->combined_length
, crop_buff
))
7270 TIFFError("processCropSelections",
7271 "Failed to invert colorspace for composite regions");
7274 if (crop
->photometric
== INVERT_DATA_AND_TAG
)
7276 switch (image
->photometric
)
7278 case PHOTOMETRIC_MINISWHITE
:
7279 image
->photometric
= PHOTOMETRIC_MINISBLACK
;
7281 case PHOTOMETRIC_MINISBLACK
:
7282 image
->photometric
= PHOTOMETRIC_MINISWHITE
;
7293 /* Mirror and Rotate will not work with multiple regions unless they are the same width */
7294 if (crop
->crop_mode
& CROP_MIRROR
)
7296 if (mirrorImage(image
->spp
, image
->bps
, crop
->mirror
,
7297 crop
->combined_width
, crop
->combined_length
, crop_buff
))
7299 TIFFError("processCropSelections", "Failed to mirror composite regions %s",
7300 (crop
->rotation
== MIRROR_HORIZ
) ? "horizontally" : "vertically");
7305 if (crop
->crop_mode
& CROP_ROTATE
) /* rotate should be last as it can reallocate the buffer */
7307 if (rotateImage(crop
->rotation
, image
, &crop
->combined_width
,
7308 &crop
->combined_length
, &crop_buff
))
7310 TIFFError("processCropSelections",
7311 "Failed to rotate composite regions by %d degrees", crop
->rotation
);
7314 seg_buffs
[0].buffer
= crop_buff
;
7315 seg_buffs
[0].size
= (((crop
->combined_width
* image
->bps
+ 7 ) / 8)
7316 * image
->spp
) * crop
->combined_length
;
7319 else /* Separated Images */
7321 total_width
= total_length
= 0;
7322 for (i
= 0; i
< crop
->selections
; i
++)
7324 cropsize
= crop
->bufftotal
;
7325 crop_buff
= seg_buffs
[i
].buffer
;
7327 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7330 prev_cropsize
= seg_buffs
[0].size
;
7331 if (prev_cropsize
< cropsize
)
7333 next_buff
= _TIFFrealloc(crop_buff
, cropsize
);
7336 _TIFFfree (crop_buff
);
7337 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7340 crop_buff
= next_buff
;
7346 TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
7350 _TIFFmemset(crop_buff
, 0, cropsize
);
7351 seg_buffs
[i
].buffer
= crop_buff
;
7352 seg_buffs
[i
].size
= cropsize
;
7354 if (extractSeparateRegion(image
, crop
, read_buff
, crop_buff
, i
))
7356 TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i
);
7360 width
= crop
->regionlist
[i
].width
;
7361 length
= crop
->regionlist
[i
].length
;
7363 if (crop
->crop_mode
& CROP_INVERT
)
7365 switch (crop
->photometric
)
7367 /* Just change the interpretation */
7368 case PHOTOMETRIC_MINISWHITE
:
7369 case PHOTOMETRIC_MINISBLACK
:
7370 image
->photometric
= crop
->photometric
;
7372 case INVERT_DATA_ONLY
:
7373 case INVERT_DATA_AND_TAG
:
7374 if (invertImage(image
->photometric
, image
->spp
, image
->bps
,
7375 width
, length
, crop_buff
))
7377 TIFFError("processCropSelections",
7378 "Failed to invert colorspace for region");
7381 if (crop
->photometric
== INVERT_DATA_AND_TAG
)
7383 switch (image
->photometric
)
7385 case PHOTOMETRIC_MINISWHITE
:
7386 image
->photometric
= PHOTOMETRIC_MINISBLACK
;
7388 case PHOTOMETRIC_MINISBLACK
:
7389 image
->photometric
= PHOTOMETRIC_MINISWHITE
;
7400 if (crop
->crop_mode
& CROP_MIRROR
)
7402 if (mirrorImage(image
->spp
, image
->bps
, crop
->mirror
,
7403 width
, length
, crop_buff
))
7405 TIFFError("processCropSelections", "Failed to mirror crop region %s",
7406 (crop
->rotation
== MIRROR_HORIZ
) ? "horizontally" : "vertically");
7411 if (crop
->crop_mode
& CROP_ROTATE
) /* rotate should be last as it can reallocate the buffer */
7413 if (rotateImage(crop
->rotation
, image
, &crop
->regionlist
[i
].width
,
7414 &crop
->regionlist
[i
].length
, &crop_buff
))
7416 TIFFError("processCropSelections",
7417 "Failed to rotate crop region by %d degrees", crop
->rotation
);
7420 total_width
+= crop
->regionlist
[i
].width
;
7421 total_length
+= crop
->regionlist
[i
].length
;
7422 crop
->combined_width
= total_width
;
7423 crop
->combined_length
= total_length
;
7424 seg_buffs
[i
].buffer
= crop_buff
;
7425 seg_buffs
[i
].size
= (((crop
->regionlist
[i
].width
* image
->bps
+ 7 ) / 8)
7426 * image
->spp
) * crop
->regionlist
[i
].length
;
7431 } /* end processCropSelections */
7433 /* Copy the crop section of the data from the current image into a buffer
7434 * and adjust the IFD values to reflect the new size. If no cropping is
7435 * required, use the origial read buffer as the crop buffer.
7437 * There is quite a bit of redundancy between this routine and the more
7438 * specialized processCropSelections, but this provides
7439 * the most optimized path when no Zones or Regions are required.
7442 createCroppedImage(struct image_data
*image
, struct crop_mask
*crop
,
7443 unsigned char **read_buff_ptr
, unsigned char **crop_buff_ptr
)
7446 unsigned char *read_buff
= NULL
;
7447 unsigned char *crop_buff
= NULL
;
7448 unsigned char *new_buff
= NULL
;
7449 static tsize_t prev_cropsize
= 0;
7451 read_buff
= *read_buff_ptr
;
7453 /* process full image, no crop buffer needed */
7454 crop_buff
= read_buff
;
7455 *crop_buff_ptr
= read_buff
;
7456 crop
->combined_width
= image
->width
;
7457 crop
->combined_length
= image
->length
;
7459 cropsize
= crop
->bufftotal
;
7460 crop_buff
= *crop_buff_ptr
;
7463 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7464 *crop_buff_ptr
= crop_buff
;
7465 _TIFFmemset(crop_buff
, 0, cropsize
);
7466 prev_cropsize
= cropsize
;
7470 if (prev_cropsize
< cropsize
)
7472 new_buff
= _TIFFrealloc(crop_buff
, cropsize
);
7476 crop_buff
= (unsigned char *)_TIFFmalloc(cropsize
);
7479 crop_buff
= new_buff
;
7480 _TIFFmemset(crop_buff
, 0, cropsize
);
7486 TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
7489 *crop_buff_ptr
= crop_buff
;
7491 if (crop
->crop_mode
& CROP_INVERT
)
7493 switch (crop
->photometric
)
7495 /* Just change the interpretation */
7496 case PHOTOMETRIC_MINISWHITE
:
7497 case PHOTOMETRIC_MINISBLACK
:
7498 image
->photometric
= crop
->photometric
;
7500 case INVERT_DATA_ONLY
:
7501 case INVERT_DATA_AND_TAG
:
7502 if (invertImage(image
->photometric
, image
->spp
, image
->bps
,
7503 crop
->combined_width
, crop
->combined_length
, crop_buff
))
7505 TIFFError("createCroppedImage",
7506 "Failed to invert colorspace for image or cropped selection");
7509 if (crop
->photometric
== INVERT_DATA_AND_TAG
)
7511 switch (image
->photometric
)
7513 case PHOTOMETRIC_MINISWHITE
:
7514 image
->photometric
= PHOTOMETRIC_MINISBLACK
;
7516 case PHOTOMETRIC_MINISBLACK
:
7517 image
->photometric
= PHOTOMETRIC_MINISWHITE
;
7528 if (crop
->crop_mode
& CROP_MIRROR
)
7530 if (mirrorImage(image
->spp
, image
->bps
, crop
->mirror
,
7531 crop
->combined_width
, crop
->combined_length
, crop_buff
))
7533 TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s",
7534 (crop
->rotation
== MIRROR_HORIZ
) ? "horizontally" : "vertically");
7539 if (crop
->crop_mode
& CROP_ROTATE
) /* rotate should be last as it can reallocate the buffer */
7541 if (rotateImage(crop
->rotation
, image
, &crop
->combined_width
,
7542 &crop
->combined_length
, crop_buff_ptr
))
7544 TIFFError("createCroppedImage",
7545 "Failed to rotate image or cropped selection by %d degrees", crop
->rotation
);
7550 if (crop_buff
== read_buff
) /* we used the read buffer for the crop buffer */
7551 *read_buff_ptr
= NULL
; /* so we don't try to free it later */
7554 } /* end createCroppedImage */
7557 /* Code in this function is heavily indebted to code in tiffcp
7558 * with modifications by Richard Nolde to handle orientation correctly.
7559 * It will have to be updated significantly if support is added to
7560 * extract one or more samples from original image since the
7561 * original code assumes we are always copying all samples.
7562 * Use of global variables for config, compression and others
7563 * should be replaced by addition to the crop_mask struct (which
7564 * will be renamed to proc_opts indicating that is controlls
7565 * user supplied processing options, not just cropping) and
7566 * then passed in as an argument.
7569 writeCroppedImage(TIFF
*in
, TIFF
*out
, struct image_data
*image
,
7570 struct dump_opts
*dump
, uint32 width
, uint32 length
,
7571 unsigned char *crop_buff
, int pagenum
, int total_pages
)
7574 uint16 input_compression
, input_photometric
;
7575 uint16 input_planar
;
7578 input_compression
= image
->compression
;
7579 input_photometric
= image
->photometric
;
7583 TIFFSetField(out
, TIFFTAG_IMAGEWIDTH
, width
);
7584 TIFFSetField(out
, TIFFTAG_IMAGELENGTH
, length
);
7585 TIFFSetField(out
, TIFFTAG_BITSPERSAMPLE
, bps
);
7586 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, spp
);
7589 TIFFError("writeCroppedImage", "Input compression: %s",
7590 (input_compression
== COMPRESSION_OJPEG
) ? "Old Jpeg" :
7591 ((input_compression
== COMPRESSION_JPEG
) ? "New Jpeg" : "Non Jpeg"));
7594 if (compression
!= (uint16
)-1)
7595 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
7598 if (input_compression
== COMPRESSION_OJPEG
)
7600 compression
= COMPRESSION_JPEG
;
7601 jpegcolormode
= JPEGCOLORMODE_RAW
;
7602 TIFFSetField(out
, TIFFTAG_COMPRESSION
, COMPRESSION_JPEG
);
7605 CopyField(TIFFTAG_COMPRESSION
, compression
);
7608 if (compression
== COMPRESSION_JPEG
)
7610 if ((input_photometric
== PHOTOMETRIC_PALETTE
) || /* color map indexed */
7611 (input_photometric
== PHOTOMETRIC_MASK
)) /* $holdout mask */
7613 TIFFError ("writeCroppedImage",
7614 "JPEG compression cannot be used with %s image data",
7615 (input_photometric
== PHOTOMETRIC_PALETTE
) ?
7616 "palette" : "mask");
7619 if ((input_photometric
== PHOTOMETRIC_RGB
) &&
7620 (jpegcolormode
== JPEGCOLORMODE_RGB
))
7621 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_YCBCR
);
7623 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, input_photometric
);
7627 if (compression
== COMPRESSION_SGILOG
|| compression
== COMPRESSION_SGILOG24
)
7629 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, spp
== 1 ?
7630 PHOTOMETRIC_LOGL
: PHOTOMETRIC_LOGLUV
);
7634 if (input_compression
== COMPRESSION_SGILOG
||
7635 input_compression
== COMPRESSION_SGILOG24
)
7637 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, spp
== 1 ?
7638 PHOTOMETRIC_LOGL
: PHOTOMETRIC_LOGLUV
);
7641 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, image
->photometric
);
7645 if (((input_photometric
== PHOTOMETRIC_LOGL
) ||
7646 (input_photometric
== PHOTOMETRIC_LOGLUV
)) &&
7647 ((compression
!= COMPRESSION_SGILOG
) &&
7648 (compression
!= COMPRESSION_SGILOG24
)))
7650 TIFFError("writeCroppedImage",
7651 "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
7656 TIFFSetField(out
, TIFFTAG_FILLORDER
, fillorder
);
7658 CopyTag(TIFFTAG_FILLORDER
, 1, TIFF_SHORT
);
7660 /* The loadimage function reads input orientation and sets
7661 * image->orientation. The correct_image_orientation function
7662 * applies the required rotation and mirror operations to
7663 * present the data in TOPLEFT orientation and updates
7664 * image->orientation if any transforms are performed,
7665 * as per EXIF standard.
7667 TIFFSetField(out
, TIFFTAG_ORIENTATION
, image
->orientation
);
7670 * Choose tiles/strip for the output image according to
7671 * the command line arguments (-tiles, -strips) and the
7672 * structure of the input image.
7675 outtiled
= TIFFIsTiled(in
);
7678 * Setup output file's tile width&height. If either
7679 * is not specified, use either the value from the
7680 * input image or, if nothing is defined, use the
7683 if (tilewidth
== (uint32
) 0)
7684 TIFFGetField(in
, TIFFTAG_TILEWIDTH
, &tilewidth
);
7685 if (tilelength
== (uint32
) 0)
7686 TIFFGetField(in
, TIFFTAG_TILELENGTH
, &tilelength
);
7688 if (tilewidth
== 0 || tilelength
== 0)
7689 TIFFDefaultTileSize(out
, &tilewidth
, &tilelength
);
7690 TIFFSetField(out
, TIFFTAG_TILEWIDTH
, tilewidth
);
7691 TIFFSetField(out
, TIFFTAG_TILELENGTH
, tilelength
);
7694 * RowsPerStrip is left unspecified: use either the
7695 * value from the input image or, if nothing is defined,
7696 * use the library default.
7698 if (rowsperstrip
== (uint32
) 0)
7700 if (!TIFFGetField(in
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
))
7701 rowsperstrip
= TIFFDefaultStripSize(out
, rowsperstrip
);
7702 if (compression
!= COMPRESSION_JPEG
)
7704 if (rowsperstrip
> length
)
7705 rowsperstrip
= length
;
7709 if (rowsperstrip
== (uint32
) -1)
7710 rowsperstrip
= length
;
7711 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
, rowsperstrip
);
7714 TIFFGetFieldDefaulted(in
, TIFFTAG_PLANARCONFIG
, &input_planar
);
7715 if (config
!= (uint16
) -1)
7716 TIFFSetField(out
, TIFFTAG_PLANARCONFIG
, config
);
7718 CopyField(TIFFTAG_PLANARCONFIG
, config
);
7720 CopyTag(TIFFTAG_TRANSFERFUNCTION
, 4, TIFF_SHORT
);
7721 CopyTag(TIFFTAG_COLORMAP
, 4, TIFF_SHORT
);
7723 /* SMinSampleValue & SMaxSampleValue */
7724 switch (compression
) {
7725 case COMPRESSION_JPEG
:
7726 if (((bps
% 8) == 0) || ((bps
% 12) == 0))
7728 TIFFSetField(out
, TIFFTAG_JPEGQUALITY
, quality
);
7729 TIFFSetField(out
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
7733 TIFFError("writeCroppedImage",
7734 "JPEG compression requires 8 or 12 bits per sample");
7738 case COMPRESSION_LZW
:
7739 case COMPRESSION_ADOBE_DEFLATE
:
7740 case COMPRESSION_DEFLATE
:
7741 if (predictor
!= (uint16
)-1)
7742 TIFFSetField(out
, TIFFTAG_PREDICTOR
, predictor
);
7744 CopyField(TIFFTAG_PREDICTOR
, predictor
);
7746 case COMPRESSION_CCITTFAX3
:
7747 case COMPRESSION_CCITTFAX4
:
7750 TIFFError("writeCroppedImage",
7751 "Group 3/4 compression is not usable with bps > 1");
7754 if (compression
== COMPRESSION_CCITTFAX3
) {
7755 if (g3opts
!= (uint32
) -1)
7756 TIFFSetField(out
, TIFFTAG_GROUP3OPTIONS
, g3opts
);
7758 CopyField(TIFFTAG_GROUP3OPTIONS
, g3opts
);
7760 CopyTag(TIFFTAG_GROUP4OPTIONS
, 1, TIFF_LONG
);
7761 CopyTag(TIFFTAG_BADFAXLINES
, 1, TIFF_LONG
);
7762 CopyTag(TIFFTAG_CLEANFAXDATA
, 1, TIFF_LONG
);
7763 CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES
, 1, TIFF_LONG
);
7764 CopyTag(TIFFTAG_FAXRECVPARAMS
, 1, TIFF_LONG
);
7765 CopyTag(TIFFTAG_FAXRECVTIME
, 1, TIFF_LONG
);
7766 CopyTag(TIFFTAG_FAXSUBADDRESS
, 1, TIFF_ASCII
);
7768 case COMPRESSION_NONE
:
7774 if (TIFFGetField(in
, TIFFTAG_ICCPROFILE
, &len32
, &data
))
7775 TIFFSetField(out
, TIFFTAG_ICCPROFILE
, len32
, data
);
7778 const char* inknames
;
7779 if (TIFFGetField(in
, TIFFTAG_NUMBEROFINKS
, &ninks
)) {
7780 TIFFSetField(out
, TIFFTAG_NUMBEROFINKS
, ninks
);
7781 if (TIFFGetField(in
, TIFFTAG_INKNAMES
, &inknames
)) {
7782 int inknameslen
= strlen(inknames
) + 1;
7783 const char* cp
= inknames
;
7785 cp
= strchr(cp
, '\0');
7788 inknameslen
+= (strlen(cp
) + 1);
7792 TIFFSetField(out
, TIFFTAG_INKNAMES
, inknameslen
, inknames
);
7797 unsigned short pg0
, pg1
;
7798 if (TIFFGetField(in
, TIFFTAG_PAGENUMBER
, &pg0
, &pg1
)) {
7799 TIFFSetField(out
, TIFFTAG_PAGENUMBER
, pagenum
, total_pages
);
7803 for (p
= tags
; p
< &tags
[NTAGS
]; p
++)
7804 CopyTag(p
->tag
, p
->count
, p
->type
);
7806 /* Compute the tile or strip dimensions and write to disk */
7809 if (config
== PLANARCONFIG_CONTIG
)
7811 if (writeBufferToContigTiles (out
, crop_buff
, length
, width
, spp
, dump
))
7812 TIFFError("","Unable to write contiguous tile data for page %d", pagenum
);
7816 if (writeBufferToSeparateTiles (out
, crop_buff
, length
, width
, spp
, dump
))
7817 TIFFError("","Unable to write separate tile data for page %d", pagenum
);
7822 if (config
== PLANARCONFIG_CONTIG
)
7824 if (writeBufferToContigStrips (out
, crop_buff
, length
))
7825 TIFFError("","Unable to write contiguous strip data for page %d", pagenum
);
7829 if (writeBufferToSeparateStrips(out
, crop_buff
, length
, width
, spp
, dump
))
7830 TIFFError("","Unable to write separate strip data for page %d", pagenum
);
7834 if (!TIFFWriteDirectory(out
))
7836 TIFFError("","Failed to write IFD for page number %d", pagenum
);
7842 } /* end writeCroppedImage */
7845 rotateContigSamples8bits(uint16 rotation
, uint16 spp
, uint16 bps
, uint32 width
,
7846 uint32 length
, uint32 col
, uint8
*src
, uint8
*dst
)
7849 uint32 src_byte
= 0, src_bit
= 0;
7850 uint32 row
, rowsize
= 0, bit_offset
= 0;
7851 uint8 matchbits
= 0, maskbits
= 0;
7852 uint8 buff1
= 0, buff2
= 0;
7856 if ((src
== NULL
) || (dst
== NULL
))
7858 TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
7862 rowsize
= ((bps
* spp
* width
) + 7) / 8;
7864 maskbits
= (uint8
)-1 >> ( 8 - bps
);
7867 for (row
= 0; row
< length
; row
++)
7869 bit_offset
= col
* bps
* spp
;
7870 for (sample
= 0; sample
< spp
; sample
++)
7874 src_byte
= bit_offset
/ 8;
7875 src_bit
= bit_offset
% 8;
7879 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
7880 src_bit
= (bit_offset
+ (sample
* bps
)) % 8;
7885 case 90: next
= src
+ src_byte
- (row
* rowsize
);
7887 case 270: next
= src
+ src_byte
+ (row
* rowsize
);
7889 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation
);
7892 matchbits
= maskbits
<< (8 - src_bit
- bps
);
7893 buff1
= ((*next
) & matchbits
) << (src_bit
);
7895 /* If we have a full buffer's worth, write it out */
7896 if (ready_bits
>= 8)
7904 buff2
= (buff2
| (buff1
>> ready_bits
));
7912 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
7917 } /* end rotateContigSamples8bits */
7921 rotateContigSamples16bits(uint16 rotation
, uint16 spp
, uint16 bps
, uint32 width
,
7922 uint32 length
, uint32 col
, uint8
*src
, uint8
*dst
)
7925 uint32 row
, rowsize
, bit_offset
;
7926 uint32 src_byte
= 0, src_bit
= 0;
7927 uint16 matchbits
= 0, maskbits
= 0;
7928 uint16 buff1
= 0, buff2
= 0;
7933 if ((src
== NULL
) || (dst
== NULL
))
7935 TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
7939 rowsize
= ((bps
* spp
* width
) + 7) / 8;
7941 maskbits
= (uint16
)-1 >> (16 - bps
);
7943 for (row
= 0; row
< length
; row
++)
7945 bit_offset
= col
* bps
* spp
;
7946 for (sample
= 0; sample
< spp
; sample
++)
7950 src_byte
= bit_offset
/ 8;
7951 src_bit
= bit_offset
% 8;
7955 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
7956 src_bit
= (bit_offset
+ (sample
* bps
)) % 8;
7961 case 90: next
= src
+ src_byte
- (row
* rowsize
);
7963 case 270: next
= src
+ src_byte
+ (row
* rowsize
);
7965 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation
);
7968 matchbits
= maskbits
<< (16 - src_bit
- bps
);
7970 buff1
= (next
[0] << 8) | next
[1];
7972 buff1
= (next
[1] << 8) | next
[0];
7974 buff1
= (buff1
& matchbits
) << (src_bit
);
7976 /* If we have a full buffer's worth, write it out */
7977 if (ready_bits
>= 8)
7979 bytebuff
= (buff2
>> 8);
7982 /* shift in new bits */
7983 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
7986 { /* add another bps bits to the buffer */
7988 buff2
= (buff2
| (buff1
>> ready_bits
));
7996 bytebuff
= (buff2
>> 8);
8001 } /* end rotateContigSamples16bits */
8004 rotateContigSamples24bits(uint16 rotation
, uint16 spp
, uint16 bps
, uint32 width
,
8005 uint32 length
, uint32 col
, uint8
*src
, uint8
*dst
)
8008 uint32 row
, rowsize
, bit_offset
;
8009 uint32 src_byte
= 0, src_bit
= 0;
8010 uint32 matchbits
= 0, maskbits
= 0;
8011 uint32 buff1
= 0, buff2
= 0;
8012 uint8 bytebuff1
= 0, bytebuff2
= 0;
8017 if ((src
== NULL
) || (dst
== NULL
))
8019 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8023 rowsize
= ((bps
* spp
* width
) + 7) / 8;
8025 maskbits
= (uint32
)-1 >> (32 - bps
);
8027 for (row
= 0; row
< length
; row
++)
8029 bit_offset
= col
* bps
* spp
;
8030 for (sample
= 0; sample
< spp
; sample
++)
8034 src_byte
= bit_offset
/ 8;
8035 src_bit
= bit_offset
% 8;
8039 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8040 src_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8045 case 90: next
= src
+ src_byte
- (row
* rowsize
);
8047 case 270: next
= src
+ src_byte
+ (row
* rowsize
);
8049 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation
);
8052 matchbits
= maskbits
<< (32 - src_bit
- bps
);
8054 buff1
= (next
[0] << 24) | (next
[1] << 16) | (next
[2] << 8) | next
[3];
8056 buff1
= (next
[3] << 24) | (next
[2] << 16) | (next
[1] << 8) | next
[0];
8057 buff1
= (buff1
& matchbits
) << (src_bit
);
8059 /* If we have a full buffer's worth, write it out */
8060 if (ready_bits
>= 16)
8062 bytebuff1
= (buff2
>> 24);
8064 bytebuff2
= (buff2
>> 16);
8068 /* shift in new bits */
8069 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
8072 { /* add another bps bits to the buffer */
8073 bytebuff1
= bytebuff2
= 0;
8074 buff2
= (buff2
| (buff1
>> ready_bits
));
8080 /* catch any trailing bits at the end of the line */
8081 while (ready_bits
> 0)
8083 bytebuff1
= (buff2
>> 24);
8086 buff2
= (buff2
<< 8);
8087 bytebuff2
= bytebuff1
;
8092 } /* end rotateContigSamples24bits */
8095 rotateContigSamples32bits(uint16 rotation
, uint16 spp
, uint16 bps
, uint32 width
,
8096 uint32 length
, uint32 col
, uint8
*src
, uint8
*dst
)
8098 int ready_bits
= 0, shift_width
= 0;
8099 int bytes_per_sample
, bytes_per_pixel
;
8100 uint32 row
, rowsize
, bit_offset
;
8101 uint32 src_byte
, src_bit
;
8102 uint32 longbuff1
= 0, longbuff2
= 0;
8103 uint64 maskbits
= 0, matchbits
= 0;
8104 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
8105 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
8110 if ((src
== NULL
) || (dst
== NULL
))
8112 TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
8116 bytes_per_sample
= (bps
+ 7) / 8;
8117 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
8118 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
8119 shift_width
= bytes_per_pixel
;
8121 shift_width
= bytes_per_sample
+ 1;
8123 rowsize
= ((bps
* spp
* width
) + 7) / 8;
8125 maskbits
= (uint64
)-1 >> (64 - bps
);
8127 for (row
= 0; row
< length
; row
++)
8129 bit_offset
= col
* bps
* spp
;
8130 for (sample
= 0; sample
< spp
; sample
++)
8134 src_byte
= bit_offset
/ 8;
8135 src_bit
= bit_offset
% 8;
8139 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8140 src_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8145 case 90: next
= src
+ src_byte
- (row
* rowsize
);
8147 case 270: next
= src
+ src_byte
+ (row
* rowsize
);
8149 default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation
);
8152 matchbits
= maskbits
<< (64 - src_bit
- bps
);
8155 longbuff1
= (next
[0] << 24) | (next
[1] << 16) | (next
[2] << 8) | next
[3];
8156 longbuff2
= longbuff1
;
8160 longbuff1
= (next
[3] << 24) | (next
[2] << 16) | (next
[1] << 8) | next
[0];
8161 longbuff2
= longbuff1
;
8164 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
8165 buff1
= (buff3
& matchbits
) << (src_bit
);
8167 if (ready_bits
< 32)
8168 { /* add another bps bits to the buffer */
8169 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
8170 buff2
= (buff2
| (buff1
>> ready_bits
));
8172 else /* If we have a full buffer's worth, write it out */
8174 bytebuff1
= (buff2
>> 56);
8176 bytebuff2
= (buff2
>> 48);
8178 bytebuff3
= (buff2
>> 40);
8180 bytebuff4
= (buff2
>> 32);
8184 /* shift in new bits */
8185 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
8190 while (ready_bits
> 0)
8192 bytebuff1
= (buff2
>> 56);
8194 buff2
= (buff2
<< 8);
8199 } /* end rotateContigSamples32bits */
8202 /* Rotate an image by a multiple of 90 degrees clockwise */
8204 rotateImage(uint16 rotation
, struct image_data
*image
, uint32
*img_width
,
8205 uint32
*img_length
, unsigned char **ibuff_ptr
)
8208 uint32 bytes_per_pixel
, bytes_per_sample
;
8209 uint32 row
, rowsize
, src_offset
, dst_offset
;
8210 uint32 i
, col
, width
, length
;
8211 uint32 colsize
, buffsize
, col_offset
, pix_offset
;
8212 unsigned char *ibuff
;
8217 unsigned char *rbuff
= NULL
;
8220 length
= *img_length
;
8224 rowsize
= ((bps
* spp
* width
) + 7) / 8;
8225 colsize
= ((bps
* spp
* length
) + 7) / 8;
8226 if ((colsize
* width
) > (rowsize
* length
))
8227 buffsize
= (colsize
+ 1) * width
;
8229 buffsize
= (rowsize
+ 1) * length
;
8231 bytes_per_sample
= (bps
+ 7) / 8;
8232 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
8233 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
8234 shift_width
= bytes_per_pixel
;
8236 shift_width
= bytes_per_sample
+ 1;
8241 case 360: return (0);
8245 default: TIFFError("rotateImage", "Invalid rotation angle %d", rotation
);
8249 if (!(rbuff
= (unsigned char *)_TIFFmalloc(buffsize
)))
8251 TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize
);
8254 _TIFFmemset(rbuff
, '\0', buffsize
);
8259 case 180: if ((bps
% 8) == 0) /* byte alligned data */
8262 pix_offset
= (spp
* bps
) / 8;
8263 for (row
= 0; row
< length
; row
++)
8265 dst_offset
= (length
- row
- 1) * rowsize
;
8266 for (col
= 0; col
< width
; col
++)
8268 col_offset
= (width
- col
- 1) * pix_offset
;
8269 dst
= rbuff
+ dst_offset
+ col_offset
;
8271 for (i
= 0; i
< bytes_per_pixel
; i
++)
8277 { /* non 8 bit per sample data */
8278 for (row
= 0; row
< length
; row
++)
8280 src_offset
= row
* rowsize
;
8281 dst_offset
= (length
- row
- 1) * rowsize
;
8282 src
= ibuff
+ src_offset
;
8283 dst
= rbuff
+ dst_offset
;
8284 switch (shift_width
)
8286 case 1: if (bps
== 1)
8288 if (reverseSamples8bits(spp
, bps
, width
, src
, dst
))
8295 if (reverseSamples16bits(spp
, bps
, width
, src
, dst
))
8301 case 2: if (reverseSamples24bits(spp
, bps
, width
, src
, dst
))
8309 case 5: if (reverseSamples32bits(spp
, bps
, width
, src
, dst
))
8315 default: TIFFError("rotateImage","Unsupported bit depth %d", bps
);
8322 *(ibuff_ptr
) = rbuff
;
8325 case 90: if ((bps
% 8) == 0) /* byte aligned data */
8327 for (col
= 0; col
< width
; col
++)
8329 src_offset
= ((length
- 1) * rowsize
) + (col
* bytes_per_pixel
);
8330 dst_offset
= col
* colsize
;
8331 src
= ibuff
+ src_offset
;
8332 dst
= rbuff
+ dst_offset
;
8333 for (row
= length
; row
> 0; row
--)
8335 for (i
= 0; i
< bytes_per_pixel
; i
++)
8336 *dst
++ = *(src
+ i
);
8342 { /* non 8 bit per sample data */
8343 for (col
= 0; col
< width
; col
++)
8345 src_offset
= (length
- 1) * rowsize
;
8346 dst_offset
= col
* colsize
;
8347 src
= ibuff
+ src_offset
;
8348 dst
= rbuff
+ dst_offset
;
8349 switch (shift_width
)
8351 case 1: if (bps
== 1)
8353 if (rotateContigSamples8bits(rotation
, spp
, bps
, width
,
8354 length
, col
, src
, dst
))
8361 if (rotateContigSamples16bits(rotation
, spp
, bps
, width
,
8362 length
, col
, src
, dst
))
8368 case 2: if (rotateContigSamples24bits(rotation
, spp
, bps
, width
,
8369 length
, col
, src
, dst
))
8377 case 5: if (rotateContigSamples32bits(rotation
, spp
, bps
, width
,
8378 length
, col
, src
, dst
))
8384 default: TIFFError("rotateImage","Unsupported bit depth %d", bps
);
8391 *(ibuff_ptr
) = rbuff
;
8393 *img_width
= length
;
8394 *img_length
= width
;
8395 image
->width
= length
;
8396 image
->length
= width
;
8397 res_temp
= image
->xres
;
8398 image
->xres
= image
->yres
;
8399 image
->yres
= res_temp
;
8402 case 270: if ((bps
% 8) == 0) /* byte aligned data */
8404 for (col
= 0; col
< width
; col
++)
8406 src_offset
= col
* bytes_per_pixel
;
8407 dst_offset
= (width
- col
- 1) * colsize
;
8408 src
= ibuff
+ src_offset
;
8409 dst
= rbuff
+ dst_offset
;
8410 for (row
= length
; row
> 0; row
--)
8412 for (i
= 0; i
< bytes_per_pixel
; i
++)
8413 *dst
++ = *(src
+ i
);
8419 { /* non 8 bit per sample data */
8420 for (col
= 0; col
< width
; col
++)
8423 dst_offset
= (width
- col
- 1) * colsize
;
8424 src
= ibuff
+ src_offset
;
8425 dst
= rbuff
+ dst_offset
;
8426 switch (shift_width
)
8428 case 1: if (bps
== 1)
8430 if (rotateContigSamples8bits(rotation
, spp
, bps
, width
,
8431 length
, col
, src
, dst
))
8438 if (rotateContigSamples16bits(rotation
, spp
, bps
, width
,
8439 length
, col
, src
, dst
))
8445 case 2: if (rotateContigSamples24bits(rotation
, spp
, bps
, width
,
8446 length
, col
, src
, dst
))
8454 case 5: if (rotateContigSamples32bits(rotation
, spp
, bps
, width
,
8455 length
, col
, src
, dst
))
8461 default: TIFFError("rotateImage","Unsupported bit depth %d", bps
);
8468 *(ibuff_ptr
) = rbuff
;
8470 *img_width
= length
;
8471 *img_length
= width
;
8472 image
->width
= length
;
8473 image
->length
= width
;
8474 res_temp
= image
->xres
;
8475 image
->xres
= image
->yres
;
8476 image
->yres
= res_temp
;
8483 } /* end rotateImage */
8486 reverseSamples8bits (uint16 spp
, uint16 bps
, uint32 width
,
8487 uint8
*ibuff
, uint8
*obuff
)
8491 uint32 src_byte
, src_bit
;
8492 uint32 bit_offset
= 0;
8493 uint8 match_bits
= 0, mask_bits
= 0;
8494 uint8 buff1
= 0, buff2
= 0;
8499 if ((ibuff
== NULL
) || (obuff
== NULL
))
8501 TIFFError("reverseSamples8bits","Invalid image or work buffer");
8506 mask_bits
= (uint8
)-1 >> ( 8 - bps
);
8508 for (col
= width
; col
> 0; col
--)
8510 /* Compute src byte(s) and bits within byte(s) */
8511 bit_offset
= (col
- 1) * bps
* spp
;
8512 for (sample
= 0; sample
< spp
; sample
++)
8516 src_byte
= bit_offset
/ 8;
8517 src_bit
= bit_offset
% 8;
8521 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8522 src_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8525 src
= ibuff
+ src_byte
;
8526 match_bits
= mask_bits
<< (8 - src_bit
- bps
);
8527 buff1
= ((*src
) & match_bits
) << (src_bit
);
8530 buff2
= (buff2
| (buff1
>> ready_bits
));
8531 else /* If we have a full buffer's worth, write it out */
8542 buff1
= (buff2
& ((unsigned int)255 << (8 - ready_bits
)));
8547 } /* end reverseSamples8bits */
8551 reverseSamples16bits (uint16 spp
, uint16 bps
, uint32 width
,
8552 uint8
*ibuff
, uint8
*obuff
)
8556 uint32 src_byte
= 0, high_bit
= 0;
8557 uint32 bit_offset
= 0;
8558 uint16 match_bits
= 0, mask_bits
= 0;
8559 uint16 buff1
= 0, buff2
= 0;
8565 if ((ibuff
== NULL
) || (obuff
== NULL
))
8567 TIFFError("reverseSample16bits","Invalid image or work buffer");
8572 mask_bits
= (uint16
)-1 >> (16 - bps
);
8574 for (col
= width
; col
> 0; col
--)
8576 /* Compute src byte(s) and bits within byte(s) */
8577 bit_offset
= (col
- 1) * bps
* spp
;
8578 for (sample
= 0; sample
< spp
; sample
++)
8582 src_byte
= bit_offset
/ 8;
8583 high_bit
= bit_offset
% 8;
8587 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8588 high_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8591 src
= ibuff
+ src_byte
;
8592 match_bits
= mask_bits
<< (16 - high_bit
- bps
);
8594 buff1
= (src
[0] << 8) | src
[1];
8596 buff1
= (src
[1] << 8) | src
[0];
8597 buff1
= (buff1
& match_bits
) << (high_bit
);
8600 { /* add another bps bits to the buffer */
8602 buff2
= (buff2
| (buff1
>> ready_bits
));
8604 else /* If we have a full buffer's worth, write it out */
8606 bytebuff
= (buff2
>> 8);
8609 /* shift in new bits */
8610 buff2
= ((buff2
<< 8) | (buff1
>> ready_bits
));
8618 bytebuff
= (buff2
>> 8);
8623 } /* end reverseSamples16bits */
8626 reverseSamples24bits (uint16 spp
, uint16 bps
, uint32 width
,
8627 uint8
*ibuff
, uint8
*obuff
)
8631 uint32 src_byte
= 0, high_bit
= 0;
8632 uint32 bit_offset
= 0;
8633 uint32 match_bits
= 0, mask_bits
= 0;
8634 uint32 buff1
= 0, buff2
= 0;
8635 uint8 bytebuff1
= 0, bytebuff2
= 0;
8640 if ((ibuff
== NULL
) || (obuff
== NULL
))
8642 TIFFError("reverseSamples24bits","Invalid image or work buffer");
8647 mask_bits
= (uint32
)-1 >> (32 - bps
);
8649 for (col
= width
; col
> 0; col
--)
8651 /* Compute src byte(s) and bits within byte(s) */
8652 bit_offset
= (col
- 1) * bps
* spp
;
8653 for (sample
= 0; sample
< spp
; sample
++)
8657 src_byte
= bit_offset
/ 8;
8658 high_bit
= bit_offset
% 8;
8662 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8663 high_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8666 src
= ibuff
+ src_byte
;
8667 match_bits
= mask_bits
<< (32 - high_bit
- bps
);
8669 buff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
8671 buff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
8672 buff1
= (buff1
& match_bits
) << (high_bit
);
8674 if (ready_bits
< 16)
8675 { /* add another bps bits to the buffer */
8676 bytebuff1
= bytebuff2
= 0;
8677 buff2
= (buff2
| (buff1
>> ready_bits
));
8679 else /* If we have a full buffer's worth, write it out */
8681 bytebuff1
= (buff2
>> 24);
8683 bytebuff2
= (buff2
>> 16);
8687 /* shift in new bits */
8688 buff2
= ((buff2
<< 16) | (buff1
>> ready_bits
));
8694 /* catch any trailing bits at the end of the line */
8695 while (ready_bits
> 0)
8697 bytebuff1
= (buff2
>> 24);
8700 buff2
= (buff2
<< 8);
8701 bytebuff2
= bytebuff1
;
8706 } /* end reverseSamples24bits */
8710 reverseSamples32bits (uint16 spp
, uint16 bps
, uint32 width
,
8711 uint8
*ibuff
, uint8
*obuff
)
8713 int ready_bits
= 0, shift_width
= 0;
8714 int bytes_per_sample
, bytes_per_pixel
;
8716 uint32 src_byte
= 0, high_bit
= 0;
8718 uint32 longbuff1
= 0, longbuff2
= 0;
8719 uint64 mask_bits
= 0, match_bits
= 0;
8720 uint64 buff1
= 0, buff2
= 0, buff3
= 0;
8721 uint8 bytebuff1
= 0, bytebuff2
= 0, bytebuff3
= 0, bytebuff4
= 0;
8726 if ((ibuff
== NULL
) || (obuff
== NULL
))
8728 TIFFError("reverseSamples32bits","Invalid image or work buffer");
8733 mask_bits
= (uint64
)-1 >> (64 - bps
);
8736 bytes_per_sample
= (bps
+ 7) / 8;
8737 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
8738 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
8739 shift_width
= bytes_per_pixel
;
8741 shift_width
= bytes_per_sample
+ 1;
8743 for (col
= width
; col
> 0; col
--)
8745 /* Compute src byte(s) and bits within byte(s) */
8746 bit_offset
= (col
- 1) * bps
* spp
;
8747 for (sample
= 0; sample
< spp
; sample
++)
8751 src_byte
= bit_offset
/ 8;
8752 high_bit
= bit_offset
% 8;
8756 src_byte
= (bit_offset
+ (sample
* bps
)) / 8;
8757 high_bit
= (bit_offset
+ (sample
* bps
)) % 8;
8760 src
= ibuff
+ src_byte
;
8761 match_bits
= mask_bits
<< (64 - high_bit
- bps
);
8764 longbuff1
= (src
[0] << 24) | (src
[1] << 16) | (src
[2] << 8) | src
[3];
8765 longbuff2
= longbuff1
;
8769 longbuff1
= (src
[3] << 24) | (src
[2] << 16) | (src
[1] << 8) | src
[0];
8770 longbuff2
= longbuff1
;
8772 buff3
= ((uint64
)longbuff1
<< 32) | longbuff2
;
8773 buff1
= (buff3
& match_bits
) << (high_bit
);
8775 if (ready_bits
< 32)
8776 { /* add another bps bits to the buffer */
8777 bytebuff1
= bytebuff2
= bytebuff3
= bytebuff4
= 0;
8778 buff2
= (buff2
| (buff1
>> ready_bits
));
8780 else /* If we have a full buffer's worth, write it out */
8782 bytebuff1
= (buff2
>> 56);
8784 bytebuff2
= (buff2
>> 48);
8786 bytebuff3
= (buff2
>> 40);
8788 bytebuff4
= (buff2
>> 32);
8792 /* shift in new bits */
8793 buff2
= ((buff2
<< 32) | (buff1
>> ready_bits
));
8798 while (ready_bits
> 0)
8800 bytebuff1
= (buff2
>> 56);
8802 buff2
= (buff2
<< 8);
8807 } /* end reverseSamples32bits */
8810 reverseSamplesBytes (uint16 spp
, uint16 bps
, uint32 width
,
8811 uint8
*src
, uint8
*dst
)
8814 uint32 col
, bytes_per_pixel
, col_offset
;
8816 unsigned char swapbuff
[32];
8818 if ((src
== NULL
) || (dst
== NULL
))
8820 TIFFError("reverseSamplesBytes","Invalid input or output buffer");
8824 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
8827 case 8: /* Use memcpy for multiple bytes per sample data */
8830 case 2: for (col
= 0; col
< (width
/ 2); col
++)
8832 col_offset
= col
* bytes_per_pixel
;
8833 _TIFFmemcpy (swapbuff
, src
+ col_offset
, bytes_per_pixel
);
8834 _TIFFmemcpy (src
+ col_offset
, dst
- col_offset
- bytes_per_pixel
, bytes_per_pixel
);
8835 _TIFFmemcpy (dst
- col_offset
- bytes_per_pixel
, swapbuff
, bytes_per_pixel
);
8838 case 1: /* Use byte copy only for single byte per sample data */
8839 for (col
= 0; col
< (width
/ 2); col
++)
8841 for (i
= 0; i
< spp
; i
++)
8844 *src
++ = *(dst
- spp
+ i
);
8845 *(dst
- spp
+ i
) = bytebuff1
;
8850 default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps
);
8854 } /* end reverseSamplesBytes */
8857 /* Mirror an image horizontally or vertically */
8859 mirrorImage(uint16 spp
, uint16 bps
, uint16 mirror
, uint32 width
, uint32 length
, unsigned char *ibuff
)
8862 uint32 bytes_per_pixel
, bytes_per_sample
;
8863 uint32 row
, rowsize
, row_offset
;
8864 unsigned char *line_buff
= NULL
;
8869 rowsize
= ((width
* bps
* spp
) + 7) / 8;
8874 line_buff
= (unsigned char *)_TIFFmalloc(rowsize
);
8875 if (line_buff
== NULL
)
8877 TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize
);
8881 dst
= ibuff
+ (rowsize
* (length
- 1));
8882 for (row
= 0; row
< length
/ 2; row
++)
8884 _TIFFmemcpy(line_buff
, src
, rowsize
);
8885 _TIFFmemcpy(src
, dst
, rowsize
);
8886 _TIFFmemcpy(dst
, line_buff
, rowsize
);
8891 _TIFFfree(line_buff
);
8892 if (mirror
== MIRROR_VERT
)
8895 if ((bps
% 8) == 0) /* byte alligned data */
8897 for (row
= 0; row
< length
; row
++)
8899 row_offset
= row
* rowsize
;
8900 src
= ibuff
+ row_offset
;
8901 dst
= ibuff
+ row_offset
+ rowsize
;
8902 if (reverseSamplesBytes(spp
, bps
, width
, src
, dst
))
8909 { /* non 8 bit per sample data */
8910 if (!(line_buff
= (unsigned char *)_TIFFmalloc(rowsize
+ 1)))
8912 TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
8915 bytes_per_sample
= (bps
+ 7) / 8;
8916 bytes_per_pixel
= ((bps
* spp
) + 7) / 8;
8917 if (bytes_per_pixel
< (bytes_per_sample
+ 1))
8918 shift_width
= bytes_per_pixel
;
8920 shift_width
= bytes_per_sample
+ 1;
8922 for (row
= 0; row
< length
; row
++)
8924 row_offset
= row
* rowsize
;
8925 src
= ibuff
+ row_offset
;
8926 _TIFFmemset (line_buff
, '\0', rowsize
);
8927 switch (shift_width
)
8929 case 1: if (reverseSamples16bits(spp
, bps
, width
, src
, line_buff
))
8931 _TIFFfree(line_buff
);
8934 _TIFFmemcpy (src
, line_buff
, rowsize
);
8936 case 2: if (reverseSamples24bits(spp
, bps
, width
, src
, line_buff
))
8938 _TIFFfree(line_buff
);
8941 _TIFFmemcpy (src
, line_buff
, rowsize
);
8945 case 5: if (reverseSamples32bits(spp
, bps
, width
, src
, line_buff
))
8947 _TIFFfree(line_buff
);
8950 _TIFFmemcpy (src
, line_buff
, rowsize
);
8952 default: TIFFError("mirrorImage","Unsupported bit depth %d", bps
);
8953 _TIFFfree(line_buff
);
8958 _TIFFfree(line_buff
);
8962 default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror
);
8970 /* Invert the light and dark values for a bilevel or grayscale image */
8972 invertImage(uint16 photometric
, uint16 spp
, uint16 bps
, uint32 width
, uint32 length
, unsigned char *work_buff
)
8975 unsigned char bytebuff1
, bytebuff2
, bytebuff3
, bytebuff4
;
8982 TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
8986 if (photometric
!= PHOTOMETRIC_MINISWHITE
&& photometric
!= PHOTOMETRIC_MINISBLACK
)
8988 TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
8995 TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
9001 case 32: src_uint32
= (uint32
*)src
;
9002 for (row
= 0; row
< length
; row
++)
9003 for (col
= 0; col
< width
; col
++)
9005 *src_uint32
= (uint32
)0xFFFFFFFF - *src_uint32
;
9009 case 16: src_uint16
= (uint16
*)src
;
9010 for (row
= 0; row
< length
; row
++)
9011 for (col
= 0; col
< width
; col
++)
9013 *src_uint16
= (uint16
)0xFFFF - *src_uint16
;
9017 case 8: for (row
= 0; row
< length
; row
++)
9018 for (col
= 0; col
< width
; col
++)
9020 *src
= (uint8
)255 - *src
;
9024 case 4: for (row
= 0; row
< length
; row
++)
9025 for (col
= 0; col
< width
; col
++)
9027 bytebuff1
= 16 - (uint8
)(*src
& 240 >> 4);
9028 bytebuff2
= 16 - (*src
& 15);
9029 *src
= bytebuff1
<< 4 & bytebuff2
;
9033 case 2: for (row
= 0; row
< length
; row
++)
9034 for (col
= 0; col
< width
; col
++)
9036 bytebuff1
= 4 - (uint8
)(*src
& 192 >> 6);
9037 bytebuff2
= 4 - (uint8
)(*src
& 48 >> 4);
9038 bytebuff3
= 4 - (uint8
)(*src
& 12 >> 2);
9039 bytebuff4
= 4 - (uint8
)(*src
& 3);
9040 *src
= (bytebuff1
<< 6) || (bytebuff2
<< 4) || (bytebuff3
<< 2) || bytebuff4
;
9044 case 1: for (row
= 0; row
< length
; row
++)
9045 for (col
= 0; col
< width
; col
+= 8 /(spp
* bps
))
9051 default: TIFFError("invertImage", "Unsupported bit depth %d", bps
);
9058 /* vim: set ts=8 sts=8 sw=8 noet: */