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