1
/* $Id: tiffcrop.c,v 1.3.2.6 2009-08-20 22:31:00 bfriesen 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.
10
* Permission to use, copy, modify, distribute, and sell this software and
11
* its documentation for any purpose is hereby granted without fee, provided
12
* that (i) the above copyright notices and this permission notice appear in
13
* all copies of the software and related documentation, and (ii) the names of
14
* Sam Leffler and Silicon Graphics may not be used in any advertising or
15
* publicity relating to the software without the specific, prior written
16
* permission of Sam Leffler and Silicon Graphics.
18
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
19
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
20
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
22
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
23
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
24
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
25
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
26
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29
* The portions of the current code that are derived from tiffcp are primarly
30
* in the areas of lowlevel reading and writing of scanlines and tiles though
31
* some of the original functions have been extended to support arbitrary bit
32
* depths. These functions are presented at the top of this file.
34
* Additions (c) Richard Nolde 2006-2009 Last Updated 1/6/2009
35
* IN NO EVENT SHALL RICHARD NOLDE BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
36
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
37
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
38
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
39
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41
* Add support for the options below to extract sections of image(s)
42
* and to modify the whole image or selected portions of each image by
43
* rotations, mirroring, and colorscale/colormap inversion of selected
44
* types of TIFF images when appropriate. Some color model dependent
45
* functions are restricted to bilevel or 8 bit per sample data.
46
* See the man page for the full explanations.
49
* -h Display the syntax guide.
50
* -v Report the version and last build date for tiffcrop
51
* -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1
52
* Specify a series of coordinates to define rectangular
53
* regions by the top left and lower right corners.
54
* -e c|d|i|m|s export mode for images and selections from input images
55
* combined All images and selections are written to a single file (default)
56
* with multiple selections from one image combined into a single image
57
* divided All images and selections are written to a single file
58
* with each selection from one image written to a new image
59
* image Each input image is written to a new file (numeric filename sequence)
60
* with multiple selections from the image combined into one image
61
* multiple Each input image is written to a new file (numeric filename sequence)
62
* with each selection from the image written to a new image
63
* separated Individual selections from each image are written to separate files
64
* -U units [in, cm, px ] inches, centimeters or pixels
65
* -H # Set horizontal resolution of output images to #
66
* -V # Set vertical resolution of output images to #
67
* -J # Horizontal margin of output page to # expressed in current
69
* -K # Vertical margin of output page to # expressed in current
71
* -X # Horizontal dimension of region to extract expressed in current
73
* -Y # Vertical dimension of region to extract expressed in current
75
* -O orient Orientation for output image, portrait, landscape, auto
76
* -P page Page size for output image segments, eg letter, legal, tabloid,
78
* -S cols:rows Divide the image into equal sized segments using cols across
80
* -E t|l|r|b Edge to use as origin
81
* -m #,#,#,# Margins from edges for selection: top, left, bottom, right
83
* -Z #:#,#:# Zones of the image designated as zone X of Y,
84
* eg 1:3 would be first of three equal portions measured
86
* -N odd|even|#,#-#,#|last
87
* Select sequences and/or ranges of images within file
88
* to process. The words odd or even may be used to specify
89
* all odd or even numbered images the word last may be used
90
* in place of a number in the sequence to indicate the final
91
* image in the file without knowing how many images there are.
92
* -R # Rotate image or crop selection by 90,180,or 270 degrees
94
* -F h|v Flip (mirror) image or crop selection horizontally
96
* -I [black|white|data|both]
97
* Invert color space, eg dark to light for bilevel and grayscale images
98
* If argument is white or black, set the PHOTOMETRIC_INTERPRETATION
99
* tag to MinIsBlack or MinIsWhite without altering the image data
100
* If the argument is data or both, the image data are modified:
101
* both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
102
* data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
103
* -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
104
* Dump raw data for input and/or output images to individual files
105
* in raw (binary) format or text (ASCII) representing binary data
106
* as strings of 1s and 0s. The filename arguments are used as stems
107
* from which individual files are created for each image. Text format
108
* includes annotations for image parameters and scanline info. Level
109
* selects which functions dump data, with higher numbers selecting
110
* lower level, scanline level routines. Debug reports a limited set
111
* of messages to monitor progess without enabling dump logs.
114
#include "tif_config.h"
123
#include <sys/stat.h>
131
extern int getopt(int, char**, char*);
137
# define unlink delete
141
#define PATH_MAX 1024
145
#define streq(a,b) (strcmp((a),(b)) == 0)
147
#define strneq(a,b,n) (strncmp((a),(b),(n)) == 0)
149
/* NB: the uint32 casts are to silence certain ANSI-C compilers */
150
#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
151
#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
157
* Definitions and data structures required to support cropping and image
163
#define EDGE_BOTTOM 3
165
#define EDGE_CENTER 5
167
#define MIRROR_HORIZ 1
168
#define MIRROR_VERT 2
169
#define MIRROR_BOTH 3
170
#define ROTATECW_90 8
171
#define ROTATECW_180 16
172
#define ROTATECW_270 32
173
#define ROTATE_ANY ROTATECW_90 || ROTATECW_180 || ROTATECW_270
176
#define CROP_MARGINS 1
178
#define CROP_LENGTH 4
180
#define CROP_REGIONS 16
181
#define CROP_ROTATE 32
182
#define CROP_MIRROR 64
183
#define CROP_INVERT 128
185
/* Modes for writing out images and selections */
186
#define ONE_FILE_COMPOSITE 0 /* One file, sections combined sections */
187
#define ONE_FILE_SEPARATED 1 /* One file, sections to new IFDs */
188
#define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
189
#define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
190
#define FILE_PER_SELECTION 4 /* One file per selection */
192
#define COMPOSITE_IMAGES 0 /* Selections combined into one image */
193
#define SEPARATED_IMAGES 1 /* Selections saved to separate images */
198
#define MAX_REGIONS 8 /* number of regions to extract from a single page */
199
#define MAX_OUTBUFFS 8 /* must match larger of zones or regions */
200
#define MAX_SECTIONS 32 /* number of sections per page to write to output */
201
#define MAX_IMAGES 1024 /* number of images in descrete list, not in the file */
202
#define MAX_SAMPLES 8 /* maximum number of samples per pixel supported */
203
#define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
209
/* Offsets into buffer for margins and fixed width and length segments */
223
/* Description of a zone within the image. Position 1 of 3 zones would be
224
* the first third of the image. These are computed after margins and
225
* width/length requests are applied so that you can extract multiple
226
* zones from within a larger region for OCR or barcode recognition.
230
uint32 size; /* size of this buffer */
231
unsigned char *buffer; /* address of the allocated buffer */
235
int position; /* ordinal of segment to be extracted */
236
int total; /* total equal sized divisions of crop area */
240
uint32 x1; /* index of left edge */
241
uint32 x2; /* index of right edge */
242
uint32 y1; /* index of top edge */
243
uint32 y2; /* index of bottom edge */
244
int position; /* ordinal of segment to be extracted */
245
int total; /* total equal sized divisions of crop area */
246
uint32 buffsize; /* size of buffer needed to hold the cropped zone */
250
double X1; /* index of left edge in current units */
251
double X2; /* index of right edge in current units */
252
double Y1; /* index of top edge in current units */
253
double Y2; /* index of bottom edge in current units */
257
uint32 x1; /* pixel offset of left edge */
258
uint32 x2; /* pixel offset of right edge */
259
uint32 y1; /* pixel offset of top edge */
260
uint32 y2; /* picel offset of bottom edge */
261
uint32 width; /* width in pixels */
262
uint32 length; /* length in pixels */
263
uint32 buffsize; /* size of buffer needed to hold the cropped region */
264
unsigned char *buffptr; /* address of start of the region */
267
/* Cropping parameters from command line and image data */
269
double width; /* Selection width for master crop region in requested units */
270
double length; /* Selection length for master crop region in requesed units */
271
double margins[4]; /* Top, left, bottom, right margins */
272
float xres; /* Horizontal resolution read from image*/
273
float yres; /* Vertical resolution read from image */
274
uint32 combined_width; /* Width of combined cropped zones */
275
uint32 combined_length; /* Length of combined cropped zones */
276
uint32 bufftotal; /* Size of buffer needed to hold all the cropped region */
277
uint16 img_mode; /* Composite or separate images created from zones or regions */
278
uint16 exp_mode; /* Export input images or selections to one or more files */
279
uint16 crop_mode; /* Crop options to be applied */
280
uint16 res_unit; /* Resolution unit for margins and selections */
281
uint16 edge_ref; /* Reference edge for sections extraction and combination */
282
uint16 rotation; /* Clockwise rotation of the extracted region or image */
283
uint16 mirror; /* Mirror extracted region or image horizontally or vertically */
284
uint16 invert; /* Invert the color map of image or region */
285
uint16 photometric; /* Status of photometric interpretation for inverted image */
286
uint16 selections; /* Number of regions or zones selected */
287
uint16 regions; /* Number of regions delimited by corner coordinates */
288
struct region regionlist[MAX_REGIONS]; /* Regions within page or master crop region */
289
uint16 zones; /* Number of zones delimited by Ordinal:Total requested */
290
struct zone zonelist[MAX_REGIONS]; /* Zones indices to define a region */
291
struct coordpairs corners[MAX_REGIONS]; /* Coordinates of upper left and lower right corner */
294
#define MAX_PAPERNAMES 49
295
#define MAX_PAPERNAME_LENGTH 15
296
#define DEFAULT_RESUNIT RESUNIT_INCH
297
#define DEFAULT_PAGE_HEIGHT 14.0
298
#define DEFAULT_PAGE_WIDTH 8.5
299
#define DEFAULT_RESOLUTION 300
300
#define DEFAULT_PAPER_SIZE "legal"
302
#define ORIENTATION_NONE 0
303
#define ORIENTATION_PORTRAIT 1
304
#define ORIENTATION_LANDSCAPE 2
305
#define ORIENTATION_SEASCAPE 4
306
#define ORIENTATION_AUTO 16
308
#define PAGE_MODE_NONE 0
309
#define PAGE_MODE_RESOLUTION 1
310
#define PAGE_MODE_PAPERSIZE 2
311
#define PAGE_MODE_MARGINS 4
312
#define PAGE_MODE_ROWSCOLS 8
314
#define INVERT_DATA_ONLY 10
315
#define INVERT_DATA_AND_TAG 11
318
char name[MAX_PAPERNAME_LENGTH];
324
/* Paper Size Width Length Aspect Ratio */
325
struct paperdef PaperTable[MAX_PAPERNAMES] = {
326
{"default", 8.500, 14.000, 0.607},
327
{"pa4", 8.264, 11.000, 0.751},
328
{"letter", 8.500, 11.000, 0.773},
329
{"legal", 8.500, 14.000, 0.607},
330
{"half-letter", 8.500, 5.514, 1.542},
331
{"executive", 7.264, 10.528, 0.690},
332
{"tabloid", 11.000, 17.000, 0.647},
333
{"11x17", 11.000, 17.000, 0.647},
334
{"ledger", 17.000, 11.000, 1.545},
335
{"archa", 9.000, 12.000, 0.750},
336
{"archb", 12.000, 18.000, 0.667},
337
{"archc", 18.000, 24.000, 0.750},
338
{"archd", 24.000, 36.000, 0.667},
339
{"arche", 36.000, 48.000, 0.750},
340
{"csheet", 17.000, 22.000, 0.773},
341
{"dsheet", 22.000, 34.000, 0.647},
342
{"esheet", 34.000, 44.000, 0.773},
343
{"superb", 11.708, 17.042, 0.687},
344
{"commercial", 4.139, 9.528, 0.434},
345
{"monarch", 3.889, 7.528, 0.517},
346
{"envelope-dl", 4.333, 8.681, 0.499},
347
{"envelope-c5", 6.389, 9.028, 0.708},
348
{"europostcard", 4.139, 5.833, 0.710},
349
{"a0", 33.111, 46.806, 0.707},
350
{"a1", 23.389, 33.111, 0.706},
351
{"a2", 16.542, 23.389, 0.707},
352
{"a3", 11.694, 16.542, 0.707},
353
{"a4", 8.264, 11.694, 0.707},
354
{"a5", 5.833, 8.264, 0.706},
355
{"a6", 4.125, 5.833, 0.707},
356
{"a7", 2.917, 4.125, 0.707},
357
{"a8", 2.056, 2.917, 0.705},
358
{"a9", 1.458, 2.056, 0.709},
359
{"a10", 1.014, 1.458, 0.695},
360
{"b0", 39.375, 55.667, 0.707},
361
{"b1", 27.833, 39.375, 0.707},
362
{"b2", 19.681, 27.833, 0.707},
363
{"b3", 13.903, 19.681, 0.706},
364
{"b4", 9.847, 13.903, 0.708},
365
{"b5", 6.931, 9.847, 0.704},
366
{"b6", 4.917, 6.931, 0.709},
367
{"c0", 36.097, 51.069, 0.707},
368
{"c1", 25.514, 36.097, 0.707},
369
{"c2", 18.028, 25.514, 0.707},
370
{"c3", 12.750, 18.028, 0.707},
371
{"c4", 9.014, 12.750, 0.707},
372
{"c5", 6.375, 9.014, 0.707},
373
{"c6", 4.486, 6.375, 0.704},
374
{"", 0.000, 0.000, 1.000},
377
/* Structure to define in input image parameters */
392
/* Structure to define the output image modifiers */
395
double width; /* width in pixels */
396
double length; /* length in pixels */
397
double hmargin; /* margins to subtract from width of sections */
398
double vmargin; /* margins to subtract from height of sections */
399
double hres; /* horizontal resolution for output */
400
double vres; /* vertical resolution for output */
401
uint32 mode; /* bitmask of modifiers to page format */
402
uint16 res_unit; /* resolution unit for output image */
403
unsigned int rows; /* number of section rows */
404
unsigned int cols; /* number of section cols */
405
unsigned int orient; /* portrait, landscape, seascape, auto */
413
char infilename[PATH_MAX + 1];
414
char outfilename[PATH_MAX + 1];
420
static int outtiled = -1;
421
static uint32 tilewidth;
422
static uint32 tilelength;
424
static uint16 config;
425
static uint16 compression;
426
static uint16 predictor;
427
static uint16 fillorder;
428
static uint32 rowsperstrip;
429
static uint32 g3opts;
430
static int ignore = FALSE; /* if true, ignore read errors */
431
static uint32 defg3opts = (uint32) -1;
432
static int quality = 75; /* JPEG quality */
433
static int jpegcolormode = JPEGCOLORMODE_RGB;
434
static uint16 defcompression = (uint16) -1;
435
static uint16 defpredictor = (uint16) -1;
436
static int pageNum = 0;
437
static int little_endian = 1;
439
/* Functions adapted from tiffcp with additions or modifications */
440
static int readContigStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t);
441
static int readSeparateStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
442
static int readContigTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t);
443
static int readSeparateTilesIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t);
444
static int writeBufferToContigStrips (TIFF*, uint8*, uint32, uint32, tsample_t);
445
static int writeBufferToContigTiles (TIFF*, uint8*, uint32, uint32, tsample_t);
446
static int writeBufferToSeparateStrips (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
447
static int writeBufferToSeparateTiles (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
448
static int extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, int, int,
449
tsample_t, uint16, uint16, struct dump_opts *);
450
static void cpStripToTile (uint8*, uint8*, uint32, uint32, int, int);
451
static void cpSeparateBufToContigBuf(uint8 *, uint8 *, uint32, uint32 ,
452
int, int, tsample_t, int);
454
static int processCompressOptions(char*);
455
static void usage(void);
457
/* New functions by Richard Nolde not found in tiffcp */
458
static void initImageData (struct image_data *);
459
static void initCropMasks (struct crop_mask *);
460
static void initPageSetup (struct pagedef *, struct pageseg *, struct buffinfo []);
461
static void initDumpOptions(struct dump_opts *);
463
/* Command line and file naming functions */
464
void process_command_opts (int, char *[], char *, char *, uint32 *,
465
uint16 *, uint16 *, uint32 *, uint32 *, uint32 *,
466
struct crop_mask *, struct pagedef *,
468
unsigned int *, unsigned int *);
469
static int update_output_file (TIFF **, char *, int, char *, unsigned int *);
472
/* * High level functions for whole image manipulation */
473
static int get_page_geometry (char *, struct pagedef*);
474
static int computeInputPixelOffsets(struct crop_mask *, struct image_data *,
476
static int computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
477
struct pagedef *, struct pageseg *,
479
static int loadImage(TIFF *, struct image_data *, struct dump_opts *, unsigned char **);
480
static int correct_orientation(struct image_data *, unsigned char **);
481
static int getCropOffsets(struct image_data *, struct crop_mask *, struct dump_opts *);
482
static int processCropSelections(struct image_data *, struct crop_mask *,
483
unsigned char **, struct buffinfo []);
484
static int writeSelections(TIFF *, TIFF **, struct crop_mask *, struct image_data *,
485
struct dump_opts *, struct buffinfo [],
486
char *, char *, unsigned int*, unsigned int);
488
/* Section functions */
489
static int createImageSection(uint32, unsigned char **);
490
static int extractImageSection(struct image_data *, struct pageseg *,
491
unsigned char *, unsigned char *);
492
static int writeSingleSection(TIFF *, TIFF *, struct image_data *,
493
struct dump_opts *, uint32, uint32,
494
double, double, unsigned char *);
495
static int writeImageSections(TIFF *, TIFF *, struct image_data *,
496
struct pagedef *, struct pageseg *,
497
struct dump_opts *, unsigned char *,
499
/* Whole image functions */
500
static int createCroppedImage(struct image_data *, struct crop_mask *,
501
unsigned char **, unsigned char **);
502
static int writeCroppedImage(TIFF *, TIFF *, struct image_data *image,
503
struct dump_opts * dump,
504
uint32, uint32, unsigned char *, int, int);
506
/* Image manipulation functions */
507
static int rotateContigSamples8bits(uint16, uint16, uint16, uint32,
508
uint32, uint32, uint8 *, uint8 *);
509
static int rotateContigSamples16bits(uint16, uint16, uint16, uint32,
510
uint32, uint32, uint8 *, uint8 *);
511
static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
512
uint32, uint32, uint8 *, uint8 *);
513
static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
514
uint32, uint32, uint8 *, uint8 *);
515
static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
517
static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
519
static int invertImage(uint16, uint16, uint16, uint32, uint32,
522
/* Functions to reverse the sequence of samples in a scanline */
523
static int reverseSamples8bits (uint16, uint16, uint32, uint8 *, uint8 *);
524
static int reverseSamples16bits (uint16, uint16, uint32, uint8 *, uint8 *);
525
static int reverseSamples24bits (uint16, uint16, uint32, uint8 *, uint8 *);
526
static int reverseSamples32bits (uint16, uint16, uint32, uint8 *, uint8 *);
527
static int reverseSamplesBytes (uint16, uint16, uint32, uint8 *, uint8 *);
529
/* Functions for manipulating individual samples in an image */
530
static int extractSeparateRegion(struct image_data *, struct crop_mask *,
531
unsigned char *, unsigned char *, int);
532
static int extractCompositeRegions(struct image_data *, struct crop_mask *,
533
unsigned char *, unsigned char *);
534
static int extractContigSamples8bits (uint8 *, uint8 *, uint32,
535
tsample_t, uint16, uint16,
536
tsample_t, uint32, uint32);
537
static int extractContigSamples16bits (uint8 *, uint8 *, uint32,
538
tsample_t, uint16, uint16,
539
tsample_t, uint32, uint32);
540
static int extractContigSamples24bits (uint8 *, uint8 *, uint32,
541
tsample_t, uint16, uint16,
542
tsample_t, uint32, uint32);
543
static int extractContigSamples32bits (uint8 *, uint8 *, uint32,
544
tsample_t, uint16, uint16,
545
tsample_t, uint32, uint32);
546
static int extractContigSamplesBytes (uint8 *, uint8 *, uint32,
547
tsample_t, uint16, uint16,
548
tsample_t, uint32, uint32);
549
static int extractContigSamplesShifted8bits (uint8 *, uint8 *, uint32,
550
tsample_t, uint16, uint16,
551
tsample_t, uint32, uint32,
553
static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
554
tsample_t, uint16, uint16,
555
tsample_t, uint32, uint32,
557
static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
558
tsample_t, uint16, uint16,
559
tsample_t, uint32, uint32,
561
static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
562
tsample_t, uint16, uint16,
563
tsample_t, uint32, uint32,
565
/* Functions to combine separate planes into interleaved planes */
566
static int combineSeparateSamples8bits (uint8 *[], uint8 *, uint32, uint32,
567
uint16, uint16, FILE *, int, int);
568
static int combineSeparateSamples16bits (uint8 *[], uint8 *, uint32, uint32,
569
uint16, uint16, FILE *, int, int);
570
static int combineSeparateSamples24bits (uint8 *[], uint8 *, uint32, uint32,
571
uint16, uint16, FILE *, int, int);
572
static int combineSeparateSamples32bits (uint8 *[], uint8 *, uint32, uint32,
573
uint16, uint16, FILE *, int, int);
574
static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
575
uint32, uint32, tsample_t, uint16,
578
/* Dump functions for debugging */
579
static void dump_info (FILE *, int, char *, char *, ...);
580
static int dump_data (FILE *, int, char *, unsigned char *, uint32);
581
static int dump_byte (FILE *, int, char *, unsigned char);
582
static int dump_short (FILE *, int, char *, uint16);
583
static int dump_long (FILE *, int, char *, uint32);
584
static int dump_wide (FILE *, int, char *, uint64);
585
static int dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *);
587
/* End function declarations */
588
/* Functions derived in whole or in part from tiffcp */
590
/* The following functions are taken largely intact from tiffcp */
592
static char tiffcrop_version_id[] = "2.0";
593
static char tiffcrop_rev_date[] = "01-06-2009";
594
static char* stuff[] = {
595
"usage: tiffcrop [options] source1 ... sourceN destination",
596
"where options are:",
597
" -h Print this syntax listing",
598
" -v Print tiffcrop version identifier and last revision date",
600
" -a Append to output instead of overwriting",
601
" -d offset Set initial directory offset, counting first image as one, not zero",
602
" -p contig Pack samples contiguously (e.g. RGBRGB...)",
603
" -p separate Store samples separately (e.g. RRR...GGG...BBB...)",
604
" -s Write output in strips",
605
" -t Write output in tiles",
606
" -i Ignore read errors",
608
" -r # Make each strip have no more than # rows",
609
" -w # Set output tile width (pixels)",
610
" -l # Set output tile length (pixels)",
612
" -f lsb2msb Force lsb-to-msb FillOrder for output",
613
" -f msb2lsb Force msb-to-lsb FillOrder for output",
615
" -c lzw[:opts] Compress output with Lempel-Ziv & Welch encoding",
616
" -c zip[:opts] Compress output with deflate encoding",
617
" -c jpeg[:opts] compress output with JPEG encoding",
618
" -c packbits Compress output with packbits encoding",
619
" -c g3[:opts] Compress output with CCITT Group 3 encoding",
620
" -c g4 Compress output with CCITT Group 4 encoding",
621
" -c none Use no compression algorithm on output",
624
" 1d Use default CCITT Group 3 1D-encoding",
625
" 2d Use optional CCITT Group 3 2D-encoding",
626
" fill Byte-align EOL codes",
627
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
630
" # Set compression quality level (0-100, default 75)",
631
" r Output color image as RGB rather than YCbCr",
632
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
634
"LZW and deflate options:",
635
" # Set predictor value",
636
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
638
"Page and selection options:",
639
" -N odd|even|#,#-#,#|last sequences and ranges of images within file to process",
640
" The words odd or even may be used to specify all odd or even numbered images.",
641
" The word last may be used in place of a number in the sequence to indicate.",
642
" The final image in the file without knowing how many images there are.",
643
" Numbers are counted from one even though TIFF IFDs are counted from zero.",
645
" -E t|l|r|b edge to use as origin for width and length of crop region",
646
" -U units [in, cm, px ] inches, centimeters or pixels",
648
" -m #,#,#,# margins from edges for selection: top, left, bottom, right separated by commas",
649
" -X # horizontal dimension of region to extract expressed in current units",
650
" -Y # vertical dimension of region to extract expressed in current units",
651
" -Z #:#,#:# zones of the image designated as position X of Y,",
652
" eg 1:3 would be first of three equal portions measured from reference edge",
653
" -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
654
" regions of the image designated by upper left and lower right coordinates",
656
"Export grouping options:",
657
" -e c|d|i|m|s export mode for images and selections from input images.",
658
" When exporting a composite image from multiple zones or regions",
659
" (combined and image modes), the selections must have equal sizes",
660
" for the axis perpendicular to the edge specified with -E.",
661
" c|combined All images and selections are written to a single file (default).",
662
" with multiple selections from one image combined into a single image.",
663
" d|divided All images and selections are written to a single file",
664
" with each selection from one image written to a new image.",
665
" i|image Each input image is written to a new file (numeric filename sequence)",
666
" with multiple selections from the image combined into one image.",
667
" m|multiple Each input image is written to a new file (numeric filename sequence)",
668
" with each selection from the image written to a new image.",
669
" s|separated Individual selections from each image are written to separate files.",
672
" -H # Set horizontal resolution of output images to #",
673
" -V # Set vertical resolution of output images to #",
674
" -J # Set horizontal margin of output page to # expressed in current units",
675
" -K # Set verticalal margin of output page to # expressed in current units",
677
" -O orient orientation for output image, portrait, landscape, auto",
678
" -P page page size for output image segments, eg letter, legal, tabloid, etc",
679
" -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
682
" flip (mirror) image or region horizontally, vertically, or both",
683
" -R # [90,180,or 270] degrees clockwise rotation of image or extracted region",
684
" -I [black|white|data|both]",
685
" invert color space, eg dark to light for bilevel and grayscale images",
686
" If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
687
" tag to MinIsBlack or MinIsWhite without altering the image data",
688
" If the argument is data or both, the image data are modified:",
689
" both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
690
" data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
692
"-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
693
" Debug/dump program progress and/or data to non-TIFF files.",
694
" Options include the following and must be joined as a comma",
695
" separate list. The use of this option is generally limited to",
696
" program debugging and development of future options.",
698
" debug:N Display limited program progress indicators where larger N",
699
" increase the level of detail. The program must be compiled with",
700
" -DDEBUG -DDEBUG2 to enable full debug reporting",
702
" format:txt|raw Format any logged data as ASCII text or raw binary ",
703
" values. ASCII text dumps include strings of ones and zeroes",
704
" representing the binary values in the image data plus identifying headers.",
706
" level:N Specify the level of detail presented in the dump files.",
707
" This can vary from dumps of the entire input or output image data to dumps",
708
" of data processed by specific functions. Current range of levels is 1 to 3.",
710
" input:full-path-to-directory/input-dumpname",
712
" output:full-path-to-directory/output-dumpnaem",
714
" When dump files are being written, each image will be written to a separate",
715
" file with the name built by adding a numeric sequence value to the dumpname",
716
" and an extension of .txt for ASCII dumps or .bin for binary dumps.",
718
" The four debug/dump options are independent, though it makes little sense to",
719
" specify a dump file without specifying a detail level.",
724
static int readContigTilesIntoBuffer (TIFF* in, uint8* buf,
730
tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
731
uint32 imagew = TIFFScanlineSize(in);
732
uint32 tilew = TIFFTileRowSize(in);
733
int iskew = imagew - tilew;
734
uint8* bufp = (uint8*) buf;
741
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
742
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
744
for (row = 0; row < imagelength; row += tl) {
745
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
749
for (col = 0; col < imagewidth; col += tw) {
750
if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
752
TIFFError(TIFFFileName(in),
753
"Error, can't read tile at %lu %lu",
755
(unsigned long) row);
759
if (colb + tilew > imagew) {
760
uint32 width = imagew - colb;
761
uint32 oskew = tilew - width;
762
cpStripToTile(bufp + colb,
763
tilebuf, nrow, width,
764
oskew + iskew, oskew );
766
cpStripToTile(bufp + colb,
767
tilebuf, nrow, tilew,
771
bufp += imagew * nrow;
778
static int readSeparateTilesIntoBuffer (TIFF* in, uint8 *buf,
779
uint32 imagelength, uint32 imagewidth, uint16 spp)
782
uint32 imagew = TIFFRasterScanlineSize(in);
783
uint32 tilew = TIFFTileRowSize(in);
784
int iskew = imagew - tilew*spp;
785
tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
786
uint8* bufp = (uint8*) buf;
789
uint16 bps, bytes_per_sample;
793
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
794
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
795
(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
796
assert( bps % 8 == 0 );
797
bytes_per_sample = bps/8;
799
for (row = 0; row < imagelength; row += tl) {
800
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
804
for (col = 0; col < imagewidth; col += tw) {
807
for (s = 0; s < spp; s++) {
808
if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
810
TIFFError(TIFFFileName(in),
811
"Error, can't read tile at %lu %lu, "
820
* Tile is clipped horizontally. Calculate
821
* visible portion and skewing factors.
823
if (colb + tilew*spp > imagew) {
824
uint32 width = imagew - colb;
825
int oskew = tilew*spp - width;
826
cpSeparateBufToContigBuf(
827
bufp+colb+s*bytes_per_sample,
829
width/(spp*bytes_per_sample),
834
cpSeparateBufToContigBuf(
835
bufp+colb+s*bytes_per_sample,
842
bufp += imagew * nrow;
849
static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength,
850
uint32 imagewidth, tsample_t spp)
852
uint32 row, rowsperstrip;
855
(void) imagewidth; (void) spp;
856
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
857
for (row = 0; row < imagelength; row += rowsperstrip) {
858
uint32 nrows = (row+rowsperstrip > imagelength) ?
859
imagelength-row : rowsperstrip;
860
tsize_t stripsize = TIFFVStripSize(out, nrows);
861
if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) {
862
TIFFError(TIFFFileName(out),
863
"Error, can't write strip %u", strip - 1);
871
/* Function modified from original tiffcp version with plans to
872
* extend so that plannar orientation separate images do not have
873
* all samples for each channel written before all sampels for the
874
* next channel. Current code is very similar in design to original.
877
writeBufferToSeparateStrips (TIFF* out, uint8* buf,
878
uint32 length, uint32 width, uint16 spp,
879
struct dump_opts *dump)
883
uint32 row, nrows, rowsize, rowsperstrip;
884
uint32 bytes_per_sample;
887
tsize_t stripsize = TIFFStripSize(out);
888
tsize_t rowstripsize, scanlinesize = TIFFScanlineSize(out);
889
tsize_t total_bytes = 0;
892
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
893
(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
894
bytes_per_sample = (bps + 7) / 8;
895
rowsize = ((bps * spp * width) + 7) / 8;
896
rowstripsize = rowsperstrip * bytes_per_sample * (width + 1);
898
obuf = _TIFFmalloc (rowstripsize);
902
for (s = 0; s < spp; s++)
904
for (row = 0; row < length; row += rowsperstrip)
906
nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
908
stripsize = TIFFVStripSize(out, nrows);
909
src = buf + (row * rowsize);
910
total_bytes += stripsize;
911
memset (obuf, '\0', rowstripsize);
912
if (extractContigSamplesToBuffer(obuf, src, nrows, width, 0, 0, s, spp, bps, dump))
917
if ((dump->outfile != NULL) && (dump->level == 1))
919
dump_info(dump->outfile, dump->format,"",
920
"Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d",
921
s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
922
dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
925
if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
927
TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
934
/* Abandoning this code for now. Would be nice to be able to write
935
* one or more rows of each color to successive strips, rather than
936
* all the rows of a given color before any rows of the next color.
938
tsize_t row_buffsize;
939
row_buffsize = scanlinesize + (((spp + bps) + 7) / 8);
940
obuf = _TIFFmalloc (row_buffsize);
945
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
946
for (row = 0; row < length; row++)
948
src = buf + (row * rowsize);
949
total_bytes += scanlinesize;
950
for (s = 0; s < spp; s++)
952
memset (obuf, '\0', row_buffsize);
953
if (extractContigSamplesToBuffer(obuf, src, 1, width, 0, 0, s, spp, bps, dump))
958
if ((dump->outfile != NULL) && (dump->level == 1))
960
dump_info(dump->outfile, dump->format,"",
961
"Row %4d, Sample %2d, bytes: %4d, Input offset: %6d",
962
row + 1, s + 1, scanlinesize, src - buf);
963
dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
966
if (TIFFWriteScanline(out, obuf, row, s) < 0)
968
TIFFError(TIFFFileName(out), "Error, can't write scanline %lu", row + 1);
980
static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
981
uint32 imagewidth, tsample_t spp)
983
uint32 imagew = TIFFScanlineSize(out);
984
uint32 tilew = TIFFTileRowSize(out);
985
int iskew = imagew - tilew;
986
tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
987
uint8* bufp = (uint8*) buf;
994
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
995
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
996
for (row = 0; row < imagelength; row += tilelength) {
997
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1001
for (col = 0; col < imagewidth; col += tw) {
1003
* Tile is clipped horizontally. Calculate
1004
* visible portion and skewing factors.
1006
if (colb + tilew > imagew) {
1007
uint32 width = imagew - colb;
1008
int oskew = tilew - width;
1009
cpStripToTile(obuf, bufp + colb, nrow, width,
1010
oskew, oskew + iskew);
1012
cpStripToTile(obuf, bufp + colb, nrow, tilew,
1014
if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
1015
TIFFError(TIFFFileName(out),
1016
"Error, can't write tile at %lu %lu",
1017
(unsigned long) col,
1018
(unsigned long) row);
1024
bufp += nrow * imagew;
1030
static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
1031
uint32 imagewidth, tsample_t spp,
1032
struct dump_opts * dump)
1034
uint32 imagew = TIFFScanlineSize(out);
1035
tsize_t tilew = TIFFTileRowSize(out);
1036
uint32 iimagew = TIFFRasterScanlineSize(out);
1037
int iskew = iimagew - tilew*spp;
1038
tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1039
uint8* bufp = (uint8*) buf;
1042
uint16 bps, bytes_per_sample;
1046
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1047
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1048
(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1049
assert( bps % 8 == 0 );
1050
bytes_per_sample = (bps + 7)/8;
1052
for (row = 0; row < imagelength; row += tl) {
1053
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1057
for (col = 0; col < imagewidth; col += tw) {
1059
for (s = 0; s < spp; s++) {
1061
* Tile is clipped horizontally. Calculate
1062
* visible portion and skewing factors.
1064
if (colb + tilew > imagew) {
1065
uint32 width = (imagew - colb);
1066
int oskew = tilew - width;
1068
extractContigSamplesToBuffer(obuf,
1069
bufp + (colb*spp) + s,
1070
nrow, width/bytes_per_sample,
1071
oskew, (oskew*spp)+iskew, s,
1074
extractContigSamplesToBuffer(obuf,
1075
bufp + (colb*spp) + s,
1079
if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
1080
TIFFError(TIFFFileName(out),
1081
"Error, can't write tile at %lu %lu "
1083
(unsigned long) col,
1084
(unsigned long) row,
1092
bufp += nrow * iimagew;
1100
processG3Options(char* cp)
1102
if( (cp = strchr(cp, ':')) ) {
1103
if (defg3opts == (uint32) -1)
1107
if (strneq(cp, "1d", 2))
1108
defg3opts &= ~GROUP3OPT_2DENCODING;
1109
else if (strneq(cp, "2d", 2))
1110
defg3opts |= GROUP3OPT_2DENCODING;
1111
else if (strneq(cp, "fill", 4))
1112
defg3opts |= GROUP3OPT_FILLBITS;
1115
} while( (cp = strchr(cp, ':')) );
1120
processCompressOptions(char* opt)
1122
if (streq(opt, "none")) {
1123
defcompression = COMPRESSION_NONE;
1124
} else if (streq(opt, "packbits")) {
1125
defcompression = COMPRESSION_PACKBITS;
1126
} else if (strneq(opt, "jpeg", 4)) {
1127
char* cp = strchr(opt, ':');
1129
defcompression = COMPRESSION_JPEG;
1132
if (isdigit((int)cp[1]))
1133
quality = atoi(cp+1);
1134
else if (cp[1] == 'r' )
1135
jpegcolormode = JPEGCOLORMODE_RAW;
1139
cp = strchr(cp+1,':');
1141
} else if (strneq(opt, "g3", 2)) {
1142
processG3Options(opt);
1143
defcompression = COMPRESSION_CCITTFAX3;
1144
} else if (streq(opt, "g4")) {
1145
defcompression = COMPRESSION_CCITTFAX4;
1146
} else if (strneq(opt, "lzw", 3)) {
1147
char* cp = strchr(opt, ':');
1149
defpredictor = atoi(cp+1);
1150
defcompression = COMPRESSION_LZW;
1151
} else if (strneq(opt, "zip", 3)) {
1152
char* cp = strchr(opt, ':');
1154
defpredictor = atoi(cp+1);
1155
defcompression = COMPRESSION_ADOBE_DEFLATE;
1168
setbuf(stderr, buf);
1169
fprintf(stderr, "\n%s\n", TIFFGetVersion());
1170
for (i = 0; stuff[i] != NULL; i++)
1171
fprintf(stderr, "%s\n", stuff[i]);
1175
#define CopyField(tag, v) \
1176
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
1177
#define CopyField2(tag, v1, v2) \
1178
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
1179
#define CopyField3(tag, v1, v2, v3) \
1180
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
1181
#define CopyField4(tag, v1, v2, v3, v4) \
1182
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
1185
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
1191
CopyField(tag, shortv);
1192
} else if (count == 2) {
1193
uint16 shortv1, shortv2;
1194
CopyField2(tag, shortv1, shortv2);
1195
} else if (count == 4) {
1196
uint16 *tr, *tg, *tb, *ta;
1197
CopyField4(tag, tr, tg, tb, ta);
1198
} else if (count == (uint16) -1) {
1201
CopyField2(tag, shortv1, shortav);
1206
CopyField(tag, longv);
1212
CopyField(tag, floatv);
1213
} else if (count == (uint16) -1) {
1215
CopyField(tag, floatav);
1220
CopyField(tag, stringv);
1226
CopyField(tag, doublev);
1227
} else if (count == (uint16) -1) {
1229
CopyField(tag, doubleav);
1233
TIFFError(TIFFFileName(in),
1234
"Data type %d is not supported, tag %d skipped.",
1239
static struct cpTag {
1244
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
1245
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
1246
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
1247
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
1248
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
1249
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
1250
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
1251
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
1252
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
1253
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
1254
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
1255
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
1256
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
1257
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
1258
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
1259
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
1260
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
1261
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
1262
{ TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
1263
{ TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
1264
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
1265
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
1266
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
1267
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
1268
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
1269
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
1270
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
1271
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
1272
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
1273
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
1274
{ TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
1275
{ TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
1276
{ TIFFTAG_STONITS, 1, TIFF_DOUBLE },
1278
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
1280
#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
1283
cpStripToTile(uint8* out, uint8* in,
1284
uint32 rows, uint32 cols, int outskew, int inskew)
1286
while (rows-- > 0) {
1296
/* Fucntions written by Richard Nolde, with exceptions noted. */
1297
void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
1298
uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
1299
uint32 *deftilelength, uint32 *defrowsperstrip,
1300
struct crop_mask *crop_data, struct pagedef *page,
1301
struct dump_opts *dump,
1302
unsigned int *imagelist, unsigned int *image_count )
1304
int c, good_args = 0;
1305
char *opt_offset = NULL; /* Position in string of value sought */
1306
char *opt_ptr = NULL; /* Pointer to next token in option set */
1307
char *sep = NULL; /* Pointer to a token separator */
1308
unsigned int i, j, start, end;
1310
extern char* optarg;
1314
while ((c = getopt(argc, argv,
1315
"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)
1319
case 'a': mode[0] = 'a'; /* append to output */
1321
case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
1323
TIFFError ("Unknown compression option", "%s", optarg);
1324
TIFFError ("For valid options type", "tiffcrop -h");
1328
case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
1331
TIFFError ("","Directory offset must be greater than zero");
1332
TIFFError ("For valid options type", "tiffcrop -h");
1335
*dirnum = start - 1;
1337
case 'e': switch (tolower(optarg[0])) /* image export modes*/
1339
case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
1340
crop_data->img_mode = COMPOSITE_IMAGES;
1341
break; /* Composite */
1342
case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
1343
crop_data->img_mode = SEPARATED_IMAGES;
1344
break; /* Divided */
1345
case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
1346
crop_data->img_mode = COMPOSITE_IMAGES;
1348
case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
1349
crop_data->img_mode = SEPARATED_IMAGES;
1350
break; /* Multiple */
1351
case 's': crop_data->exp_mode = FILE_PER_SELECTION;
1352
crop_data->img_mode = SEPARATED_IMAGES;
1353
break; /* Sections */
1354
default: TIFFError ("Unknown export mode","%s", optarg);
1355
TIFFError ("For valid options type", "tiffcrop -h");
1359
case 'f': if (streq(optarg, "lsb2msb")) /* fill order */
1360
*deffillorder = FILLORDER_LSB2MSB;
1361
else if (streq(optarg, "msb2lsb"))
1362
*deffillorder = FILLORDER_MSB2LSB;
1365
TIFFError ("Unknown fill order", "%s", optarg);
1366
TIFFError ("For valid options type", "tiffcrop -h");
1372
case 'i': ignore = TRUE; /* ignore errors */
1374
case 'l': outtiled = TRUE; /* tile length */
1375
*deftilelength = atoi(optarg);
1377
case 'p': /* planar configuration */
1378
if (streq(optarg, "separate"))
1379
*defconfig = PLANARCONFIG_SEPARATE;
1380
else if (streq(optarg, "contig"))
1381
*defconfig = PLANARCONFIG_CONTIG;
1384
TIFFError ("Unkown planar configuration", "%s", optarg);
1385
TIFFError ("For valid options type", "tiffcrop -h");
1389
case 'r': /* rows/strip */
1390
*defrowsperstrip = atol(optarg);
1392
case 's': /* generate stripped output */
1395
case 't': /* generate tiled output */
1398
case 'v': TIFFError ("Tiffcrop version", "%s, last updated: %s",
1399
tiffcrop_version_id, tiffcrop_rev_date);
1400
TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
1401
TIFFError (" ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
1402
TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2009 Richard Nolde");
1405
case 'w': /* tile width */
1407
*deftilewidth = atoi(optarg);
1409
case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
1410
crop_data->crop_mode |= CROP_REGIONS;
1411
for (i = 0, opt_ptr = strtok (optarg, ":");
1412
((opt_ptr != NULL) && (i < MAX_REGIONS));
1413
(opt_ptr = strtok (NULL, ":")), i++)
1415
crop_data->regions++;
1416
if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
1417
&crop_data->corners[i].X1, &crop_data->corners[i].Y1,
1418
&crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
1420
TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
1421
TIFFError ("For valid options type", "tiffcrop -h");
1425
/* check for remaining elements over MAX_REGIONS */
1426
if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
1428
TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
1429
TIFFError ("For valid options type", "tiffcrop -h");
1433
/* options for file open modes */
1434
case 'B': *mp++ = 'b'; *mp = '\0';
1436
case 'L': *mp++ = 'l'; *mp = '\0';
1438
case 'M': *mp++ = 'm'; *mp = '\0';
1440
case 'C': *mp++ = 'c'; *mp = '\0';
1442
/* options for Debugging / data dump */
1443
case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
1445
(opt_ptr = strtok (NULL, ",")), i++)
1447
opt_offset = strpbrk(opt_ptr, ":=");
1449
opt_offset = strchr(opt_ptr, ':');
1451
if (opt_offset == NULL)
1453
TIFFError("Invalid dump option", "%s", optarg);
1454
TIFFError ("For valid options type", "tiffcrop -h");
1459
/* convert option to lowercase */
1460
end = strlen (opt_ptr);
1461
for (i = 0; i < end; i++)
1462
*(opt_ptr + i) = tolower(*(opt_ptr + i));
1463
/* Look for dump format specification */
1464
if (strncmp(opt_ptr, "for", 3) == 0)
1466
/* convert value to lowercase */
1467
end = strlen (opt_offset + 1);
1468
for (i = 1; i <= end; i++)
1469
*(opt_offset + i) = tolower(*(opt_offset + i));
1470
/* check dump format value */
1471
if (strncmp (opt_offset + 1, "txt", 3) == 0)
1473
dump->format = DUMP_TEXT;
1474
strcpy (dump->mode, "w");
1478
if (strncmp(opt_offset + 1, "raw", 3) == 0)
1480
dump->format = DUMP_RAW;
1481
strcpy (dump->mode, "wb");
1485
TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
1486
TIFFError ("For valid options type", "tiffcrop -h");
1492
{ /* Look for dump level specification */
1493
if (strncmp (opt_ptr, "lev", 3) == 0)
1494
dump->level = atoi(opt_offset + 1);
1495
/* Look for input data dump file name */
1496
if (strncmp (opt_ptr, "in", 2) == 0)
1497
strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
1498
/* Look for output data dump file name */
1499
if (strncmp (opt_ptr, "out", 3) == 0)
1500
strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
1501
if (strncmp (opt_ptr, "deb", 3) == 0)
1502
dump->debug = atoi(opt_offset + 1);
1505
if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
1507
if (dump->level == 1)
1508
TIFFError("","Defaulting to dump level 1, no data.");
1509
if (dump->format == DUMP_NONE)
1511
TIFFError("", "You must specify a dump format for dump files");
1512
TIFFError ("For valid options type", "tiffcrop -h");
1518
/* image manipulation routine options */
1519
case 'm': /* margins to exclude from selection, uppercase M was already used */
1520
/* order of values must be TOP, LEFT, BOTTOM, RIGHT */
1521
crop_data->crop_mode |= CROP_MARGINS;
1522
for (i = 0, opt_ptr = strtok (optarg, ",:");
1523
((opt_ptr != NULL) && (i < 4));
1524
(opt_ptr = strtok (NULL, ",:")), i++)
1526
crop_data->margins[i] = atof(opt_ptr);
1529
case 'E': /* edge reference */
1530
switch (tolower(optarg[0]))
1532
case 't': crop_data->edge_ref = EDGE_TOP;
1534
case 'b': crop_data->edge_ref = EDGE_BOTTOM;
1536
case 'l': crop_data->edge_ref = EDGE_LEFT;
1538
case 'r': crop_data->edge_ref = EDGE_RIGHT;
1540
default: TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
1541
TIFFError ("For valid options type", "tiffcrop -h");
1545
case 'F': /* flip eg mirror image or cropped segment, M was already used */
1546
crop_data->crop_mode |= CROP_MIRROR;
1547
switch (tolower(optarg[0]))
1549
case 'h': crop_data->mirror = MIRROR_HORIZ;
1551
case 'v': crop_data->mirror = MIRROR_VERT;
1553
case 'b': crop_data->mirror = MIRROR_BOTH;
1555
default: TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
1556
TIFFError ("For valid options type", "tiffcrop -h");
1560
case 'H': /* set horizontal resolution to new value */
1561
page->hres = atof (optarg);
1562
page->mode |= PAGE_MODE_RESOLUTION;
1564
case 'I': /* invert the color space, eg black to white */
1565
crop_data->crop_mode |= CROP_INVERT;
1566
/* The PHOTOMETIC_INTERPRETATION tag may be updated */
1567
if (streq(optarg, "black"))
1569
crop_data->photometric = PHOTOMETRIC_MINISBLACK;
1572
if (streq(optarg, "white"))
1574
crop_data->photometric = PHOTOMETRIC_MINISWHITE;
1577
if (streq(optarg, "data"))
1579
crop_data->photometric = INVERT_DATA_ONLY;
1582
if (streq(optarg, "both"))
1584
crop_data->photometric = INVERT_DATA_AND_TAG;
1588
TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
1589
TIFFError ("For valid options type", "tiffcrop -h");
1592
case 'J': /* horizontal margin for sectioned ouput pages */
1593
page->hmargin = atof(optarg);
1594
page->mode |= PAGE_MODE_MARGINS;
1596
case 'K': /* vertical margin for sectioned ouput pages*/
1597
page->vmargin = atof(optarg);
1598
page->mode |= PAGE_MODE_MARGINS;
1600
case 'N': /* list of images to process */
1601
for (i = 0, opt_ptr = strtok (optarg, ",");
1602
((opt_ptr != NULL) && (i < MAX_IMAGES));
1603
(opt_ptr = strtok (NULL, ",")))
1604
{ /* We do not know how many images are in file yet
1605
* so we build a list to include the maximum allowed
1606
* and follow it until we hit the end of the file.
1607
* Image count is not accurate for odd, even, last
1608
* so page numbers won't be valid either.
1610
if (streq(opt_ptr, "odd"))
1612
for (j = 1; j <= MAX_IMAGES; j += 2)
1614
*image_count = (MAX_IMAGES - 1) / 2;
1619
if (streq(opt_ptr, "even"))
1621
for (j = 2; j <= MAX_IMAGES; j += 2)
1623
*image_count = MAX_IMAGES / 2;
1628
if (streq(opt_ptr, "last"))
1629
imagelist[i++] = MAX_IMAGES;
1630
else /* single value between commas */
1632
sep = strpbrk(opt_ptr, ":-");
1634
imagelist[i++] = atoi(opt_ptr) - 1;
1638
start = atoi (opt_ptr);
1639
if (!strcmp((sep + 1), "last"))
1642
end = atoi (sep + 1);
1643
for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
1644
imagelist[i++] = j - 1;
1652
case 'O': /* page orientation */
1653
switch (tolower(optarg[0]))
1655
case 'a': page->orient = ORIENTATION_AUTO;
1657
case 'p': page->orient = ORIENTATION_PORTRAIT;
1659
case 'l': page->orient = ORIENTATION_LANDSCAPE;
1661
default: TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
1662
TIFFError ("For valid options type", "tiffcrop -h");
1666
case 'P': /* page size selection */
1667
if (get_page_geometry (optarg, page))
1669
if (!strcmp(optarg, "list"))
1671
TIFFError("", "Name Width Length (in inches)");
1672
for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1673
TIFFError ("", "%-15.15s %5.2f %5.2f",
1674
PaperTable[i].name, PaperTable[i].width,
1675
PaperTable[i].length);
1679
TIFFError ("Invalid paper size", "%s", optarg);
1680
TIFFError ("", "Select one of:");
1681
TIFFError("", "Name Width Length (in inches)");
1682
for (i = 0; i < MAX_PAPERNAMES - 1; i++)
1683
TIFFError ("", "%-15.15s %5.2f %5.2f",
1684
PaperTable[i].name, PaperTable[i].width,
1685
PaperTable[i].length);
1690
page->mode |= PAGE_MODE_PAPERSIZE;
1693
case 'R': /* rotate image or cropped segment */
1694
crop_data->crop_mode |= CROP_ROTATE;
1695
switch (strtoul(optarg, NULL, 0))
1697
case 90: crop_data->rotation = (uint16)90;
1699
case 180: crop_data->rotation = (uint16)180;
1701
case 270: crop_data->rotation = (uint16)270;
1703
default: TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
1704
TIFFError ("For valid options type", "tiffcrop -h");
1708
case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
1709
sep = strpbrk(optarg, ",:");
1713
page->cols = atoi(optarg);
1714
page->rows = atoi(sep +1);
1718
page->cols = atoi(optarg);
1719
page->rows = atoi(optarg);
1721
if ((page->cols * page->rows) > MAX_SECTIONS)
1723
TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
1726
page->mode |= PAGE_MODE_ROWSCOLS;
1728
case 'U': /* units for measurements and offsets */
1729
if (streq(optarg, "in"))
1731
crop_data->res_unit = RESUNIT_INCH;
1732
page->res_unit = RESUNIT_INCH;
1734
else if (streq(optarg, "cm"))
1736
crop_data->res_unit = RESUNIT_CENTIMETER;
1737
page->res_unit = RESUNIT_CENTIMETER;
1739
else if (streq(optarg, "px"))
1741
crop_data->res_unit = RESUNIT_NONE;
1742
page->res_unit = RESUNIT_NONE;
1746
TIFFError ("Illegal unit of measure","%s", optarg);
1747
TIFFError ("For valid options type", "tiffcrop -h");
1751
case 'V': /* set vertical resolution to new value */
1752
page->vres = atof (optarg);
1753
page->mode |= PAGE_MODE_RESOLUTION;
1755
case 'X': /* selection width */
1756
crop_data->crop_mode |= CROP_WIDTH;
1757
crop_data->width = atof(optarg);
1759
case 'Y': /* selection length */
1760
crop_data->crop_mode |= CROP_LENGTH;
1761
crop_data->length = atof(optarg);
1763
case 'Z': /* zones of an image X:Y read as zone X of Y */
1764
crop_data->crop_mode |= CROP_ZONES;
1765
for (i = 0, opt_ptr = strtok (optarg, ",");
1766
((opt_ptr != NULL) && (i < MAX_REGIONS));
1767
(opt_ptr = strtok (NULL, ",")), i++)
1770
opt_offset = strchr(opt_ptr, ':');
1772
crop_data->zonelist[i].position = atoi(opt_ptr);
1773
crop_data->zonelist[i].total = atoi(opt_offset + 1);
1775
/* check for remaining elements over MAX_REGIONS */
1776
if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
1778
TIFFError("Zone list exceeds region limit", "%d", MAX_REGIONS);
1782
case '?': TIFFError ("For valid options type", "tiffcrop -h");
1787
} /* end process_command_opts */
1789
/* Start a new output file if one has not been previously opened or
1790
* autoindex is set to non-zero. Update page and file counters
1791
* so TIFFTAG PAGENUM will be correct in image.
1794
update_output_file (TIFF **tiffout, char *mode, int autoindex,
1795
char *outname, unsigned int *page)
1797
static int findex = 0; /* file sequence indicator */
1800
char export_ext[16];
1801
char exportname[PATH_MAX];
1803
strcpy (export_ext, ".tiff");
1804
if (autoindex && (*tiffout != NULL))
1806
/* Close any export file that was previously opened */
1807
TIFFClose (*tiffout);
1811
strncpy (exportname, outname, PATH_MAX - 15);
1812
if (*tiffout == NULL) /* This is a new export file */
1815
{ /* create a new filename for each export */
1817
if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
1819
strncpy (export_ext, sep, 5);
1823
strncpy (export_ext, ".tiff", 5);
1824
export_ext[5] = '\0';
1826
sprintf (filenum, "-%03d%s", findex, export_ext);
1828
strncat (exportname, filenum, 14);
1831
*tiffout = TIFFOpen(exportname, mode);
1832
if (*tiffout == NULL)
1834
TIFFError("update_output_file", "Unable to open output file %s\n", exportname);
1845
} /* end update_output_file */
1849
main(int argc, char* argv[])
1851
uint16 defconfig = (uint16) -1;
1852
uint16 deffillorder = 0;
1853
uint32 deftilewidth = (uint32) -1;
1854
uint32 deftilelength = (uint32) -1;
1855
uint32 defrowsperstrip = (uint32) 0;
1863
/** RJN additions **/
1864
struct image_data image; /* Image parameters for one image */
1865
struct crop_mask crop; /* Cropping parameters for all images */
1866
struct pagedef page; /* Page definition for output pages */
1867
struct pageseg sections[MAX_SECTIONS]; /* Sections of one output page */
1868
struct buffinfo seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
1869
struct dump_opts dump; /* Data dump options */
1870
unsigned char *read_buff = NULL; /* Input image data buffer */
1871
unsigned char *crop_buff = NULL; /* Crop area buffer */
1872
unsigned char *sect_buff = NULL; /* Image section buffer */
1873
unsigned char *sect_src = NULL; /* Image section buffer pointer */
1874
unsigned int imagelist[MAX_IMAGES + 1]; /* individually specified images */
1875
unsigned int image_count = 0;
1876
unsigned int dump_images = 0;
1877
unsigned int next_image = 0;
1878
unsigned int next_page = 0;
1879
unsigned int total_pages = 0;
1880
unsigned int total_images = 0;
1881
unsigned int end_of_input = FALSE;
1883
char temp_filename[PATH_MAX + 1];
1884
memset (temp_filename, '\0', PATH_MAX + 1);
1885
little_endian = *((unsigned char *)&little_endian) & '1';
1887
initImageData(&image);
1888
initCropMasks(&crop);
1889
initPageSetup(&page, sections, seg_buffs);
1890
initDumpOptions(&dump);
1892
process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig,
1893
&deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
1894
&crop, &page, &dump, imagelist, &image_count);
1896
if (argc - optind < 2)
1899
if ((argc - optind) == 2)
1903
/* read multiple input files and write to output file(s) */
1904
while (optind < argc - 1)
1906
in = TIFFOpen (argv[optind], "r");
1910
/* If only one input file is specified, we can use directory count */
1911
total_images = TIFFNumberOfDirectories(in);
1912
if (image_count == 0)
1915
total_pages = total_images; /* Only valid with single input file */
1919
dirnum = (tdir_t)(imagelist[next_image] - 1);
1922
/* Total pages only valid for enumerated list of pages not derived
1923
* using odd, even, or last keywords.
1925
if (image_count > total_images)
1926
image_count = total_images;
1928
total_pages = image_count;
1931
/* MAX_IMAGES is used for special case "last" in selection list */
1932
if (dirnum == (MAX_IMAGES - 1))
1933
dirnum = total_images - 1;
1935
if (dirnum > (total_images))
1937
TIFFError (TIFFFileName(in),
1938
"Invalid image number %d, File contains only %d images",
1939
(int)dirnum + 1, total_images);
1941
(void) TIFFClose(out);
1945
if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
1947
TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
1949
(void) TIFFClose(out);
1953
end_of_input = FALSE;
1954
while (end_of_input == FALSE)
1957
compression = defcompression;
1958
predictor = defpredictor;
1959
fillorder = deffillorder;
1960
rowsperstrip = defrowsperstrip;
1961
tilewidth = deftilewidth;
1962
tilelength = deftilelength;
1965
if (dump.format != DUMP_NONE)
1967
/* manage input and/or output dump files here */
1969
length = strlen(dump.infilename);
1972
if (dump.infile != NULL)
1973
fclose (dump.infile);
1975
sprintf (temp_filename, "%s-read-%03d.%s", dump.infilename, dump_images,
1976
(dump.format == DUMP_TEXT) ? "txt" : "raw");
1977
if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
1979
TIFFError ("Unable to open dump file %s for writing", temp_filename);
1982
dump_info(dump.infile, dump.format, "Reading image","%d from %s",
1983
dump_images, TIFFFileName(in));
1985
length = strlen(dump.outfilename);
1988
if (dump.outfile != NULL)
1989
fclose (dump.outfile);
1991
sprintf (temp_filename, "%s-write-%03d.%s", dump.outfilename, dump_images,
1992
(dump.format == DUMP_TEXT) ? "txt" : "raw");
1993
if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
1995
TIFFError ("Unable to open dump file %s for writing", temp_filename);
1998
dump_info(dump.outfile, dump.format, "Writing image","%d from %s",
1999
dump_images, TIFFFileName(in));
2004
TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
2006
if (loadImage(in, &image, &dump, &read_buff))
2008
TIFFError("main", "Unable to load source image");
2012
/* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
2014
if (image.adjustments != 0)
2016
if (correct_orientation(&image, &read_buff))
2017
TIFFError("main", "Unable to correct image orientation");
2020
if (getCropOffsets(&image, &crop, &dump))
2022
TIFFError("main", "Unable to define crop regions");
2026
if (crop.selections > 0)
2028
if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
2030
TIFFError("main", "Unable to process image selections");
2034
else /* Single image segment without zones or regions */
2036
if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
2038
TIFFError("main", "Unable to create output image");
2042
if (page.mode == PAGE_MODE_NONE)
2043
{ /* Whole image or sections not based on output page size */
2044
if (crop.selections > 0)
2046
writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
2047
mp, argv[argc - 1], &next_page, total_pages);
2049
else /* One file all images and sections */
2051
if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
2054
if (writeCroppedImage(in, out, &image, &dump,crop.combined_width,
2055
crop.combined_length, crop_buff, next_page, total_pages))
2057
TIFFError("main", "Unable to write new image");
2064
/* If we used a crop buffer, our data is there, otherwise it is
2065
* in the read_buffer
2067
if (crop_buff != NULL)
2068
sect_src = crop_buff;
2070
sect_src = read_buff;
2071
/* Break input image into pages or rows and columns */
2072
if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
2074
TIFFError("main", "Unable to compute output section data");
2077
/* If there are multiple files on the command line, the final one is assumed
2078
* to be the output filename into which the images are written.
2080
if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
2083
if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, §_buff))
2085
TIFFError("main", "Unable to write image sections");
2090
/* No image list specified, just read the next image */
2091
if (image_count == 0)
2095
dirnum = (tdir_t)(imagelist[next_image] - 1);
2099
if (dirnum == MAX_IMAGES - 1)
2100
dirnum = TIFFNumberOfDirectories(in) - 1;
2102
if (!TIFFSetDirectory(in, (tdir_t)dirnum))
2103
end_of_input = TRUE;
2109
/* If we did not use the read buffer as the crop buffer */
2111
_TIFFfree(read_buff);
2114
_TIFFfree(crop_buff);
2117
_TIFFfree(sect_buff);
2119
/* Clean up any segment buffers used for zones or regions */
2120
for (seg = 0; seg < crop.selections; seg++)
2121
_TIFFfree (seg_buffs[seg].buffer);
2123
if (dump.format != DUMP_NONE)
2125
if (dump.infile != NULL)
2126
fclose (dump.infile);
2128
if (dump.outfile != NULL)
2130
dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
2131
fclose (dump.outfile);
2141
/* Debugging functions */
2142
static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
2146
char dump_array[10];
2147
unsigned char bitset;
2149
if (dumpfile == NULL)
2151
TIFFError ("", "Invalid FILE pointer for dump file\n");
2155
if (format == DUMP_TEXT)
2157
fprintf (dumpfile," %s ", dump_tag);
2158
for (i = 0; i < count; i++)
2160
for (j = 0, k = 7; j < 8; j++, k--)
2162
bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
2163
sprintf(&dump_array[j], (bitset) ? "1" : "0");
2165
dump_array[8] = '\0';
2166
fprintf (dumpfile," %s", dump_array);
2168
fprintf (dumpfile,"\n");
2172
if ((fwrite (data, 1, count, dumpfile)) != count)
2174
TIFFError ("", "Unable to write binary data to dump file\n");
2182
static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
2185
char dump_array[10];
2186
unsigned char bitset;
2188
if (dumpfile == NULL)
2190
TIFFError ("", "Invalid FILE pointer for dump file\n");
2194
if (format == DUMP_TEXT)
2196
fprintf (dumpfile," %s ", dump_tag);
2197
for (j = 0, k = 7; j < 8; j++, k--)
2199
bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2200
sprintf(&dump_array[j], (bitset) ? "1" : "0");
2202
dump_array[8] = '\0';
2203
fprintf (dumpfile," %s\n", dump_array);
2207
if ((fwrite (&data, 1, 1, dumpfile)) != 1)
2209
TIFFError ("", "Unable to write binary data to dump file\n");
2217
static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
2220
char dump_array[20];
2221
unsigned char bitset;
2223
if (dumpfile == NULL)
2225
TIFFError ("", "Invalid FILE pointer for dump file\n");
2229
if (format == DUMP_TEXT)
2231
fprintf (dumpfile," %s ", dump_tag);
2232
for (j = 0, k = 15; k >= 0; j++, k--)
2234
bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
2235
sprintf(&dump_array[j], (bitset) ? "1" : "0");
2237
sprintf(&dump_array[++j], " ");
2239
dump_array[17] = '\0';
2240
fprintf (dumpfile," %s\n", dump_array);
2244
if ((fwrite (&data, 2, 1, dumpfile)) != 2)
2246
TIFFError ("", "Unable to write binary data to dump file\n");
2254
static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
2257
char dump_array[40];
2258
unsigned char bitset;
2260
if (dumpfile == NULL)
2262
TIFFError ("", "Invalid FILE pointer for dump file\n");
2266
if (format == DUMP_TEXT)
2268
fprintf (dumpfile," %s ", dump_tag);
2269
for (j = 0, k = 31; k >= 0; j++, k--)
2271
bitset = data & (((uint32)1 << k)) ? 1 : 0;
2272
sprintf(&dump_array[j], (bitset) ? "1" : "0");
2274
sprintf(&dump_array[++j], " ");
2276
dump_array[35] = '\0';
2277
fprintf (dumpfile," %s\n", dump_array);
2281
if ((fwrite (&data, 4, 1, dumpfile)) != 4)
2283
TIFFError ("", "Unable to write binary data to dump file\n");
2290
static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
2293
char dump_array[80];
2294
unsigned char bitset;
2296
if (dumpfile == NULL)
2298
TIFFError ("", "Invalid FILE pointer for dump file\n");
2302
if (format == DUMP_TEXT)
2304
fprintf (dumpfile," %s ", dump_tag);
2305
for (j = 0, k = 63; k >= 0; j++, k--)
2307
bitset = data & (((uint64)1 << k)) ? 1 : 0;
2308
sprintf(&dump_array[j], (bitset) ? "1" : "0");
2310
sprintf(&dump_array[++j], " ");
2312
dump_array[71] = '\0';
2313
fprintf (dumpfile," %s\n", dump_array);
2317
if ((fwrite (&data, 8, 1, dumpfile)) != 8)
2319
TIFFError ("", "Unable to write binary data to dump file\n");
2327
static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
2329
if (format == DUMP_TEXT)
2333
fprintf(dumpfile, "%s ", prefix);
2334
vfprintf(dumpfile, msg, ap);
2335
fprintf(dumpfile, "\n");
2339
static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width,
2340
uint32 row, unsigned char *buff)
2344
unsigned char * dump_ptr;
2346
if (dumpfile == NULL)
2348
TIFFError ("", "Invalid FILE pointer for dump file\n");
2352
for (i = 0; i < rows; i++)
2354
dump_ptr = buff + (i * width);
2355
if (format == DUMP_TEXT)
2356
dump_info (dumpfile, format, "",
2357
"Row %4d, %d bytes at offset %d",
2358
row + i + 1, width, row * width);
2360
for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
2361
dump_data (dumpfile, format, "", dump_ptr, 10);
2363
dump_data (dumpfile, format, "", dump_ptr, k);
2368
/* Extract one or more samples from an interleaved buffer. If count == 1,
2369
* only the sample plane indicated by sample will be extracted. If count > 1,
2370
* count samples beginning at sample will be extracted. Portions of a
2371
* scanline can be extracted by specifying a start and end value.
2375
extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols,
2376
tsample_t sample, uint16 spp, uint16 bps,
2377
tsample_t count, uint32 start, uint32 end)
2379
int i, bytes_per_sample, sindex;
2380
uint32 col, dst_rowsize, bit_offset;
2381
uint32 src_byte, src_bit;
2385
if ((src == NULL) || (dst == NULL))
2387
TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
2391
if ((start > end) || (start > cols))
2393
TIFFError ("extractContigSamplesBytes",
2394
"Invalid start column value %d ignored", start);
2397
if ((end == 0) || (end > cols))
2399
TIFFError ("extractContigSamplesBytes",
2400
"Invalid end column value %d ignored", end);
2404
dst_rowsize = (bps * (end - start) * count) / 8;
2406
bytes_per_sample = (bps + 7) / 8;
2407
/* Optimize case for copying all samples */
2410
src = in + (start * spp * bytes_per_sample);
2411
_TIFFmemcpy (dst, src, dst_rowsize);
2415
for (col = start; col < end; col++)
2417
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2419
bit_offset = col * bps * spp;
2422
src_byte = bit_offset / 8;
2423
src_bit = bit_offset % 8;
2427
src_byte = (bit_offset + (sindex * bps)) / 8;
2428
src_bit = (bit_offset + (sindex * bps)) % 8;
2430
src = in + src_byte;
2431
for (i = 0; i < bytes_per_sample; i++)
2438
} /* end extractContigSamplesBytes */
2441
extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
2442
tsample_t sample, uint16 spp, uint16 bps,
2443
tsample_t count, uint32 start, uint32 end)
2445
int ready_bits = 0, sindex = 0;
2446
uint32 col, src_byte, src_bit, bit_offset;
2447
uint8 maskbits = 0, matchbits = 0;
2448
uint8 buff1 = 0, buff2 = 0;
2452
if ((src == NULL) || (dst == NULL))
2454
TIFFError("extractContigSamples8bits","Invalid input or output buffer");
2458
if ((start > end) || (start > cols))
2460
TIFFError ("extractContigSamples8bits",
2461
"Invalid start column value %d ignored", start);
2464
if ((end == 0) || (end > cols))
2466
TIFFError ("extractContigSamples8bits",
2467
"Invalid end column value %d ignored", end);
2472
maskbits = (uint8)-1 >> ( 8 - bps);
2474
for (col = start; col < end; col++)
2475
{ /* Compute src byte(s) and bits within byte(s) */
2476
bit_offset = col * bps * spp;
2477
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2481
src_byte = bit_offset / 8;
2482
src_bit = bit_offset % 8;
2486
src_byte = (bit_offset + (sindex * bps)) / 8;
2487
src_bit = (bit_offset + (sindex * bps)) % 8;
2490
src = in + src_byte;
2491
matchbits = maskbits << (8 - src_bit - bps);
2492
buff1 = ((*src) & matchbits) << (src_bit);
2494
/* If we have a full buffer's worth, write it out */
2495
if (ready_bits >= 8)
2502
buff2 = (buff2 | (buff1 >> ready_bits));
2507
while (ready_bits > 0)
2509
buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
2515
} /* end extractContigSamples8bits */
2518
extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols,
2519
tsample_t sample, uint16 spp, uint16 bps,
2520
tsample_t count, uint32 start, uint32 end)
2522
int ready_bits = 0, sindex = 0;
2523
uint32 col, src_byte, src_bit, bit_offset;
2524
uint16 maskbits = 0, matchbits = 0;
2525
uint16 buff1 = 0, buff2 = 0;
2529
unsigned char swapbuff[2];
2531
if ((src == NULL) || (dst == NULL))
2533
TIFFError("extractContigSamples16bits","Invalid input or output buffer");
2537
if ((start > end) || (start > cols))
2539
TIFFError ("extractContigSamples16bits",
2540
"Invalid start column value %d ignored", start);
2543
if ((end == 0) || (end > cols))
2545
TIFFError ("extractContigSamples16bits",
2546
"Invalid end column value %d ignored", end);
2551
maskbits = (uint16)-1 >> (16 - bps);
2553
for (col = start; col < end; col++)
2554
{ /* Compute src byte(s) and bits within byte(s) */
2555
bit_offset = col * bps * spp;
2556
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2560
src_byte = bit_offset / 8;
2561
src_bit = bit_offset % 8;
2565
src_byte = (bit_offset + (sindex * bps)) / 8;
2566
src_bit = (bit_offset + (sindex * bps)) % 8;
2569
src = in + src_byte;
2570
matchbits = maskbits << (16 - src_bit - bps);
2574
swapbuff[0] = *(src + 1);
2579
swapbuff[1] = *(src + 1);
2581
buff1 = *((uint16 *)swapbuff);
2582
buff1 = (buff1 & matchbits) << (src_bit);
2584
if (ready_bits < 8) /* add another bps bits to the buffer */
2587
buff2 = (buff2 | (buff1 >> ready_bits));
2589
else /* If we have a full buffer's worth, write it out */
2591
bytebuff = (buff2 >> 8);
2594
/* shift in new bits */
2595
buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
2601
/* catch any trailing bits at the end of the line */
2602
while (ready_bits > 0)
2604
bytebuff = (buff2 >> 8);
2610
} /* end extractContigSamples16bits */
2614
extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
2615
tsample_t sample, uint16 spp, uint16 bps,
2616
tsample_t count, uint32 start, uint32 end)
2618
int ready_bits = 0, sindex = 0;
2619
uint32 col, src_byte, src_bit, bit_offset;
2620
uint32 maskbits = 0, matchbits = 0;
2621
uint32 buff1 = 0, buff2 = 0;
2622
uint8 bytebuff1 = 0, bytebuff2 = 0;
2625
unsigned char swapbuff[4];
2627
if ((in == NULL) || (out == NULL))
2629
TIFFError("extractContigSamples24bits","Invalid input or output buffer");
2633
if ((start > end) || (start > cols))
2635
TIFFError ("extractContigSamples24bits",
2636
"Invalid start column value %d ignored", start);
2639
if ((end == 0) || (end > cols))
2641
TIFFError ("extractContigSamples24bits",
2642
"Invalid end column value %d ignored", end);
2647
maskbits = (uint32)-1 >> ( 32 - bps);
2648
for (col = start; col < end; col++)
2650
/* Compute src byte(s) and bits within byte(s) */
2651
bit_offset = col * bps * spp;
2652
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2656
src_byte = bit_offset / 8;
2657
src_bit = bit_offset % 8;
2661
src_byte = (bit_offset + (sindex * bps)) / 8;
2662
src_bit = (bit_offset + (sindex * bps)) % 8;
2665
src = in + src_byte;
2666
matchbits = maskbits << (32 - src_bit - bps);
2670
swapbuff[2] = *(src + 1);
2671
swapbuff[1] = *(src + 2);
2672
swapbuff[0] = *(src + 3);
2677
swapbuff[1] = *(src + 1);
2678
swapbuff[2] = *(src + 2);
2679
swapbuff[3] = *(src + 3);
2682
buff1 = *((uint32 *)swapbuff);
2683
buff1 = (buff1 & matchbits) << (src_bit);
2685
if (ready_bits < 16) /* add another bps bits to the buffer */
2687
bytebuff1 = bytebuff2 = 0;
2688
buff2 = (buff2 | (buff1 >> ready_bits));
2690
else /* If we have a full buffer's worth, write it out */
2692
bytebuff1 = (buff2 >> 24);
2694
bytebuff2 = (buff2 >> 16);
2698
/* shift in new bits */
2699
buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
2705
/* catch any trailing bits at the end of the line */
2706
while (ready_bits > 0)
2708
bytebuff1 = (buff2 >> 24);
2711
buff2 = (buff2 << 8);
2712
bytebuff2 = bytebuff1;
2717
} /* end extractContigSamples24bits */
2720
extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
2721
tsample_t sample, uint16 spp, uint16 bps,
2722
tsample_t count, uint32 start, uint32 end)
2724
int ready_bits = 0, sindex = 0, shift_width = 0;
2725
uint32 col, src_byte, src_bit, bit_offset;
2726
uint32 longbuff1 = 0, longbuff2 = 0;
2727
uint64 maskbits = 0, matchbits = 0;
2728
uint64 buff1 = 0, buff2 = 0, buff3 = 0;
2729
uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
2732
unsigned char swapbuff1[4];
2733
unsigned char swapbuff2[4];
2735
if ((in == NULL) || (out == NULL))
2737
TIFFError("extractContigSamples32bits","Invalid input or output buffer");
2742
if ((start > end) || (start > cols))
2744
TIFFError ("extractContigSamples32bits",
2745
"Invalid start column value %d ignored", start);
2748
if ((end == 0) || (end > cols))
2750
TIFFError ("extractContigSamples32bits",
2751
"Invalid end column value %d ignored", end);
2755
shift_width = ((bps + 7) / 8) + 1;
2757
maskbits = (uint64)-1 >> ( 64 - bps);
2758
for (col = start; col < end; col++)
2760
/* Compute src byte(s) and bits within byte(s) */
2761
bit_offset = col * bps * spp;
2762
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2766
src_byte = bit_offset / 8;
2767
src_bit = bit_offset % 8;
2771
src_byte = (bit_offset + (sindex * bps)) / 8;
2772
src_bit = (bit_offset + (sindex * bps)) % 8;
2775
src = in + src_byte;
2776
matchbits = maskbits << (64 - src_bit - bps);
2779
swapbuff1[3] = *src;
2780
swapbuff1[2] = *(src + 1);
2781
swapbuff1[1] = *(src + 2);
2782
swapbuff1[0] = *(src + 3);
2786
swapbuff1[0] = *src;
2787
swapbuff1[1] = *(src + 1);
2788
swapbuff1[2] = *(src + 2);
2789
swapbuff1[3] = *(src + 3);
2791
longbuff1 = *((uint32 *)swapbuff1);
2793
memset (swapbuff2, '\0', sizeof(swapbuff2));
2796
swapbuff2[3] = *src;
2797
swapbuff2[2] = *(src + 1);
2798
swapbuff2[1] = *(src + 2);
2799
swapbuff2[0] = *(src + 3);
2803
swapbuff2[0] = *src;
2804
swapbuff2[1] = *(src + 1);
2805
swapbuff2[2] = *(src + 2);
2806
swapbuff2[3] = *(src + 3);
2809
longbuff2 = *((uint32 *)swapbuff2);
2810
buff3 = ((uint64)longbuff1 << 32) | longbuff2;
2811
buff1 = (buff3 & matchbits) << (src_bit);
2813
/* If we have a full buffer's worth, write it out */
2814
if (ready_bits >= 32)
2816
bytebuff1 = (buff2 >> 56);
2818
bytebuff2 = (buff2 >> 48);
2820
bytebuff3 = (buff2 >> 40);
2822
bytebuff4 = (buff2 >> 32);
2826
/* shift in new bits */
2827
buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
2830
{ /* add another bps bits to the buffer */
2831
bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
2832
buff2 = (buff2 | (buff1 >> ready_bits));
2837
while (ready_bits > 0)
2839
bytebuff1 = (buff2 >> 56);
2841
buff2 = (buff2 << 8);
2846
} /* end extractContigSamples32bits */
2849
extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
2850
tsample_t sample, uint16 spp, uint16 bps,
2851
tsample_t count, uint32 start, uint32 end,
2854
int ready_bits = 0, sindex = 0;
2855
uint32 col, src_byte, src_bit, bit_offset;
2856
uint8 maskbits = 0, matchbits = 0;
2857
uint8 buff1 = 0, buff2 = 0;
2861
if ((src == NULL) || (dst == NULL))
2863
TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
2867
if ((start > end) || (start > cols))
2869
TIFFError ("extractContigSamplesShifted8bits",
2870
"Invalid start column value %d ignored", start);
2873
if ((end == 0) || (end > cols))
2875
TIFFError ("extractContigSamplesShifted8bits",
2876
"Invalid end column value %d ignored", end);
2881
maskbits = (uint8)-1 >> ( 8 - bps);
2883
for (col = start; col < end; col++)
2884
{ /* Compute src byte(s) and bits within byte(s) */
2885
bit_offset = col * bps * spp;
2886
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2890
src_byte = bit_offset / 8;
2891
src_bit = bit_offset % 8;
2895
src_byte = (bit_offset + (sindex * bps)) / 8;
2896
src_bit = (bit_offset + (sindex * bps)) % 8;
2899
src = in + src_byte;
2900
matchbits = maskbits << (8 - src_bit - bps);
2901
buff1 = ((*src) & matchbits) << (src_bit);
2902
if ((col == start) && (sindex == sample))
2903
buff2 = *src & ((uint8)-1) << (shift);
2905
/* If we have a full buffer's worth, write it out */
2906
if (ready_bits >= 8)
2913
buff2 = buff2 | (buff1 >> ready_bits);
2918
while (ready_bits > 0)
2920
buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
2926
} /* end extractContigSamplesShifted8bits */
2929
extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols,
2930
tsample_t sample, uint16 spp, uint16 bps,
2931
tsample_t count, uint32 start, uint32 end,
2934
int ready_bits = 0, sindex = 0;
2935
uint32 col, src_byte, src_bit, bit_offset;
2936
uint16 maskbits = 0, matchbits = 0;
2937
uint16 buff1 = 0, buff2 = 0;
2941
unsigned char swapbuff[2];
2943
if ((src == NULL) || (dst == NULL))
2945
TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
2949
if ((start > end) || (start > cols))
2951
TIFFError ("extractContigSamplesShifted16bits",
2952
"Invalid start column value %d ignored", start);
2955
if ((end == 0) || (end > cols))
2957
TIFFError ("extractContigSamplesShifted16bits",
2958
"Invalid end column value %d ignored", end);
2963
maskbits = (uint16)-1 >> (16 - bps);
2964
for (col = start; col < end; col++)
2965
{ /* Compute src byte(s) and bits within byte(s) */
2966
bit_offset = col * bps * spp;
2967
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
2971
src_byte = bit_offset / 8;
2972
src_bit = bit_offset % 8;
2976
src_byte = (bit_offset + (sindex * bps)) / 8;
2977
src_bit = (bit_offset + (sindex * bps)) % 8;
2980
src = in + src_byte;
2981
matchbits = maskbits << (16 - src_bit - bps);
2985
swapbuff[0] = *(src + 1);
2990
swapbuff[1] = *(src + 1);
2993
buff1 = *((uint16 *)swapbuff);
2994
if ((col == start) && (sindex == sample))
2995
buff2 = buff1 & ((uint16)-1) << (8 - shift);
2997
buff1 = (buff1 & matchbits) << (src_bit);
2999
if (ready_bits < 8) /* add another bps bits to the buffer */
3000
buff2 = buff2 | (buff1 >> ready_bits);
3001
else /* If we have a full buffer's worth, write it out */
3003
bytebuff = (buff2 >> 8);
3006
/* shift in new bits */
3007
buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3014
/* catch any trailing bits at the end of the line */
3015
while (ready_bits > 0)
3017
bytebuff = (buff2 >> 8);
3023
} /* end extractContigSamplesShifted16bits */
3027
extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
3028
tsample_t sample, uint16 spp, uint16 bps,
3029
tsample_t count, uint32 start, uint32 end,
3032
int ready_bits = 0, sindex = 0;
3033
uint32 col, src_byte, src_bit, bit_offset;
3034
uint32 maskbits = 0, matchbits = 0;
3035
uint32 buff1 = 0, buff2 = 0;
3036
uint8 bytebuff1 = 0, bytebuff2 = 0;
3039
unsigned char swapbuff[4];
3041
if ((in == NULL) || (out == NULL))
3043
TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
3047
if ((start > end) || (start > cols))
3049
TIFFError ("extractContigSamplesShifted24bits",
3050
"Invalid start column value %d ignored", start);
3053
if ((end == 0) || (end > cols))
3055
TIFFError ("extractContigSamplesShifted24bits",
3056
"Invalid end column value %d ignored", end);
3061
maskbits = (uint32)-1 >> ( 32 - bps);
3062
for (col = start; col < end; col++)
3064
/* Compute src byte(s) and bits within byte(s) */
3065
bit_offset = col * bps * spp;
3066
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3070
src_byte = bit_offset / 8;
3071
src_bit = bit_offset % 8;
3075
src_byte = (bit_offset + (sindex * bps)) / 8;
3076
src_bit = (bit_offset + (sindex * bps)) % 8;
3079
src = in + src_byte;
3080
matchbits = maskbits << (32 - src_bit - bps);
3084
swapbuff[2] = *(src + 1);
3085
swapbuff[1] = *(src + 2);
3086
swapbuff[0] = *(src + 3);
3091
swapbuff[1] = *(src + 1);
3092
swapbuff[2] = *(src + 2);
3093
swapbuff[3] = *(src + 3);
3096
buff1 = *((uint32 *)swapbuff);
3097
if ((col == start) && (sindex == sample))
3098
buff2 = buff1 & ((uint32)-1) << (16 - shift);
3100
buff1 = (buff1 & matchbits) << (src_bit);
3102
if (ready_bits < 16) /* add another bps bits to the buffer */
3104
bytebuff1 = bytebuff2 = 0;
3105
buff2 = (buff2 | (buff1 >> ready_bits));
3107
else /* If we have a full buffer's worth, write it out */
3109
bytebuff1 = (buff2 >> 24);
3111
bytebuff2 = (buff2 >> 16);
3115
/* shift in new bits */
3116
buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3122
/* catch any trailing bits at the end of the line */
3123
while (ready_bits > 0)
3125
bytebuff1 = (buff2 >> 24);
3128
buff2 = (buff2 << 8);
3129
bytebuff2 = bytebuff1;
3134
} /* end extractContigSamplesShifted24bits */
3137
extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
3138
tsample_t sample, uint16 spp, uint16 bps,
3139
tsample_t count, uint32 start, uint32 end,
3142
int ready_bits = 0, sindex = 0, shift_width = 0;
3143
uint32 col, src_byte, src_bit, bit_offset;
3144
uint32 longbuff1 = 0, longbuff2 = 0;
3145
uint64 maskbits = 0, matchbits = 0;
3146
uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3147
uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3150
unsigned char swapbuff1[4];
3151
unsigned char swapbuff2[4];
3153
if ((in == NULL) || (out == NULL))
3155
TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
3160
if ((start > end) || (start > cols))
3162
TIFFError ("extractContigSamplesShifted32bits",
3163
"Invalid start column value %d ignored", start);
3166
if ((end == 0) || (end > cols))
3168
TIFFError ("extractContigSamplesShifted32bits",
3169
"Invalid end column value %d ignored", end);
3173
shift_width = ((bps + 7) / 8) + 1;
3175
maskbits = (uint64)-1 >> ( 64 - bps);
3176
for (col = start; col < end; col++)
3178
/* Compute src byte(s) and bits within byte(s) */
3179
bit_offset = col * bps * spp;
3180
for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
3184
src_byte = bit_offset / 8;
3185
src_bit = bit_offset % 8;
3189
src_byte = (bit_offset + (sindex * bps)) / 8;
3190
src_bit = (bit_offset + (sindex * bps)) % 8;
3193
src = in + src_byte;
3194
matchbits = maskbits << (64 - src_bit - bps);
3197
swapbuff1[3] = *src;
3198
swapbuff1[2] = *(src + 1);
3199
swapbuff1[1] = *(src + 2);
3200
swapbuff1[0] = *(src + 3);
3204
swapbuff1[0] = *src;
3205
swapbuff1[1] = *(src + 1);
3206
swapbuff1[2] = *(src + 2);
3207
swapbuff1[3] = *(src + 3);
3209
longbuff1 = *((uint32 *)swapbuff1);
3211
memset (swapbuff2, '\0', sizeof(swapbuff2));
3214
swapbuff2[3] = *src;
3215
swapbuff2[2] = *(src + 1);
3216
swapbuff2[1] = *(src + 2);
3217
swapbuff2[0] = *(src + 3);
3221
swapbuff2[0] = *src;
3222
swapbuff2[1] = *(src + 1);
3223
swapbuff2[2] = *(src + 2);
3224
swapbuff2[3] = *(src + 3);
3227
longbuff2 = *((uint32 *)swapbuff2);
3228
buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3229
if ((col == start) && (sindex == sample))
3230
buff2 = buff3 & ((uint64)-1) << (32 - shift);
3232
buff1 = (buff3 & matchbits) << (src_bit);
3234
if (ready_bits < 32)
3235
{ /* add another bps bits to the buffer */
3236
bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3237
buff2 = (buff2 | (buff1 >> ready_bits));
3239
else /* If we have a full buffer's worth, write it out */
3241
bytebuff1 = (buff2 >> 56);
3243
bytebuff2 = (buff2 >> 48);
3245
bytebuff3 = (buff2 >> 40);
3247
bytebuff4 = (buff2 >> 32);
3251
/* shift in new bits */
3252
buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3257
while (ready_bits > 0)
3259
bytebuff1 = (buff2 >> 56);
3261
buff2 = (buff2 << 8);
3266
} /* end extractContigSamplesShifted32bits */
3270
extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3271
int outskew, int inskew, tsample_t sample,
3272
uint16 spp, uint16 bps, struct dump_opts *dump)
3274
int shift_width, bytes_per_sample, bytes_per_pixel;
3275
uint32 src_rowsize, src_offset, row, first_col = 0;
3276
uint32 dst_rowsize, dst_offset;
3277
tsample_t count = 1;
3280
bytes_per_sample = (bps + 7) / 8;
3281
bytes_per_pixel = ((bps * spp) + 7) / 8;
3286
if (bytes_per_pixel < (bytes_per_sample + 1))
3287
shift_width = bytes_per_pixel;
3289
shift_width = bytes_per_sample + 1;
3291
src_rowsize = ((bps * spp * cols) + 7) / 8;
3292
dst_rowsize = ((bps * cols) + 7) / 8;
3294
if ((dump->outfile != NULL) && (dump->level == 4))
3296
dump_info (dump->outfile, dump->format, "extractContigSamplesToBuffer",
3297
"Sample %d, %d rows", sample + 1, rows + 1);
3299
for (row = 0; row < rows; row++)
3301
src_offset = row * src_rowsize;
3302
dst_offset = row * dst_rowsize;
3303
src = in + src_offset;
3304
dst = out + dst_offset;
3306
/* pack the data into the scanline */
3307
switch (shift_width)
3309
case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
3310
spp, bps, count, first_col, cols))
3313
case 1: if (extractContigSamples8bits (src, dst, cols, sample,
3314
spp, bps, count, first_col, cols))
3317
case 2: if (extractContigSamples16bits (src, dst, cols, sample,
3318
spp, bps, count, first_col, cols))
3321
case 3: if (extractContigSamples24bits (src, dst, cols, sample,
3322
spp, bps, count, first_col, cols))
3326
case 5: if (extractContigSamples32bits (src, dst, cols, sample,
3327
spp, bps, count, first_col, cols))
3330
default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
3333
if ((dump->outfile != NULL) && (dump->level == 4))
3334
dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
3341
} /* end extractContigSamplesToBuffer */
3343
/* This will not work unless bps is a multiple of 8 */
3345
cpSeparateBufToContigBuf(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
3346
int outskew, int inskew, tsample_t spp,
3347
int bytes_per_sample)
3354
int n = bytes_per_sample;
3359
out += (spp-1)*bytes_per_sample;
3364
} /* end of cpSeparateBufToContifBuf */
3366
static int readContigStripsIntoBuffer (TIFF* in, uint8* buf, uint32 imagelength,
3367
uint32 imagewidth, tsample_t spp)
3369
tsize_t scanlinesize = TIFFScanlineSize(in);
3373
(void) imagewidth; (void) spp;
3374
for (row = 0; row < imagelength; row++)
3376
if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
3379
TIFFError(TIFFFileName(in),"Error, can't read scanline %lu",
3380
(unsigned long) row);
3383
bufp += scanlinesize;
3387
} /* end readContigStripsIntoBuffer */
3390
combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 row,
3391
uint32 cols, uint16 spp, uint16 bps,
3392
FILE *dumpfile, int format, int level)
3395
int bytes_per_sample = 0;
3398
uint32 col, src_byte = 0, src_bit = 0;
3399
uint8 maskbits = 0, matchbits = 0;
3400
uint8 buff1 = 0, buff2 = 0;
3402
unsigned char *src = in[0];
3403
unsigned char *dst = out;
3406
if ((src == NULL) || (dst == NULL))
3408
TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
3412
bytes_per_sample = (bps + 7) / 8;
3413
dst_rowsize = ((bps * cols * spp) + 7) / 8;
3414
maskbits = (uint8)-1 >> ( 8 - bps);
3419
for (col = 0; col < cols; col++)
3421
/* Compute src byte(s) and bits within byte(s) */
3422
bit_offset = col * bps;
3423
src_byte = bit_offset / 8;
3424
src_bit = bit_offset % 8;
3426
matchbits = maskbits << (8 - src_bit - bps);
3427
/* load up next sample from each plane */
3428
for (s = 0; s < spp; s++)
3430
src = in[s] + src_byte;
3431
buff1 = ((*src) & matchbits) << (src_bit);
3433
/* If we have a full buffer's worth, write it out */
3434
if (ready_bits >= 8)
3439
strcpy (action, "Flush");
3443
buff2 = (buff2 | (buff1 >> ready_bits));
3444
strcpy (action, "Update");
3448
if ((dumpfile != NULL) && (level == 3))
3450
dump_info (dumpfile, format, "",
3451
"Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3452
row + 1, col + 1, s, src_byte, src_bit, dst - out);
3453
dump_byte (dumpfile, format, "Match bits", matchbits);
3454
dump_byte (dumpfile, format, "Src bits", *src);
3455
dump_byte (dumpfile, format, "Buff1 bits", buff1);
3456
dump_byte (dumpfile, format, "Buff2 bits", buff2);
3457
dump_info (dumpfile, format, "","%s", action);
3464
buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
3466
if ((dumpfile != NULL) && (level == 3))
3468
dump_info (dumpfile, format, "",
3469
"Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3470
row + 1, col + 1, src_byte, src_bit, dst - out);
3471
dump_byte (dumpfile, format, "Final bits", buff1);
3475
if ((dumpfile != NULL) && (level == 2))
3477
dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
3478
dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
3482
} /* end combineSeparateSamples8bits */
3485
combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 row,
3486
uint32 cols, uint16 spp, uint16 bps,
3487
FILE *dumpfile, int format, int level)
3489
int ready_bits = 0, bytes_per_sample = 0;
3492
uint32 col, src_byte = 0, src_bit = 0;
3493
uint16 maskbits = 0, matchbits = 0;
3494
uint16 buff1 = 0, buff2 = 0;
3497
unsigned char *src = in[0];
3498
unsigned char *dst = out;
3499
unsigned char swapbuff[2];
3502
if ((src == NULL) || (dst == NULL))
3504
TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
3508
bytes_per_sample = (bps + 7) / 8;
3509
dst_rowsize = ((bps * cols * spp) + 7) / 8;
3510
maskbits = (uint16)-1 >> (16 - bps);
3514
for (col = 0; col < cols; col++)
3516
/* Compute src byte(s) and bits within byte(s) */
3517
bit_offset = col * bps;
3518
src_byte = bit_offset / 8;
3519
src_bit = bit_offset % 8;
3521
matchbits = maskbits << (16 - src_bit - bps);
3522
for (s = 0; s < spp; s++)
3524
src = in[s] + src_byte;
3528
swapbuff[0] = *(src + 1);
3533
swapbuff[1] = *(src + 1);
3536
buff1 = *((uint16 *)swapbuff);
3537
buff1 = (buff1 & matchbits) << (src_bit);
3539
/* If we have a full buffer's worth, write it out */
3540
if (ready_bits >= 8)
3542
bytebuff = (buff2 >> 8);
3545
/* shift in new bits */
3546
buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
3547
strcpy (action, "Flush");
3550
{ /* add another bps bits to the buffer */
3552
buff2 = (buff2 | (buff1 >> ready_bits));
3553
strcpy (action, "Update");
3557
if ((dumpfile != NULL) && (level == 3))
3559
dump_info (dumpfile, format, "",
3560
"Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3561
row + 1, col + 1, s, src_byte, src_bit, dst - out);
3563
dump_short (dumpfile, format, "Match bits", matchbits);
3564
dump_data (dumpfile, format, "Src bits", src, 2);
3565
dump_short (dumpfile, format, "Buff1 bits", buff1);
3566
dump_short (dumpfile, format, "Buff2 bits", buff2);
3567
dump_byte (dumpfile, format, "Write byte", bytebuff);
3568
dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
3572
/* catch any trailing bits at the end of the line */
3575
bytebuff = (buff2 >> 8);
3577
if ((dumpfile != NULL) && (level == 3))
3579
dump_info (dumpfile, format, "",
3580
"Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3581
row + 1, col + 1, src_byte, src_bit, dst - out);
3582
dump_byte (dumpfile, format, "Final bits", bytebuff);
3586
if ((dumpfile != NULL) && (level == 2))
3588
dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
3589
dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
3593
} /* end combineSeparateSamples16bits */
3596
combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 row,
3597
uint32 cols, uint16 spp, uint16 bps,
3598
FILE *dumpfile, int format, int level)
3600
int ready_bits = 0, bytes_per_sample = 0;
3603
uint32 col, src_byte = 0, src_bit = 0;
3604
uint32 maskbits = 0, matchbits = 0;
3605
uint32 buff1 = 0, buff2 = 0;
3606
uint8 bytebuff1 = 0, bytebuff2 = 0;
3608
unsigned char *src = in[0];
3609
unsigned char *dst = out;
3610
unsigned char swapbuff[4];
3613
if ((src == NULL) || (dst == NULL))
3615
TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
3619
bytes_per_sample = (bps + 7) / 8;
3620
dst_rowsize = ((bps * cols) + 7) / 8;
3621
maskbits = (uint32)-1 >> ( 32 - bps);
3625
for (col = 0; col < cols; col++)
3627
/* Compute src byte(s) and bits within byte(s) */
3628
bit_offset = col * bps;
3629
src_byte = bit_offset / 8;
3630
src_bit = bit_offset % 8;
3632
matchbits = maskbits << (32 - src_bit - bps);
3633
for (s = 0; s < spp; s++)
3635
src = in[s] + src_byte;
3639
swapbuff[2] = *(src + 1);
3640
swapbuff[1] = *(src + 2);
3641
swapbuff[0] = *(src + 3);
3646
swapbuff[1] = *(src + 1);
3647
swapbuff[2] = *(src + 2);
3648
swapbuff[3] = *(src + 3);
3651
buff1 = *((uint32 *)swapbuff);
3652
buff1 = (buff1 & matchbits) << (src_bit);
3654
/* If we have a full buffer's worth, write it out */
3655
if (ready_bits >= 16)
3657
bytebuff1 = (buff2 >> 24);
3659
bytebuff2 = (buff2 >> 16);
3663
/* shift in new bits */
3664
buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
3665
strcpy (action, "Flush");
3668
{ /* add another bps bits to the buffer */
3669
bytebuff1 = bytebuff2 = 0;
3670
buff2 = (buff2 | (buff1 >> ready_bits));
3671
strcpy (action, "Update");
3675
if ((dumpfile != NULL) && (level == 3))
3677
dump_info (dumpfile, format, "",
3678
"Row %3d, Col %3d, Samples %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3679
row + 1, col + 1, s, src_byte, src_bit, dst - out);
3680
dump_long (dumpfile, format, "Match bits ", matchbits);
3681
dump_data (dumpfile, format, "Src bits ", src, 4);
3682
dump_long (dumpfile, format, "Buff1 bits ", buff1);
3683
dump_long (dumpfile, format, "Buff2 bits ", buff2);
3684
dump_byte (dumpfile, format, "Write bits1", bytebuff1);
3685
dump_byte (dumpfile, format, "Write bits2", bytebuff2);
3686
dump_info (dumpfile, format, "","Ready bits: %d, %s", ready_bits, action);
3691
/* catch any trailing bits at the end of the line */
3692
while (ready_bits > 0)
3694
bytebuff1 = (buff2 >> 24);
3697
buff2 = (buff2 << 8);
3698
bytebuff2 = bytebuff1;
3702
if ((dumpfile != NULL) && (level == 3))
3704
dump_info (dumpfile, format, "",
3705
"Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3706
row + 1, col + 1, src_byte, src_bit, dst - out);
3708
dump_long (dumpfile, format, "Match bits ", matchbits);
3709
dump_data (dumpfile, format, "Src bits ", src, 4);
3710
dump_long (dumpfile, format, "Buff1 bits ", buff1);
3711
dump_long (dumpfile, format, "Buff2 bits ", buff2);
3712
dump_byte (dumpfile, format, "Write bits1", bytebuff1);
3713
dump_byte (dumpfile, format, "Write bits2", bytebuff2);
3714
dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
3717
if ((dumpfile != NULL) && (level == 2))
3719
dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
3720
dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
3724
} /* end combineSeparateSamples24bits */
3727
combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 row,
3728
uint32 cols, uint16 spp, uint16 bps,
3729
FILE *dumpfile, int format, int level)
3731
int ready_bits = 0, bytes_per_sample = 0, shift_width = 0;
3734
uint32 src_byte = 0, src_bit = 0;
3736
uint32 longbuff1 = 0, longbuff2 = 0;
3737
uint64 maskbits = 0, matchbits = 0;
3738
uint64 buff1 = 0, buff2 = 0, buff3 = 0;
3739
uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
3741
unsigned char *src = in[0];
3742
unsigned char *dst = out;
3743
unsigned char swapbuff1[4];
3744
unsigned char swapbuff2[4];
3747
if ((src == NULL) || (dst == NULL))
3749
TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
3753
bytes_per_sample = (bps + 7) / 8;
3754
dst_rowsize = ((bps * cols) + 7) / 8;
3755
maskbits = (uint64)-1 >> ( 64 - bps);
3756
shift_width = ((bps + 7) / 8) + 1;
3760
for (col = 0; col < cols; col++)
3762
/* Compute src byte(s) and bits within byte(s) */
3763
bit_offset = col * bps;
3764
src_byte = bit_offset / 8;
3765
src_bit = bit_offset % 8;
3767
matchbits = maskbits << (64 - src_bit - bps);
3768
for (s = 0; s < spp; s++)
3770
src = in[s] + src_byte;
3773
swapbuff1[3] = *src;
3774
swapbuff1[2] = *(src + 1);
3775
swapbuff1[1] = *(src + 2);
3776
swapbuff1[0] = *(src + 3);
3780
swapbuff1[0] = *src;
3781
swapbuff1[1] = *(src + 1);
3782
swapbuff1[2] = *(src + 2);
3783
swapbuff1[3] = *(src + 3);
3785
longbuff1 = *((uint32 *)swapbuff1);
3787
memset (swapbuff2, '\0', sizeof(swapbuff2));
3790
swapbuff2[3] = *src;
3791
swapbuff2[2] = *(src + 1);
3792
swapbuff2[1] = *(src + 2);
3793
swapbuff2[0] = *(src + 3);
3797
swapbuff2[0] = *src;
3798
swapbuff2[1] = *(src + 1);
3799
swapbuff2[2] = *(src + 2);
3800
swapbuff2[3] = *(src + 3);
3803
longbuff2 = *((uint32 *)swapbuff2);
3804
buff3 = ((uint64)longbuff1 << 32) | longbuff2;
3805
buff1 = (buff3 & matchbits) << (src_bit);
3807
/* If we have a full buffer's worth, write it out */
3808
if (ready_bits >= 32)
3810
bytebuff1 = (buff2 >> 56);
3812
bytebuff2 = (buff2 >> 48);
3814
bytebuff3 = (buff2 >> 40);
3816
bytebuff4 = (buff2 >> 32);
3820
/* shift in new bits */
3821
buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
3822
strcpy (action, "Flush");
3825
{ /* add another bps bits to the buffer */
3826
bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
3827
buff2 = (buff2 | (buff1 >> ready_bits));
3828
strcpy (action, "Update");
3832
if ((dumpfile != NULL) && (level == 3))
3834
dump_info (dumpfile, format, "",
3835
"Row %3d, Col %3d, Sample %d, Src byte offset %3d bit offset %2d Dst offset %3d",
3836
row + 1, col + 1, s, src_byte, src_bit, dst - out);
3837
dump_wide (dumpfile, format, "Match bits ", matchbits);
3838
dump_data (dumpfile, format, "Src bits ", src, 8);
3839
dump_wide (dumpfile, format, "Buff1 bits ", buff1);
3840
dump_wide (dumpfile, format, "Buff2 bits ", buff2);
3841
dump_info (dumpfile, format, "", "Ready bits: %d, %s", ready_bits, action);
3845
while (ready_bits > 0)
3847
bytebuff1 = (buff2 >> 56);
3849
buff2 = (buff2 << 8);
3853
if ((dumpfile != NULL) && (level == 3))
3855
dump_info (dumpfile, format, "",
3856
"Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
3857
row + 1, col + 1, src_byte, src_bit, dst - out);
3859
dump_long (dumpfile, format, "Match bits ", matchbits);
3860
dump_data (dumpfile, format, "Src bits ", src, 4);
3861
dump_long (dumpfile, format, "Buff1 bits ", buff1);
3862
dump_long (dumpfile, format, "Buff2 bits ", buff2);
3863
dump_byte (dumpfile, format, "Write bits1", bytebuff1);
3864
dump_byte (dumpfile, format, "Write bits2", bytebuff2);
3865
dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
3868
if ((dumpfile != NULL) && (level == 2))
3870
dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
3871
dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
3875
} /* end combineSeparateSamples32bits */
3878
combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
3879
uint32 row, uint32 width, uint16 spp, uint16 bps,
3880
FILE *dumpfile, int format, int level)
3882
int i, bytes_per_sample, bytes_per_pixel, dst_rowsize, shift_width;
3883
uint32 col, col_offset;
3890
if ((src == NULL) || (dst == NULL))
3892
TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
3896
bytes_per_sample = (bps + 7) / 8;
3897
bytes_per_pixel = ((bps * spp) + 7) / 8;
3898
if (bytes_per_pixel < (bytes_per_sample + 1))
3899
shift_width = bytes_per_sample;
3901
shift_width = bytes_per_pixel;
3903
if ((dumpfile != NULL) && (level == 2))
3905
for (s = 0; s < spp; s++)
3907
dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
3908
dump_buffer(dumpfile, format, 1, width, row, srcbuffs[s]);
3912
dst_rowsize = ((bps * spp * width) + 7) / 8;
3913
for (col = 0; col < width; col++)
3915
col_offset = col * (bps / 8);
3916
for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3918
src = srcbuffs[s] + col_offset;
3919
for (i = 0; i < bytes_per_sample; i++)
3920
*(dst + i) = *(src + i);
3921
src += bytes_per_sample;
3922
dst += bytes_per_sample;
3926
if ((dumpfile != NULL) && (level == 2))
3928
dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
3929
dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
3933
} /* end combineSeparateSamplesBytes */
3935
static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
3936
uint32 width, uint16 spp,
3937
struct dump_opts *dump)
3939
int i, bytes_per_sample, bytes_per_pixel, shift_width;
3941
uint32 row, src_rowsize, dst_rowsize;
3943
tsize_t scanlinesize = TIFFScanlineSize(in);
3944
unsigned char *srcbuffs[MAX_SAMPLES];
3945
unsigned char *buff = NULL;
3946
unsigned char *dst = NULL;
3948
(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
3952
TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
3956
bytes_per_sample = (bps + 7) / 8;
3957
bytes_per_pixel = ((bps * spp) + 7) / 8;
3958
if (bytes_per_pixel < (bytes_per_sample + 1))
3959
shift_width = bytes_per_pixel;
3961
shift_width = bytes_per_sample + 1;
3963
src_rowsize = ((bps * width) + 7) / 8;
3964
dst_rowsize = ((bps * width * spp) + 7) / 8;
3967
if ((dump->infile != NULL) && (dump->level == 3))
3969
dump_info (dump->infile, dump->format, "",
3970
"Image width %d, length %d, Scanline size, %4d bytes",
3971
width, length, scanlinesize);
3972
dump_info (dump->infile, dump->format, "",
3973
"Bits per sample %d, Samples per pixel %d, Shift width %d",
3974
bps, spp, shift_width);
3977
/* allocate scanline buffers for each sample */
3978
for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3981
buff = _TIFFmalloc(src_rowsize);
3984
TIFFError ("readSeparateStripsIntoBuffer",
3985
"Unable to allocate read buffer for sample %d", s);
3986
for (i = 0; i < s; i++)
3987
_TIFFfree (srcbuffs[i]);
3993
/* read and process one scanline from each sample */
3994
for (row = 0; row < length; row++)
3996
for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
3999
/* read one scanline in the current sample color */
4000
if (TIFFReadScanline(in, buff, row, s) < 0
4003
TIFFError(TIFFFileName(in),
4004
"Error, can't read scanline %lu for sample %d",
4005
(unsigned long) row, s + 1);
4006
for (i = 0; i < s; i++)
4007
_TIFFfree (srcbuffs[i]);
4012
/* combine the samples in each scanline */
4013
dst = obuf + (row * dst_rowsize);
4016
if (combineSeparateSamplesBytes (srcbuffs, dst, row, width,
4017
spp, bps, dump->infile,
4018
dump->format, dump->level))
4020
for (i = 0; i < spp; i++)
4021
_TIFFfree (srcbuffs[i]);
4027
switch (shift_width)
4029
case 1: if (combineSeparateSamples8bits (srcbuffs, dst, row, width,
4030
spp, bps, dump->infile,
4031
dump->format, dump->level))
4033
for (i = 0; i < spp; i++)
4034
_TIFFfree (srcbuffs[i]);
4038
case 2: if (combineSeparateSamples16bits (srcbuffs, dst, row, width,
4039
spp, bps, dump->infile,
4040
dump->format, dump->level))
4042
for (i = 0; i < spp; i++)
4043
_TIFFfree (srcbuffs[i]);
4047
case 3: if (combineSeparateSamples24bits (srcbuffs, dst, row, width,
4048
spp, bps, dump->infile,
4049
dump->format, dump->level))
4051
for (i = 0; i < spp; i++)
4052
_TIFFfree (srcbuffs[i]);
4061
case 8: if (combineSeparateSamples32bits (srcbuffs, dst, row, width,
4062
spp, bps, dump->infile,
4063
dump->format, dump->level))
4065
for (i = 0; i < spp; i++)
4066
_TIFFfree (srcbuffs[i]);
4070
default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
4071
for (i = 0; i < spp; i++)
4072
_TIFFfree (srcbuffs[i]);
4078
/* free any buffers allocated for each plane or scanline and
4079
* any temporary buffers
4081
for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
4089
} /* end readSeparateStripsIntoBuffer */
4092
get_page_geometry (char *name, struct pagedef *page)
4097
for (ptr = name; *ptr; ptr++)
4098
*ptr = (char)tolower((int)*ptr);
4100
for (n = 0; n < MAX_PAPERNAMES; n++)
4102
if (strcmp(name, PaperTable[n].name) == 0)
4104
page->width = PaperTable[n].width;
4105
page->length = PaperTable[n].length;
4106
strncpy (page->name, PaperTable[n].name, 15);
4107
page->name[15] = '\0';
4117
initPageSetup (struct pagedef *page, struct pageseg *pagelist,
4118
struct buffinfo seg_buffs[])
4122
strcpy (page->name, "");
4123
page->mode = PAGE_MODE_NONE;
4124
page->res_unit = RESUNIT_NONE;
4129
page->hmargin = 0.0;
4130
page->vmargin = 0.0;
4133
page->orient = ORIENTATION_NONE;
4135
for (i = 0; i < MAX_SECTIONS; i++)
4137
pagelist[i].x1 = (uint32)0;
4138
pagelist[i].x2 = (uint32)0;
4139
pagelist[i].y1 = (uint32)0;
4140
pagelist[i].y2 = (uint32)0;
4141
pagelist[i].buffsize = (uint32)0;
4142
pagelist[i].position = 0;
4143
pagelist[i].total = 0;
4146
for (i = 0; i < MAX_OUTBUFFS; i++)
4148
seg_buffs[i].size = 0;
4149
seg_buffs[i].buffer = NULL;
4154
initImageData (struct image_data *image)
4160
image->res_unit = RESUNIT_NONE;
4164
image->photometric = 0;
4165
image->orientation = 0;
4166
image->adjustments = 0;
4170
initCropMasks (struct crop_mask *cps)
4174
cps->crop_mode = CROP_NONE;
4175
cps->res_unit = RESUNIT_NONE;
4176
cps->edge_ref = EDGE_TOP;
4179
for (i = 0; i < 4; i++)
4180
cps->margins[i] = 0.0;
4181
cps->bufftotal = (uint32)0;
4182
cps->combined_width = (uint32)0;
4183
cps->combined_length = (uint32)0;
4184
cps->rotation = (uint16)0;
4185
cps->photometric = INVERT_DATA_AND_TAG;
4186
cps->mirror = (uint16)0;
4187
cps->invert = (uint16)0;
4188
cps->zones = (uint32)0;
4189
cps->regions = (uint32)0;
4190
for (i = 0; i < MAX_REGIONS; i++)
4192
cps->corners[i].X1 = 0.0;
4193
cps->corners[i].X2 = 0.0;
4194
cps->corners[i].Y1 = 0.0;
4195
cps->corners[i].Y2 = 0.0;
4196
cps->regionlist[i].x1 = 0;
4197
cps->regionlist[i].x2 = 0;
4198
cps->regionlist[i].y1 = 0;
4199
cps->regionlist[i].y2 = 0;
4200
cps->regionlist[i].width = 0;
4201
cps->regionlist[i].length = 0;
4202
cps->regionlist[i].buffsize = 0;
4203
cps->regionlist[i].buffptr = NULL;
4204
cps->zonelist[i].position = 0;
4205
cps->zonelist[i].total = 0;
4207
cps->exp_mode = ONE_FILE_COMPOSITE;
4208
cps->img_mode = COMPOSITE_IMAGES;
4211
static void initDumpOptions(struct dump_opts *dump)
4214
dump->format = DUMP_NONE;
4216
sprintf (dump->mode, "w");
4217
memset (dump->infilename, '\0', PATH_MAX + 1);
4218
memset (dump->outfilename, '\0',PATH_MAX + 1);
4219
dump->infile = NULL;
4220
dump->outfile = NULL;
4223
/* Compute pixel offsets into the image for margins and fixed regions */
4225
computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
4230
/* Values for these offsets are in pixels from start of image, not bytes,
4231
* and are indexed from zero to width - 1 or length - 1 */
4232
uint32 tmargin, bmargin, lmargin, rmargin;
4233
uint32 startx, endx; /* offsets of first and last columns to extract */
4234
uint32 starty, endy; /* offsets of first and last row to extract */
4235
uint32 width, length, crop_width, crop_length;
4236
uint32 i, max_width, max_length, zwidth, zlength, buffsize;
4237
uint32 x1, x2, y1, y2;
4239
if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
4246
if (((image->xres == 0) || (image->yres == 0)) &&
4247
((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
4248
(crop->crop_mode & CROP_LENGTH) || (crop->crop_mode & CROP_WIDTH)))
4250
TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
4251
TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
4258
/* Translate user units to image units */
4260
switch (crop->res_unit) {
4261
case RESUNIT_CENTIMETER:
4262
if (image->res_unit == RESUNIT_INCH)
4266
if (image->res_unit == RESUNIT_CENTIMETER)
4269
case RESUNIT_NONE: /* Dimensions in pixels */
4274
if (crop->crop_mode & CROP_REGIONS)
4276
max_width = max_length = 0;
4277
for (i = 0; i < crop->regions; i++)
4279
if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
4281
x1 = (uint32) (crop->corners[i].X1 * scale * xres);
4282
x2 = (uint32) (crop->corners[i].X2 * scale * xres);
4283
y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
4284
y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
4288
x1 = (uint32) (crop->corners[i].X1);
4289
x2 = (uint32) (crop->corners[i].X2);
4290
y1 = (uint32) (crop->corners[i].Y1);
4291
y2 = (uint32) (crop->corners[i].Y2);
4294
crop->regionlist[i].x1 = 0;
4296
crop->regionlist[i].x1 = (uint32) (x1 - 1);
4298
if (x2 > image->width - 1)
4299
crop->regionlist[i].x2 = image->width - 1;
4301
crop->regionlist[i].x2 = (uint32) (x2 - 1);
4302
zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
4305
crop->regionlist[i].y1 = 0;
4307
crop->regionlist[i].y1 = (uint32) (y1 - 1);
4309
if (y2 > image->length - 1)
4310
crop->regionlist[i].y2 = image->length - 1;
4312
crop->regionlist[i].y2 = (uint32) (y2 - 1);
4314
zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
4316
if (zwidth > max_width)
4318
if (zlength > max_length)
4319
max_length = zlength;
4322
(((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
4326
(((zwidth * image->bps + 7 ) / 8) * image->spp * (zlength + 1));
4328
crop->regionlist[i].buffsize = buffsize;
4329
crop->bufftotal += buffsize;
4330
if (crop->img_mode == COMPOSITE_IMAGES)
4332
switch (crop->edge_ref)
4336
crop->combined_length = zlength;
4337
crop->combined_width += zwidth;
4340
case EDGE_TOP: /* width from left, length from top */
4342
crop->combined_width = zwidth;
4343
crop->combined_length += zlength;
4351
/* Convert crop margins into offsets into image
4352
* Margins are expressed as pixel rows and columns, not bytes
4354
if (crop->crop_mode & CROP_MARGINS)
4356
if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
4357
{ /* User has specified pixels as reference unit */
4358
tmargin = (uint32)(crop->margins[0]);
4359
lmargin = (uint32)(crop->margins[1]);
4360
bmargin = (uint32)(crop->margins[2]);
4361
rmargin = (uint32)(crop->margins[3]);
4364
{ /* inches or centimeters specified */
4365
tmargin = (uint32)(crop->margins[0] * scale * yres);
4366
lmargin = (uint32)(crop->margins[1] * scale * xres);
4367
bmargin = (uint32)(crop->margins[2] * scale * yres);
4368
rmargin = (uint32)(crop->margins[3] * scale * xres);
4371
if ((lmargin + rmargin) > image->width)
4373
TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
4374
lmargin = (uint32) 0;
4375
rmargin = (uint32) 0;
4378
if ((tmargin + bmargin) > image->length)
4380
TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length");
4381
tmargin = (uint32) 0;
4382
bmargin = (uint32) 0;
4387
{ /* no margins requested */
4388
tmargin = (uint32) 0;
4389
lmargin = (uint32) 0;
4390
bmargin = (uint32) 0;
4391
rmargin = (uint32) 0;
4394
/* Width, height, and margins are expressed as pixel offsets into image */
4395
if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
4397
if (crop->crop_mode & CROP_WIDTH)
4398
width = (uint32)crop->width;
4400
width = image->width - lmargin - rmargin;
4402
if (crop->crop_mode & CROP_LENGTH)
4403
length = (uint32)crop->length;
4405
length = image->length - tmargin - bmargin;
4409
if (crop->crop_mode & CROP_WIDTH)
4410
width = (uint32)(crop->width * scale * image->xres);
4412
width = image->width - lmargin - rmargin;
4414
if (crop->crop_mode & CROP_LENGTH)
4415
length = (uint32)(crop->length * scale * image->yres);
4417
length = image->length - tmargin - bmargin;
4420
off->tmargin = tmargin;
4421
off->bmargin = bmargin;
4422
off->lmargin = lmargin;
4423
off->rmargin = rmargin;
4425
/* Calculate regions defined by margins, width, and length.
4426
* Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
4427
* since they are used to compute offsets into buffers */
4428
switch (crop->edge_ref) {
4431
if ((startx + width) >= (image->width - rmargin))
4432
endx = image->width - rmargin - 1;
4434
endx = startx + width - 1;
4436
endy = image->length - bmargin - 1;
4437
if ((endy - length) <= tmargin)
4440
starty = endy - length + 1;
4443
endx = image->width - rmargin - 1;
4444
if ((endx - width) <= lmargin)
4447
startx = endx - width + 1;
4450
if ((starty + length) >= (image->length - bmargin))
4451
endy = image->length - bmargin - 1;
4453
endy = starty + length - 1;
4455
case EDGE_TOP: /* width from left, length from top */
4459
if ((startx + width) >= (image->width - rmargin))
4460
endx = image->width - rmargin - 1;
4462
endx = startx + width - 1;
4465
if ((starty + length) >= (image->length - bmargin))
4466
endy = image->length - bmargin - 1;
4468
endy = starty + length - 1;
4471
off->startx = startx;
4472
off->starty = starty;
4476
crop_width = endx - startx + 1;
4477
crop_length = endy - starty + 1;
4479
if (crop_width <= 0)
4481
TIFFError("computeInputPixelOffsets",
4482
"Invalid left/right margins and /or image crop width requested");
4485
if (crop_width > image->width)
4486
crop_width = image->width;
4488
if (crop_length <= 0)
4490
TIFFError("computeInputPixelOffsets",
4491
"Invalid top/bottom margins and /or image crop length requested");
4494
if (crop_length > image->length)
4495
crop_length = image->length;
4497
off->crop_width = crop_width;
4498
off->crop_length = crop_length;
4501
} /* end computeInputPixelOffsets */
4504
* Translate crop options into pixel offsets for one or more regions of the image.
4505
* Options are applied in this order: margins, specific width and length, zones,
4506
* but all are optional. Margins are relative to each edge. Width, length and
4507
* zones are relative to the specified reference edge. Zones are expressed as
4508
* X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
4509
* 2:3 would indicate the middle third of the region qualified by margins and
4510
* any explicit width and length specified. Regions are specified by coordinates
4511
* of the top left and lower right corners with range 1 to width or height.
4515
getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
4517
struct offset offsets;
4520
uint32 test, seg, total, need_buff = 0;
4522
uint32 zwidth, zlength;
4524
memset(&offsets, '\0', sizeof(struct offset));
4525
crop->bufftotal = 0;
4526
crop->combined_width = (uint32)0;
4527
crop->combined_length = (uint32)0;
4528
crop->selections = 0;
4530
/* Compute pixel offsets if margins or fixed width or length specified */
4531
if ((crop->crop_mode & CROP_MARGINS) ||
4532
(crop->crop_mode & CROP_REGIONS) ||
4533
(crop->crop_mode & CROP_LENGTH) ||
4534
(crop->crop_mode & CROP_WIDTH))
4536
if (computeInputPixelOffsets(crop, image, &offsets))
4538
TIFFError ("getCropOffsets", "Unable to compute crop margins");
4542
crop->selections = crop->regions;
4543
/* Regions are only calculated from top and left edges with no margins */
4544
if (crop->crop_mode & CROP_REGIONS)
4548
{ /* cropped area is the full image */
4549
offsets.tmargin = 0;
4550
offsets.lmargin = 0;
4551
offsets.bmargin = 0;
4552
offsets.rmargin = 0;
4553
offsets.crop_width = image->width;
4554
offsets.crop_length = image->length;
4556
offsets.endx = image->width - 1;
4558
offsets.endy = image->length - 1;
4562
if (dump->outfile != NULL)
4564
dump_info (dump->outfile, dump->format, "", "Margins: Top: %d Left: %d Bottom: %d Right: %d",
4565
offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin);
4566
dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width: %6d Length: %6d",
4567
offsets.crop_width, offsets.crop_length);
4570
if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
4572
if (need_buff == FALSE) /* No margins or fixed width or length areas */
4574
crop->selections = 0;
4575
crop->combined_width = image->width;
4576
crop->combined_length = image->length;
4581
/* Use one region for margins and fixed width or length areas
4582
* even though it was not formally declared as a region.
4584
crop->selections = 1;
4586
crop->zonelist[0].total = 1;
4587
crop->zonelist[0].position = 1;
4591
crop->selections = crop->zones;
4593
for (i = 0; i < crop->zones; i++)
4595
seg = crop->zonelist[i].position;
4596
total = crop->zonelist[i].total;
4598
switch (crop->edge_ref)
4600
case EDGE_LEFT: /* zones from left to right, length from top */
4601
zlength = offsets.crop_length;
4602
crop->regionlist[i].y1 = offsets.starty;
4603
crop->regionlist[i].y2 = offsets.endy;
4605
crop->regionlist[i].x1 = offsets.startx +
4606
(uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
4607
test = offsets.startx +
4608
(uint32)(offsets.crop_width * 1.0 * seg / total);
4609
if (test > image->width - 1)
4610
crop->regionlist[i].x2 = image->width - 1;
4612
crop->regionlist[i].x2 = test - 1;
4613
zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
4615
/* This is passed to extractCropZone or extractCompositeZones */
4616
crop->combined_length = (uint32)zlength;
4617
if (crop->exp_mode == COMPOSITE_IMAGES)
4618
crop->combined_width += (uint32)zwidth;
4620
crop->combined_width = (uint32)zwidth;
4622
case EDGE_BOTTOM: /* width from left, zones from bottom to top */
4623
zwidth = offsets.crop_width;
4624
crop->regionlist[i].x1 = offsets.startx;
4625
crop->regionlist[i].x2 = offsets.endx;
4627
test2 = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
4629
crop->regionlist[i].y1 = 0;
4631
crop->regionlist[i].y1 = test2 + 1;
4633
test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
4634
if (test > (image->length - 1))
4635
crop->regionlist[i].y2 = image->length - 1;
4637
crop->regionlist[i].y2 = test;
4638
zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
4640
/* This is passed to extractCropZone or extractCompositeZones */
4641
if (crop->exp_mode == COMPOSITE_IMAGES)
4642
crop->combined_length += (uint32)zlength;
4644
crop->combined_length = (uint32)zlength;
4645
crop->combined_width = (uint32)zwidth;
4647
case EDGE_RIGHT: /* zones from right to left, length from top */
4648
zlength = offsets.crop_length;
4649
crop->regionlist[i].y1 = offsets.starty;
4650
crop->regionlist[i].y2 = offsets.endy;
4652
crop->regionlist[i].x1 = offsets.startx +
4653
(uint32)(offsets.crop_width * (total - seg) * 1.0 / total);
4654
test = offsets.startx +
4655
(uint32)(offsets.crop_width * (total - seg + 1) * 1.0 / total);
4657
if (test > image->width - 1)
4658
crop->regionlist[i].x2 = image->width - 1;
4660
crop->regionlist[i].x2 = test - 1;
4661
zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
4663
/* This is passed to extractCropZone or extractCompositeZones */
4664
crop->combined_length = (uint32)zlength;
4665
if (crop->exp_mode == COMPOSITE_IMAGES)
4666
crop->combined_width += (uint32)zwidth;
4668
crop->combined_width = (uint32)zwidth;
4670
case EDGE_TOP: /* width from left, zones from top to bottom */
4672
zwidth = offsets.crop_width;
4673
crop->regionlist[i].x1 = offsets.startx;
4674
crop->regionlist[i].x2 = offsets.endx;
4676
crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
4677
test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
4678
if (test > image->length - 1)
4679
crop->regionlist[i].y2 = image->length - 1;
4681
crop->regionlist[i].y2 = test - 1;
4682
zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
4684
/* This is passed to extractCropZone or extractCompositeZones */
4685
if (crop->exp_mode == COMPOSITE_IMAGES)
4686
crop->combined_length += (uint32)zlength;
4688
crop->combined_length = (uint32)zlength;
4689
crop->combined_width = (uint32)zwidth;
4691
} /* end switch statement */
4694
((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
4695
crop->regionlist[i].width = (uint32) zwidth;
4696
crop->regionlist[i].length = (uint32) zlength;
4697
crop->regionlist[i].buffsize = buffsize;
4698
crop->bufftotal += buffsize;
4701
if (dump->outfile != NULL)
4702
dump_info (dump->outfile, dump->format, "", "Zone %d, width: %4d, length: %4d, x1: %4d x2: %4d y1: %4d y2: %4d",
4703
i + 1, (uint32)zwidth, (uint32)zlength,
4704
crop->regionlist[i].x1, crop->regionlist[i].x2,
4705
crop->regionlist[i].y1, crop->regionlist[i].y2);
4709
} /* end getCropOffsets */
4713
computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
4714
struct pagedef *page, struct pageseg *sections,
4715
struct dump_opts* dump)
4718
uint32 iwidth, ilength; /* Input image width and length */
4719
uint32 owidth, olength; /* Output image width and length */
4720
uint32 pwidth, plength; /* Output page width and length */
4721
uint32 orows, ocols; /* rows and cols for output */
4722
uint32 hmargin, vmargin; /* Horizontal and vertical margins */
4723
uint32 x1, x2, y1, y2, line_bytes;
4724
unsigned int orientation;
4728
if (page->res_unit == RESUNIT_NONE)
4729
page->res_unit = image->res_unit;
4731
switch (image->res_unit) {
4732
case RESUNIT_CENTIMETER:
4733
if (page->res_unit == RESUNIT_INCH)
4737
if (page->res_unit == RESUNIT_CENTIMETER)
4740
case RESUNIT_NONE: /* Dimensions in pixels */
4745
/* get width, height, resolutions of input image selection */
4746
if (crop->combined_width > 0)
4747
iwidth = crop->combined_width;
4749
iwidth = image->width;
4750
if (crop->combined_length > 0)
4751
ilength = crop->combined_length;
4753
ilength = image->length;
4755
if (page->hres <= 1.0)
4756
page->hres = image->xres;
4757
if (page->vres <= 1.0)
4758
page->vres = image->yres;
4760
if ((page->hres < 1.0) || (page->vres < 1.0))
4762
TIFFError("computeOutputPixelOffsets",
4763
"Invalid horizontal or vertical resolution specified or read from input image");
4767
/* If no page sizes are being specified, we just use the input image size to
4768
* calculate maximum margins that can be taken from image.
4770
if (page->width <= 0)
4773
pwidth = page->width;
4775
if (page->length <= 0)
4778
plength = page->length;
4782
TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
4783
"Hmargin: %3.2f, Vmargin: %3.2f\n",
4784
page->name, page->vres, page->hres,
4785
page->hmargin, page->vmargin);
4786
TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %d, length: %d\n",
4787
page->res_unit, scale, pwidth, plength);
4790
/* compute margins at specified unit and resolution */
4791
if (page->mode & PAGE_MODE_MARGINS)
4793
if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
4794
{ /* inches or centimeters specified */
4795
hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
4796
vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
4799
{ /* Otherwise user has specified pixels as reference unit */
4800
hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
4801
vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
4804
if ((hmargin * 2.0) > (pwidth * page->hres))
4806
TIFFError("computeOutputPixelOffsets",
4807
"Combined left and right margins exceed page width");
4808
hmargin = (uint32) 0;
4811
if ((vmargin * 2.0) > (plength * page->vres))
4813
TIFFError("computeOutputPixelOffsets",
4814
"Combined top and bottom margins exceed page length");
4815
vmargin = (uint32) 0;
4825
if (page->mode & PAGE_MODE_ROWSCOLS )
4827
/* Maybe someday but not for now */
4828
if (page->mode & PAGE_MODE_MARGINS)
4829
TIFFError("computeOutputPixelOffsets",
4830
"Output margins cannot be specified with rows and columns");
4832
owidth = TIFFhowmany(iwidth, page->cols);
4833
olength = TIFFhowmany(ilength, page->rows);
4837
if (page->mode & PAGE_MODE_PAPERSIZE )
4839
owidth = (uint32)((pwidth * page->hres) - (hmargin * 2));
4840
olength = (uint32)((plength * page->vres) - (vmargin * 2));
4844
owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
4845
olength = (uint32)(ilength - (vmargin * 2 * page->vres));
4849
if (owidth > iwidth)
4851
if (olength > ilength)
4854
/* Compute the number of pages required for Portrait or Landscape */
4855
switch (page->orient)
4857
case ORIENTATION_NONE:
4858
case ORIENTATION_PORTRAIT:
4859
ocols = TIFFhowmany(iwidth, owidth);
4860
orows = TIFFhowmany(ilength, olength);
4861
orientation = ORIENTATION_PORTRAIT;
4864
case ORIENTATION_LANDSCAPE:
4865
ocols = TIFFhowmany(iwidth, olength);
4866
orows = TIFFhowmany(ilength, owidth);
4870
orientation = ORIENTATION_LANDSCAPE;
4873
case ORIENTATION_AUTO:
4875
x1 = TIFFhowmany(iwidth, owidth);
4876
x2 = TIFFhowmany(ilength, olength);
4877
y1 = TIFFhowmany(iwidth, olength);
4878
y2 = TIFFhowmany(ilength, owidth);
4880
if ( (x1 * x2) < (y1 * y2))
4884
orientation = ORIENTATION_PORTRAIT;
4893
orientation = ORIENTATION_LANDSCAPE;
4902
/* If user did not specify rows and cols, set them from calcuation */
4908
line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
4910
if ((page->rows * page->cols) > MAX_SECTIONS)
4912
TIFFError("computeOutputPixelOffsets",
4913
"Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
4917
/* build the list of offsets for each output section */
4918
for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
4920
y1 = (uint32)(olength * i);
4921
y2 = (uint32)(olength * (i + 1) - 1);
4924
for (j = 0; j < ocols; j++, k++)
4926
x1 = (uint32)(owidth * j);
4927
x2 = (uint32)(owidth * (j + 1) - 1);
4930
sections[k].x1 = x1;
4931
sections[k].x2 = x2;
4932
sections[k].y1 = y1;
4933
sections[k].y2 = y2;
4934
sections[k].buffsize = line_bytes * olength;
4935
sections[k].position = k + 1;
4936
sections[k].total = orows * ocols;
4940
} /* end computeOutputPixelOffsets */
4943
loadImage(TIFF* in, struct image_data *image, struct dump_opts * dump, unsigned char **read_ptr)
4947
uint16 nstrips, ntiles, planar, bps, spp, res_unit, photometric, orientation;
4948
uint32 width, length, rowsperstrip;
4949
uint32 stsize, tlsize, buffsize, scanlinesize;
4950
unsigned char *read_buff = NULL;
4951
unsigned char *new_buff = NULL;
4953
static uint32 prev_readsize = 0;
4955
TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
4956
TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
4957
TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
4958
TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
4959
TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric);
4960
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
4961
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length);
4962
TIFFGetField(in, TIFFTAG_XRESOLUTION, &xres);
4963
TIFFGetField(in, TIFFTAG_YRESOLUTION, &yres);
4964
TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit);
4965
scanlinesize = TIFFScanlineSize(in);
4969
image->planar = planar;
4970
image->width = width;
4971
image->length = length;
4974
image->res_unit = res_unit;
4975
image->photometric = photometric;
4976
image->orientation = orientation;
4977
switch (orientation)
4980
case ORIENTATION_TOPLEFT:
4981
image->adjustments = 0;
4983
case ORIENTATION_TOPRIGHT:
4984
image->adjustments = MIRROR_HORIZ;
4986
case ORIENTATION_BOTRIGHT:
4987
image->adjustments = ROTATECW_180;
4989
case ORIENTATION_BOTLEFT:
4990
image->adjustments = MIRROR_VERT;
4992
case ORIENTATION_LEFTTOP:
4993
image->adjustments = MIRROR_VERT | ROTATECW_90;
4995
case ORIENTATION_RIGHTTOP:
4996
image->adjustments = ROTATECW_90;
4998
case ORIENTATION_RIGHTBOT:
4999
image->adjustments = MIRROR_VERT | ROTATECW_270;
5001
case ORIENTATION_LEFTBOT:
5002
image->adjustments = ROTATECW_270;
5005
image->adjustments = 0;
5006
image->orientation = ORIENTATION_TOPLEFT;
5009
if ((bps == 0) || (spp == 0))
5011
TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
5016
if (TIFFIsTiled(in))
5019
tlsize = TIFFTileSize(in);
5020
ntiles = TIFFNumberOfTiles(in);
5021
buffsize = tlsize * ntiles;
5022
if (dump->infile != NULL)
5023
dump_info (dump->infile, dump->format, "",
5024
"Tilesize: %u, Number of Tiles: %u, Scanline size: %u",
5025
tlsize, ntiles, scanlinesize);
5030
TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
5031
stsize = TIFFStripSize(in);
5032
nstrips = TIFFNumberOfStrips(in);
5033
buffsize = stsize * nstrips;
5034
if (dump->infile != NULL)
5035
dump_info (dump->infile, dump->format, "",
5036
"Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
5037
stsize, nstrips, rowsperstrip, scanlinesize);
5040
read_buff = *read_ptr;
5042
read_buff = (unsigned char *)_TIFFmalloc(buffsize);
5045
if (prev_readsize < buffsize)
5047
new_buff = _TIFFrealloc(read_buff, buffsize);
5051
read_buff = (unsigned char *)_TIFFmalloc(buffsize);
5054
read_buff = new_buff;
5060
TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
5063
_TIFFmemset(read_buff, '\0', buffsize);
5064
prev_readsize = buffsize;
5065
*read_ptr = read_buff;
5067
/* N.B. The read functions used copy separate plane data into a buffer as interleaved
5068
* samples rather than separate planes so the same logic works to extract regions
5069
* regardless of the way the data are organized in the input file.
5073
if (planar == PLANARCONFIG_CONTIG)
5075
if (!(readContigStripsIntoBuffer(in, read_buff, length, width, spp)))
5077
TIFFError("loadImage", "Unable to read contiguous strips into buffer");
5083
if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
5085
TIFFError("loadImage", "Unable to read separate strips into buffer");
5092
if (planar == PLANARCONFIG_CONTIG)
5094
if (!(readContigTilesIntoBuffer(in, read_buff, length, width, spp)))
5096
TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
5102
if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, spp)))
5104
TIFFError("loadImage", "Unable to read separate tiles into buffer");
5109
default: TIFFError("loadImage", "Unsupported image file format");
5113
if ((dump->infile != NULL) && (dump->level == 2))
5115
dump_info (dump->infile, dump->format, "loadImage",
5116
"Image width %d, length %d, Raw image data, %4d bytes",
5117
width, length, buffsize);
5118
dump_info (dump->infile, dump->format, "",
5119
"Bits per sample %d, Samples per pixel %d", bps, spp);
5121
for (i = 0; i < length; i++)
5122
dump_buffer(dump->infile, dump->format, 1, scanlinesize,
5123
i, read_buff + (i * scanlinesize));
5126
} /* end loadImage */
5128
static int correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
5130
uint16 mirror, rotation;
5131
unsigned char *work_buff;
5133
work_buff = *work_buff_ptr;
5134
if ((image == NULL) || (work_buff == NULL))
5136
TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
5140
if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
5142
mirror = (uint16)(image->adjustments & MIRROR_BOTH);
5143
if (mirrorImage(image->spp, image->bps, mirror,
5144
image->width, image->length, work_buff))
5146
TIFFError ("correct_orientation", "Unable to mirror image");
5151
if (image->adjustments & ROTATE_ANY)
5153
if (image->adjustments & ROTATECW_90)
5154
rotation = (uint16) 90;
5156
if (image->adjustments & ROTATECW_180)
5157
rotation = (uint16) 180;
5159
if (image->adjustments & ROTATECW_270)
5160
rotation = (uint16) 270;
5163
TIFFError ("correct_orientation", "Invalid rotation value: %d",
5164
image->adjustments & ROTATE_ANY);
5168
if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
5170
TIFFError ("correct_orientation", "Unable to rotate image");
5173
image->orientation = ORIENTATION_TOPLEFT;
5177
} /* end correct_orientation */
5180
/* Extract multiple zones from an image and combine into a single composite image */
5182
extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
5183
unsigned char *read_buff, unsigned char *crop_buff)
5185
int shift_width, bytes_per_sample, bytes_per_pixel;
5186
uint32 i, trailing_bits, prev_trailing_bits;
5187
uint32 row, first_row, last_row, first_col, last_col;
5188
uint32 src_rowsize, dst_rowsize, src_offset, dst_offset;
5189
uint32 crop_width, crop_length, img_width, img_length;
5190
uint32 prev_length, prev_width, composite_width;
5193
tsample_t count, sample = 0; /* Update to extract one or more samples */
5195
img_width = image->width;
5196
img_length = image->length;
5201
bytes_per_sample = (bps + 7) / 8;
5202
bytes_per_pixel = ((bps * spp) + 7) / 8;
5207
if (bytes_per_pixel < (bytes_per_sample + 1))
5208
shift_width = bytes_per_pixel;
5210
shift_width = bytes_per_sample + 1;
5215
/* These are setup for adding additional sections */
5216
prev_width = prev_length = 0;
5217
prev_trailing_bits = trailing_bits = 0;
5218
composite_width = crop->combined_width;
5219
crop->combined_width = 0;
5220
crop->combined_length = 0;
5222
for (i = 0; i < crop->selections; i++)
5224
/* rows, columns, width, length are expressed in pixels */
5225
first_row = crop->regionlist[i].y1;
5226
last_row = crop->regionlist[i].y2;
5227
first_col = crop->regionlist[i].x1;
5228
last_col = crop->regionlist[i].x2;
5230
crop_width = last_col - first_col + 1;
5231
crop_length = last_row - first_row + 1;
5233
/* These should not be needed for composite images */
5234
crop->regionlist[i].width = crop_width;
5235
crop->regionlist[i].length = crop_length;
5236
crop->regionlist[i].buffptr = crop_buff;
5238
src_rowsize = ((img_width * bps * spp) + 7) / 8;
5239
dst_rowsize = (((crop_width * bps * count) + 7) / 8);
5241
switch (crop->edge_ref)
5246
if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
5248
TIFFError ("extractCompositeRegions",
5249
"Only equal width regions can be combined for -E top or bottom");
5253
crop->combined_width = crop_width;
5254
crop->combined_length += crop_length;
5256
for (row = first_row; row <= last_row; row++)
5258
src_offset = row * src_rowsize;
5259
dst_offset = (row - first_row) * dst_rowsize;
5260
src = read_buff + src_offset;
5261
dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
5262
switch (shift_width)
5264
case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
5265
spp, bps, count, first_col,
5268
TIFFError("extractCompositeRegions",
5269
"Unable to extract row %d", row);
5273
case 1: if (extractContigSamplesShifted8bits (src, dst, img_width,
5274
sample, spp, bps, count,
5275
first_col, last_col + 1,
5276
prev_trailing_bits))
5278
TIFFError("extractCompositeRegions",
5279
"Unable to extract row %d", row);
5283
case 2: if (extractContigSamplesShifted16bits (src, dst, img_width,
5284
sample, spp, bps, count,
5285
first_col, last_col + 1,
5286
prev_trailing_bits))
5288
TIFFError("extractCompositeRegions",
5289
"Unable to extract row %d", row);
5293
case 3: if (extractContigSamplesShifted24bits (src, dst, img_width,
5294
sample, spp, bps, count,
5295
first_col, last_col + 1,
5296
prev_trailing_bits))
5298
TIFFError("extractCompositeRegions",
5299
"Unable to extract row %d", row);
5304
case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
5305
sample, spp, bps, count,
5306
first_col, last_col + 1,
5307
prev_trailing_bits))
5309
TIFFError("extractCompositeRegions",
5310
"Unable to extract row %d", row);
5314
default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
5318
prev_length += crop_length;
5320
case EDGE_LEFT: /* splice the pieces of each row together, side by side */
5322
if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
5324
TIFFError ("extractCompositeRegions",
5325
"Only equal length regions can be combined for -E left or right");
5328
crop->combined_width += crop_width;
5329
crop->combined_length = crop_length;
5330
dst_rowsize = (((composite_width * bps * count) + 7) / 8);
5331
trailing_bits = (crop_width * bps * count) % 8;
5332
for (row = first_row; row <= last_row; row++)
5334
src_offset = row * src_rowsize;
5335
dst_offset = (row - first_row) * dst_rowsize;
5336
src = read_buff + src_offset;
5337
dst = crop_buff + dst_offset + prev_width;
5339
switch (shift_width)
5341
case 0: if (extractContigSamplesBytes (src, dst, img_width,
5342
sample, spp, bps, count,
5343
first_col, last_col + 1))
5345
TIFFError("extractCompositeRegions",
5346
"Unable to extract row %d", row);
5350
case 1: if (extractContigSamplesShifted8bits (src, dst, img_width,
5351
sample, spp, bps, count,
5352
first_col, last_col + 1,
5353
prev_trailing_bits))
5355
TIFFError("extractCompositeRegions",
5356
"Unable to extract row %d", row);
5360
case 2: if (extractContigSamplesShifted16bits (src, dst, img_width,
5361
sample, spp, bps, count,
5362
first_col, last_col + 1,
5363
prev_trailing_bits))
5365
TIFFError("extractCompositeRegions",
5366
"Unable to extract row %d", row);
5370
case 3: if (extractContigSamplesShifted24bits (src, dst, img_width,
5371
sample, spp, bps, count,
5372
first_col, last_col + 1,
5373
prev_trailing_bits))
5375
TIFFError("extractCompositeRegions",
5376
"Unable to extract row %d", row);
5381
case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
5382
sample, spp, bps, count,
5383
first_col, last_col + 1,
5384
prev_trailing_bits))
5386
TIFFError("extractCompositeRegions",
5387
"Unable to extract row %d", row);
5391
default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
5395
prev_width += (crop_width * bps * count) / 8;
5396
prev_trailing_bits += trailing_bits;
5397
if (prev_trailing_bits > 7)
5398
prev_trailing_bits-= 8;
5402
if (crop->combined_width != composite_width)
5403
TIFFError("combineSeparateRegions","Combined width does not match composite width");
5406
} /* end extractCompositeRegions */
5408
/* Copy a single region of input buffer to an output buffer.
5409
* The read functions used copy separate plane data into a buffer
5410
* as interleaved samples rather than separate planes so the same
5411
* logic works to extract regions regardless of the way the data
5412
* are organized in the input file. This function can be used to
5413
* extract one or more samples from the input image by updating the
5414
* parameters for starting sample and number of samples to copy in the
5415
* fifth and eighth arguments of the call to extractContigSamples.
5416
* They would be passed as new elements of the crop_mask struct.
5420
extractSeparateRegion(struct image_data *image, struct crop_mask *crop,
5421
unsigned char *read_buff, unsigned char *crop_buff,
5424
int shift_width, prev_trailing_bits = 0;
5425
uint32 bytes_per_sample, bytes_per_pixel;
5426
uint32 src_rowsize, dst_rowsize;
5427
uint32 row, first_row, last_row, first_col, last_col;
5428
uint32 src_offset, dst_offset;
5429
uint32 crop_width, crop_length, img_width, img_length;
5432
tsample_t count, sample = 0; /* Update to extract more or more samples */
5434
img_width = image->width;
5435
img_length = image->length;
5440
bytes_per_sample = (bps + 7) / 8;
5441
bytes_per_pixel = ((bps * spp) + 7) / 8;
5443
shift_width = 0; /* Byte aligned data only */
5446
if (bytes_per_pixel < (bytes_per_sample + 1))
5447
shift_width = bytes_per_pixel;
5449
shift_width = bytes_per_sample + 1;
5452
/* rows, columns, width, length are expressed in pixels */
5453
first_row = crop->regionlist[region].y1;
5454
last_row = crop->regionlist[region].y2;
5455
first_col = crop->regionlist[region].x1;
5456
last_col = crop->regionlist[region].x2;
5458
crop_width = last_col - first_col + 1;
5459
crop_length = last_row - first_row + 1;
5461
crop->regionlist[region].width = crop_width;
5462
crop->regionlist[region].length = crop_length;
5463
crop->regionlist[region].buffptr = crop_buff;
5467
src_rowsize = ((img_width * bps * spp) + 7) / 8;
5468
dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
5470
for (row = first_row; row <= last_row; row++)
5472
src_offset = row * src_rowsize;
5473
dst_offset = (row - first_row) * dst_rowsize;
5474
src = read_buff + src_offset;
5475
dst = crop_buff + dst_offset;
5477
switch (shift_width)
5479
case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
5480
spp, bps, count, first_col,
5483
TIFFError("extractSeparateRegion",
5484
"Unable to extract row %d", row);
5488
case 1: if (extractContigSamplesShifted8bits (src, dst, img_width,
5489
sample, spp, bps, count,
5490
first_col, last_col + 1,
5491
prev_trailing_bits))
5493
TIFFError("extractSeparateRegion",
5494
"Unable to extract row %d", row);
5498
case 2: if (extractContigSamplesShifted16bits (src, dst, img_width,
5499
sample, spp, bps, count,
5500
first_col, last_col + 1,
5501
prev_trailing_bits))
5503
TIFFError("extractSeparateRegion",
5504
"Unable to extract row %d", row);
5508
case 3: if (extractContigSamplesShifted24bits (src, dst, img_width,
5509
sample, spp, bps, count,
5510
first_col, last_col + 1,
5511
prev_trailing_bits))
5513
TIFFError("extractSeparateRegion",
5514
"Unable to extract row %d", row);
5519
case 5: if (extractContigSamplesShifted32bits (src, dst, img_width,
5520
sample, spp, bps, count,
5521
first_col, last_col + 1,
5522
prev_trailing_bits))
5524
TIFFError("extractSeparateRegion",
5525
"Unable to extract row %d", row);
5529
default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
5535
} /* end extractSeparateRegion */
5538
extractImageSection(struct image_data *image, struct pageseg *section,
5539
unsigned char *src_buff, unsigned char *sect_buff)
5541
unsigned char bytebuff1, bytebuff2;
5542
unsigned char *src, *dst;
5544
uint32 img_width, img_length, img_rowsize;
5545
uint32 j, shift1, shift2, trailing_bits;
5546
uint32 row, first_row, last_row, first_col, last_col;
5547
uint32 src_offset, dst_offset, row_offset, col_offset;
5548
uint32 offset1, offset2, full_bytes;
5549
uint32 sect_width, sect_length;
5554
unsigned char bitset;
5555
static char *bitarray = NULL;
5558
img_width = image->width;
5559
img_length = image->length;
5569
if (bitarray == NULL)
5571
if ((bitarray = (char *)malloc(img_width)) == NULL)
5573
TIFFError ("", "DEBUG: Unable to allocate debugging bitarray\n");
5579
/* rows, columns, width, length are expressed in pixels */
5580
first_row = section->y1;
5581
last_row = section->y2;
5582
first_col = section->x1;
5583
last_col = section->x2;
5585
sect_width = last_col - first_col + 1;
5586
sect_length = last_row - first_row + 1;
5587
img_rowsize = ((img_width * bps + 7) / 8) * spp;
5588
full_bytes = (sect_width * spp * bps) / 8; /* number of COMPLETE bytes per row in section */
5589
trailing_bits = (sect_width * bps) % 8;
5592
TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
5593
first_row, last_row, first_col, last_col);
5594
TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
5595
img_width, img_length, bps, spp);
5596
TIFFError ("", "Sect width: %d, Sect length: %d, full bytes: %d trailing bits %d\n",
5597
sect_width, sect_length, full_bytes, trailing_bits);
5602
col_offset = first_col * spp * bps / 8;
5603
for (row = first_row; row <= last_row; row++)
5605
/* row_offset = row * img_width * spp * bps / 8; */
5606
row_offset = row * img_rowsize;
5607
src_offset = row_offset + col_offset;
5610
TIFFError ("", "Src offset: %8d, Dst offset: %8d\n", src_offset, dst_offset);
5612
_TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
5613
dst_offset += full_bytes;
5618
shift1 = spp * ((first_col * bps) % 8);
5619
shift2 = spp * ((last_col * bps) % 8);
5620
for (row = first_row; row <= last_row; row++)
5622
/* pull out the first byte */
5623
row_offset = row * img_rowsize;
5624
offset1 = row_offset + (first_col * bps / 8);
5625
offset2 = row_offset + (last_col * bps / 8);
5628
for (j = 0, k = 7; j < 8; j++, k--)
5630
bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
5631
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5633
sprintf(&bitarray[8], " ");
5634
sprintf(&bitarray[9], " ");
5635
for (j = 10, k = 7; j < 18; j++, k--)
5637
bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
5638
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5640
bitarray[18] = '\0';
5641
TIFFError ("", "Row: %3d Offset1: %d, Shift1: %d, Offset2: %d, Shift2: %d\n",
5642
row, offset1, shift1, offset2, shift2);
5645
bytebuff1 = bytebuff2 = 0;
5646
if (shift1 == 0) /* the region is byte and sample alligned */
5648
_TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
5651
TIFFError ("", " Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset);
5652
sprintf(&bitarray[18], "\n");
5653
sprintf(&bitarray[19], "\t");
5654
for (j = 20, k = 7; j < 28; j++, k--)
5656
bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
5657
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5662
dst_offset += full_bytes;
5664
if (trailing_bits != 0)
5666
bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
5667
sect_buff[dst_offset] = bytebuff2;
5669
TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n",
5670
offset2, dst_offset);
5671
for (j = 30, k = 7; j < 38; j++, k--)
5673
bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
5674
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5676
bitarray[38] = '\0';
5677
TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
5682
else /* each destination byte will have to be built from two source bytes*/
5685
TIFFError ("", " Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset);
5687
for (j = 0; j <= full_bytes; j++)
5689
bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
5690
bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
5691
sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
5694
sprintf(&bitarray[18], "\n");
5695
sprintf(&bitarray[19], "\t");
5696
for (j = 20, k = 7; j < 28; j++, k--)
5698
bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
5699
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5704
dst_offset += full_bytes;
5706
if (trailing_bits != 0)
5709
TIFFError ("", " Trailing bits src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset);
5711
if (shift2 > shift1)
5713
bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
5714
bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
5715
sect_buff[dst_offset] = bytebuff2;
5717
TIFFError ("", " Shift2 > Shift1\n");
5722
if (shift2 < shift1)
5724
bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
5725
sect_buff[dst_offset] &= bytebuff2;
5727
TIFFError ("", " Shift2 < Shift1\n");
5732
TIFFError ("", " Shift2 == Shift1\n");
5737
sprintf(&bitarray[28], " ");
5738
sprintf(&bitarray[29], " ");
5739
for (j = 30, k = 7; j < 38; j++, k--)
5741
bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
5742
sprintf(&bitarray[j], (bitset) ? "1" : "0");
5744
bitarray[38] = '\0';
5745
TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
5753
} /* end extractImageSection */
5756
writeSelections(TIFF *in, TIFF **out, struct crop_mask *crop,
5757
struct image_data *image, struct dump_opts *dump,
5758
struct buffinfo seg_buffs[], char *mp, char *filename,
5759
unsigned int *page, unsigned int total_pages)
5763
unsigned char *crop_buff = NULL;
5765
/* Where we open a new file depends on the export mode */
5766
switch (crop->exp_mode)
5768
case ONE_FILE_COMPOSITE: /* Regions combined into single image */
5770
crop_buff = seg_buffs[0].buffer;
5771
if (update_output_file (out, mp, autoindex, filename, page))
5773
page_count = total_pages;
5774
if (writeCroppedImage(in, *out, image, dump,
5775
crop->combined_width,
5776
crop->combined_length,
5777
crop_buff, *page, total_pages))
5779
TIFFError("writeRegions", "Unable to write new image");
5783
case ONE_FILE_SEPARATED: /* Regions as separated images */
5785
if (update_output_file (out, mp, autoindex, filename, page))
5787
page_count = crop->selections * total_pages;
5788
for (i = 0; i < crop->selections; i++)
5790
crop_buff = seg_buffs[i].buffer;
5791
if (writeCroppedImage(in, *out, image, dump,
5792
crop->regionlist[i].width,
5793
crop->regionlist[i].length,
5794
crop_buff, *page, page_count))
5796
TIFFError("writeRegions", "Unable to write new image");
5801
case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
5803
if (update_output_file (out, mp, autoindex, filename, page))
5806
crop_buff = seg_buffs[0].buffer;
5807
if (writeCroppedImage(in, *out, image, dump,
5808
crop->combined_width,
5809
crop->combined_length,
5810
crop_buff, *page, total_pages))
5812
TIFFError("writeRegions", "Unable to write new image");
5816
case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
5818
page_count = crop->selections;
5819
if (update_output_file (out, mp, autoindex, filename, page))
5822
for (i = 0; i < crop->selections; i++)
5824
crop_buff = seg_buffs[i].buffer;
5825
/* Write the current region to the current file */
5826
if (writeCroppedImage(in, *out, image, dump,
5827
crop->regionlist[i].width,
5828
crop->regionlist[i].length,
5829
crop_buff, *page, page_count))
5831
TIFFError("writeRegions", "Unable to write new image");
5836
case FILE_PER_SELECTION:
5839
for (i = 0; i < crop->selections; i++)
5841
if (update_output_file (out, mp, autoindex, filename, page))
5844
crop_buff = seg_buffs[i].buffer;
5845
/* Write the current region to the current file */
5846
if (writeCroppedImage(in, *out, image, dump,
5847
crop->regionlist[i].width,
5848
crop->regionlist[i].length,
5849
crop_buff, *page, page_count))
5851
TIFFError("writeRegions", "Unable to write new image");
5856
default: return (1);
5860
} /* end writeRegions */
5863
writeImageSections(TIFF *in, TIFF *out, struct image_data *image,
5864
struct pagedef *page, struct pageseg *sections,
5865
struct dump_opts * dump, unsigned char *src_buff,
5866
unsigned char **sect_buff_ptr)
5869
uint32 i, k, width, length, sectsize;
5870
unsigned char *sect_buff = *sect_buff_ptr;
5877
"Writing %d sections for each original page. Hres: %3.2f Vres: %3.2f\n",
5878
page->rows * page->cols, hres, vres);
5880
k = page->cols * page->rows;
5881
if ((k < 1) || (k > MAX_SECTIONS))
5883
TIFFError("writeImageSections",
5884
"%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
5888
for (i = 0; i < k; i++)
5890
width = sections[i].x2 - sections[i].x1 + 1;
5891
length = sections[i].y2 - sections[i].y1 + 1;
5893
ceil((width * image->bps + 7) / (double)8) * image->spp * length;
5894
/* allocate a buffer if we don't have one already */
5895
if (createImageSection(sectsize, sect_buff_ptr))
5897
TIFFError("writeImageSections", "Unable to allocate section buffer");
5900
sect_buff = *sect_buff_ptr;
5903
TIFFError ("", "\nSection: %d, Width: %4d, Length: %4d, x1: %4d x2: %4d y1: %4d y2: %4d\n",
5904
i + 1, width, length, sections[i].x1, sections[i].x2, sections[i].y1, sections[i].y2);
5907
if (extractImageSection (image, §ions[i], src_buff, sect_buff))
5909
TIFFError("writeImageSections", "Unable to extract image sections");
5913
/* call the write routine here instead of outside the loop */
5914
if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
5916
TIFFError("writeImageSections", "Unable to write image section");
5922
} /* end writeImageSections */
5924
/* Code in this function is heavily indebted to code in tiffcp
5925
* with modifications by Richard Nolde to handle orientation correctly.
5928
writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
5929
struct dump_opts *dump, uint32 width, uint32 length,
5930
double hres, double vres,
5931
unsigned char *sect_buff)
5938
"\nWriting single section: Width %d Length: %d Hres: %4.1f, Vres: %4.1f\n\n",
5939
width, length, hres, vres);
5941
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
5942
TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
5944
CopyField(TIFFTAG_BITSPERSAMPLE, bps);
5945
CopyField(TIFFTAG_SAMPLESPERPIXEL, spp);
5946
if (compression != (uint16)-1)
5947
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
5949
CopyField(TIFFTAG_COMPRESSION, compression);
5951
if (compression == COMPRESSION_JPEG) {
5952
uint16 input_compression, input_photometric;
5954
if (TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression)
5955
&& input_compression == COMPRESSION_JPEG) {
5956
TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
5958
if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &input_photometric)) {
5959
if(input_photometric == PHOTOMETRIC_RGB) {
5960
if (jpegcolormode == JPEGCOLORMODE_RGB)
5961
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
5963
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
5965
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
5970
if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
5971
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
5972
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
5974
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
5977
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
5979
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
5981
/* The loadimage function reads input orientation and sets
5982
* image->orientation. The correct_image_orientation function
5983
* applies the required rotation and mirror operations to
5984
* present the data in TOPLEFT orientation and updates
5985
* image->orientation if any transforms are performed,
5986
* as per EXIF standard. Original tiffcp code removed here.
5988
TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
5991
* Choose tiles/strip for the output image according to
5992
* the command line arguments (-tiles, -strips) and the
5993
* structure of the input image.
5996
outtiled = TIFFIsTiled(in);
5999
* Setup output file's tile width&height. If either
6000
* is not specified, use either the value from the
6001
* input image or, if nothing is defined, use the
6004
if (tilewidth == (uint32) -1)
6005
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
6006
if (tilelength == (uint32) -1)
6007
TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
6009
if (tilewidth > width)
6011
if (tilelength > length)
6012
tilelength = length;
6014
TIFFDefaultTileSize(out, &tilewidth, &tilelength);
6015
TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
6016
TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
6019
* RowsPerStrip is left unspecified: use either the
6020
* value from the input image or, if nothing is defined,
6021
* use the library default.
6023
if (rowsperstrip == (uint32) 0) {
6024
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip)) {
6025
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
6027
if (rowsperstrip > length && rowsperstrip != (uint32)-1)
6028
rowsperstrip = length;
6030
else if (rowsperstrip == (uint32) -1)
6031
rowsperstrip = length;
6032
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
6034
if (config != (uint16) -1)
6035
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
6037
CopyField(TIFFTAG_PLANARCONFIG, config);
6039
CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
6040
CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
6042
/* SMinSampleValue & SMaxSampleValue */
6043
switch (compression) {
6044
case COMPRESSION_JPEG:
6045
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
6046
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
6048
case COMPRESSION_LZW:
6049
case COMPRESSION_ADOBE_DEFLATE:
6050
case COMPRESSION_DEFLATE:
6051
if (predictor != (uint16)-1)
6052
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
6054
CopyField(TIFFTAG_PREDICTOR, predictor);
6056
case COMPRESSION_CCITTFAX3:
6057
case COMPRESSION_CCITTFAX4:
6058
if (compression == COMPRESSION_CCITTFAX3) {
6059
if (g3opts != (uint32) -1)
6060
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
6062
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
6064
CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
6065
CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
6066
CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
6067
CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
6068
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
6069
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
6070
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
6075
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
6076
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
6079
const char* inknames;
6080
if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
6081
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
6082
if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
6083
int inknameslen = strlen(inknames) + 1;
6084
const char* cp = inknames;
6086
cp = strchr(cp, '\0');
6089
inknameslen += (strlen(cp) + 1);
6093
TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
6098
unsigned short pg0, pg1;
6099
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
6100
if (pageNum < 0) /* only one input file */
6101
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
6103
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
6107
for (p = tags; p < &tags[NTAGS]; p++)
6108
CopyTag(p->tag, p->count, p->type);
6110
/* Update these since they are overwritten from input res by loop above */
6111
TIFFSetField(out, TIFFTAG_XRESOLUTION, (float)hres);
6112
TIFFSetField(out, TIFFTAG_YRESOLUTION, (float)vres);
6114
/* Compute the tile or strip dimensions and write to disk */
6117
if (config == PLANARCONFIG_CONTIG)
6119
writeBufferToContigTiles (out, sect_buff, length, width, spp);
6122
writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
6126
if (config == PLANARCONFIG_CONTIG)
6128
writeBufferToContigStrips (out, sect_buff, length, width, spp);
6132
writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
6136
if (!TIFFWriteDirectory(out))
6143
} /* end writeSingleSection */
6146
/* Create a buffer to write one section at a time */
6148
createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
6150
unsigned char *sect_buff = NULL;
6151
unsigned char *new_buff = NULL;
6152
static uint32 prev_sectsize = 0;
6154
sect_buff = *sect_buff_ptr;
6158
sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
6159
*sect_buff_ptr = sect_buff;
6160
_TIFFmemset(sect_buff, 0, sectsize);
6164
if (prev_sectsize < sectsize)
6166
new_buff = _TIFFrealloc(sect_buff, sectsize);
6170
sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
6173
sect_buff = new_buff;
6175
_TIFFmemset(sect_buff, 0, sectsize);
6181
TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
6184
prev_sectsize = sectsize;
6185
*sect_buff_ptr = sect_buff;
6188
} /* end createImageSection */
6191
/* Process selections defined by regions, zones, margins, or fixed sized areas */
6193
processCropSelections(struct image_data *image, struct crop_mask *crop,
6194
unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
6197
uint32 width, length, total_width, total_length;
6199
unsigned char *crop_buff = NULL;
6200
unsigned char *read_buff = NULL;
6201
unsigned char *next_buff = NULL;
6202
tsize_t prev_cropsize = 0;
6204
read_buff = *read_buff_ptr;
6206
if (crop->img_mode == COMPOSITE_IMAGES)
6208
cropsize = crop->bufftotal;
6209
crop_buff = seg_buffs[0].buffer;
6211
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6214
prev_cropsize = seg_buffs[0].size;
6215
if (prev_cropsize < cropsize)
6217
next_buff = _TIFFrealloc(crop_buff, cropsize);
6220
_TIFFfree (crop_buff);
6221
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6224
crop_buff = next_buff;
6230
TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
6234
_TIFFmemset(crop_buff, 0, cropsize);
6235
seg_buffs[0].buffer = crop_buff;
6236
seg_buffs[0].size = cropsize;
6238
/* Checks for matching width or length as required */
6239
if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
6242
if (crop->crop_mode & CROP_INVERT)
6244
switch (crop->photometric)
6246
/* Just change the interpretation */
6247
case PHOTOMETRIC_MINISWHITE:
6248
case PHOTOMETRIC_MINISBLACK:
6249
image->photometric = crop->photometric;
6251
case INVERT_DATA_ONLY:
6252
case INVERT_DATA_AND_TAG:
6253
if (invertImage(image->photometric, image->spp, image->bps,
6254
crop->combined_width, crop->combined_length, crop_buff))
6256
TIFFError("processCropSelections",
6257
"Failed to invert colorspace for composite regions");
6260
if (crop->photometric == INVERT_DATA_AND_TAG)
6262
switch (image->photometric)
6264
case PHOTOMETRIC_MINISWHITE:
6265
image->photometric = PHOTOMETRIC_MINISBLACK;
6267
case PHOTOMETRIC_MINISBLACK:
6268
image->photometric = PHOTOMETRIC_MINISWHITE;
6279
/* Mirror and Rotate will not work with multiple regions unless they are the same width */
6280
if (crop->crop_mode & CROP_MIRROR)
6282
if (mirrorImage(image->spp, image->bps, crop->mirror,
6283
crop->combined_width, crop->combined_length, crop_buff))
6285
TIFFError("processCropSelections", "Failed to mirror composite regions %s",
6286
(crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
6291
if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
6293
if (rotateImage(crop->rotation, image, &crop->combined_width,
6294
&crop->combined_length, &crop_buff))
6296
TIFFError("processCropSelections",
6297
"Failed to rotate composite regions by %d degrees", crop->rotation);
6300
seg_buffs[0].buffer = crop_buff;
6301
seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
6302
* image->spp) * crop->combined_length;
6305
else /* Separated Images */
6307
total_width = total_length = 0;
6308
for (i = 0; i < crop->selections; i++)
6310
cropsize = crop->bufftotal;
6311
crop_buff = seg_buffs[i].buffer;
6313
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6316
prev_cropsize = seg_buffs[0].size;
6317
if (prev_cropsize < cropsize)
6319
next_buff = _TIFFrealloc(crop_buff, cropsize);
6322
_TIFFfree (crop_buff);
6323
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6326
crop_buff = next_buff;
6332
TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
6336
_TIFFmemset(crop_buff, 0, cropsize);
6337
seg_buffs[i].buffer = crop_buff;
6338
seg_buffs[i].size = cropsize;
6340
if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
6342
TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
6346
width = crop->regionlist[i].width;
6347
length = crop->regionlist[i].length;
6349
if (crop->crop_mode & CROP_INVERT)
6351
switch (crop->photometric)
6353
/* Just change the interpretation */
6354
case PHOTOMETRIC_MINISWHITE:
6355
case PHOTOMETRIC_MINISBLACK:
6356
image->photometric = crop->photometric;
6358
case INVERT_DATA_ONLY:
6359
case INVERT_DATA_AND_TAG:
6360
if (invertImage(image->photometric, image->spp, image->bps,
6361
width, length, crop_buff))
6363
TIFFError("processCropSelections",
6364
"Failed to invert colorspace for region");
6367
if (crop->photometric == INVERT_DATA_AND_TAG)
6369
switch (image->photometric)
6371
case PHOTOMETRIC_MINISWHITE:
6372
image->photometric = PHOTOMETRIC_MINISBLACK;
6374
case PHOTOMETRIC_MINISBLACK:
6375
image->photometric = PHOTOMETRIC_MINISWHITE;
6386
if (crop->crop_mode & CROP_MIRROR)
6388
if (mirrorImage(image->spp, image->bps, crop->mirror,
6389
width, length, crop_buff))
6391
TIFFError("processCropSelections", "Failed to mirror crop region %s",
6392
(crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
6397
if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
6399
if (rotateImage(crop->rotation, image, &crop->regionlist[i].width,
6400
&crop->regionlist[i].length, &crop_buff))
6402
TIFFError("processCropSelections",
6403
"Failed to rotate crop region by %d degrees", crop->rotation);
6406
total_width += crop->regionlist[i].width;
6407
total_length += crop->regionlist[i].length;
6408
crop->combined_width = total_width;
6409
crop->combined_length = total_length;
6410
seg_buffs[i].buffer = crop_buff;
6411
seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
6412
* image->spp) * crop->regionlist[i].length;
6417
} /* end processCropSelections */
6419
/* Copy the crop section of the data from the current image into a buffer
6420
* and adjust the IFD values to reflect the new size. If no cropping is
6421
* required, use the origial read buffer as the crop buffer.
6423
* There is quite a bit of redundancy between this routine and the more
6424
* specialized processCropSelections, but this provides
6425
* the most optimized path when no Zones or Regions are required.
6428
createCroppedImage(struct image_data *image, struct crop_mask *crop,
6429
unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
6432
unsigned char *read_buff = NULL;
6433
unsigned char *crop_buff = NULL;
6434
unsigned char *new_buff = NULL;
6435
static tsize_t prev_cropsize = 0;
6437
read_buff = *read_buff_ptr;
6439
/* process full image, no crop buffer needed */
6440
crop_buff = read_buff;
6441
*crop_buff_ptr = read_buff;
6442
crop->combined_width = image->width;
6443
crop->combined_length = image->length;
6445
cropsize = crop->bufftotal;
6446
crop_buff = *crop_buff_ptr;
6449
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6450
*crop_buff_ptr = crop_buff;
6451
_TIFFmemset(crop_buff, 0, cropsize);
6452
prev_cropsize = cropsize;
6456
if (prev_cropsize < cropsize)
6458
new_buff = _TIFFrealloc(crop_buff, cropsize);
6462
crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
6465
crop_buff = new_buff;
6466
_TIFFmemset(crop_buff, 0, cropsize);
6472
TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
6475
*crop_buff_ptr = crop_buff;
6477
if (crop->crop_mode & CROP_INVERT)
6479
switch (crop->photometric)
6481
/* Just change the interpretation */
6482
case PHOTOMETRIC_MINISWHITE:
6483
case PHOTOMETRIC_MINISBLACK:
6484
image->photometric = crop->photometric;
6486
case INVERT_DATA_ONLY:
6487
case INVERT_DATA_AND_TAG:
6488
if (invertImage(image->photometric, image->spp, image->bps,
6489
crop->combined_width, crop->combined_length, crop_buff))
6491
TIFFError("createCroppedImage",
6492
"Failed to invert colorspace for image or cropped selection");
6495
if (crop->photometric == INVERT_DATA_AND_TAG)
6497
switch (image->photometric)
6499
case PHOTOMETRIC_MINISWHITE:
6500
image->photometric = PHOTOMETRIC_MINISBLACK;
6502
case PHOTOMETRIC_MINISBLACK:
6503
image->photometric = PHOTOMETRIC_MINISWHITE;
6514
if (crop->crop_mode & CROP_MIRROR)
6516
if (mirrorImage(image->spp, image->bps, crop->mirror,
6517
crop->combined_width, crop->combined_length, crop_buff))
6519
TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s",
6520
(crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
6525
if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
6527
if (rotateImage(crop->rotation, image, &crop->combined_width,
6528
&crop->combined_length, crop_buff_ptr))
6530
TIFFError("createCroppedImage",
6531
"Failed to rotate image or cropped selection by %d degrees", crop->rotation);
6536
if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
6537
*read_buff_ptr = NULL; /* so we don't try to free it later */
6540
} /* end createCroppedImage */
6543
/* The code in this function is heavily indebted to code from tiffcp. */
6545
writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image,
6546
struct dump_opts *dump, uint32 width, uint32 length,
6547
unsigned char *crop_buff, int pagenum, int total_pages)
6552
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
6553
TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
6555
CopyField(TIFFTAG_BITSPERSAMPLE, bps);
6556
CopyField(TIFFTAG_SAMPLESPERPIXEL, spp);
6557
if (compression != (uint16)-1)
6558
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
6560
CopyField(TIFFTAG_COMPRESSION, compression);
6562
if (compression == COMPRESSION_JPEG) {
6563
uint16 input_compression, input_photometric;
6565
if (TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression)
6566
&& input_compression == COMPRESSION_JPEG) {
6567
TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
6569
if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &input_photometric)) {
6570
if(input_photometric == PHOTOMETRIC_RGB) {
6571
if (jpegcolormode == JPEGCOLORMODE_RGB)
6572
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
6574
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
6576
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
6581
if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
6582
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
6583
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
6585
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
6588
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
6590
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
6592
/* The loadimage function reads input orientation and sets
6593
* image->orientation. The correct_image_orientation function
6594
* applies the required rotation and mirror operations to
6595
* present the data in TOPLEFT orientation and updates
6596
* image->orientation if any transforms are performed,
6597
* as per EXIF standard.
6599
TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
6602
* Choose tiles/strip for the output image according to
6603
* the command line arguments (-tiles, -strips) and the
6604
* structure of the input image.
6607
outtiled = TIFFIsTiled(in);
6610
* Setup output file's tile width&height. If either
6611
* is not specified, use either the value from the
6612
* input image or, if nothing is defined, use the
6615
if (tilewidth == (uint32) -1)
6616
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
6617
if (tilelength == (uint32) -1)
6618
TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
6620
if (tilewidth > width)
6622
if (tilelength > length)
6623
tilelength = length;
6625
TIFFDefaultTileSize(out, &tilewidth, &tilelength);
6626
TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
6627
TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
6630
* RowsPerStrip is left unspecified: use either the
6631
* value from the input image or, if nothing is defined,
6632
* use the library default.
6634
if (rowsperstrip == (uint32) 0)
6636
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
6638
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
6640
if (rowsperstrip > length)
6641
rowsperstrip = length;
6644
if (rowsperstrip == (uint32) -1)
6645
rowsperstrip = length;
6646
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
6648
if (config != (uint16) -1)
6649
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
6651
CopyField(TIFFTAG_PLANARCONFIG, config);
6653
CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
6654
CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
6656
/* SMinSampleValue & SMaxSampleValue */
6657
switch (compression) {
6658
case COMPRESSION_JPEG:
6659
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
6660
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
6662
case COMPRESSION_LZW:
6663
case COMPRESSION_ADOBE_DEFLATE:
6664
case COMPRESSION_DEFLATE:
6665
if (predictor != (uint16)-1)
6666
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
6668
CopyField(TIFFTAG_PREDICTOR, predictor);
6670
case COMPRESSION_CCITTFAX3:
6671
case COMPRESSION_CCITTFAX4:
6672
if (compression == COMPRESSION_CCITTFAX3) {
6673
if (g3opts != (uint32) -1)
6674
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
6676
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
6678
CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
6679
CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
6680
CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
6681
CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
6682
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
6683
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
6684
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
6689
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
6690
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
6693
const char* inknames;
6694
if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
6695
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
6696
if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
6697
int inknameslen = strlen(inknames) + 1;
6698
const char* cp = inknames;
6700
cp = strchr(cp, '\0');
6703
inknameslen += (strlen(cp) + 1);
6707
TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
6712
unsigned short pg0, pg1;
6713
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
6714
TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
6718
for (p = tags; p < &tags[NTAGS]; p++)
6719
CopyTag(p->tag, p->count, p->type);
6721
/* Compute the tile or strip dimensions and write to disk */
6724
if (config == PLANARCONFIG_CONTIG)
6726
writeBufferToContigTiles (out, crop_buff, length, width, spp);
6729
writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump);
6733
if (config == PLANARCONFIG_CONTIG)
6735
writeBufferToContigStrips (out, crop_buff, length, width, spp);
6739
writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump);
6743
if (!TIFFWriteDirectory(out))
6750
} /* end writeCroppedImage */
6753
rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
6754
uint32 length, uint32 col, uint8 *src, uint8 *dst)
6757
uint32 src_byte = 0, src_bit = 0;
6758
uint32 row, rowsize = 0, bit_offset = 0;
6759
uint8 matchbits = 0, maskbits = 0;
6760
uint8 buff1 = 0, buff2 = 0;
6764
if ((src == NULL) || (dst == NULL))
6766
TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
6770
rowsize = ((bps * spp * width) + 7) / 8;
6772
maskbits = (uint8)-1 >> ( 8 - bps);
6775
for (row = 0; row < length ; row++)
6777
bit_offset = col * bps * spp;
6778
for (sample = 0; sample < spp; sample++)
6782
src_byte = bit_offset / 8;
6783
src_bit = bit_offset % 8;
6787
src_byte = (bit_offset + (sample * bps)) / 8;
6788
src_bit = (bit_offset + (sample * bps)) % 8;
6793
case 90: next = src + src_byte - (row * rowsize);
6795
case 270: next = src + src_byte + (row * rowsize);
6797
default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
6800
matchbits = maskbits << (8 - src_bit - bps);
6801
buff1 = ((*next) & matchbits) << (src_bit);
6803
/* If we have a full buffer's worth, write it out */
6804
if (ready_bits >= 8)
6812
buff2 = (buff2 | (buff1 >> ready_bits));
6820
buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
6825
} /* end rotateContigSamples8bits */
6829
rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
6830
uint32 length, uint32 col, uint8 *src, uint8 *dst)
6833
uint32 row, rowsize, bit_offset;
6834
uint32 src_byte = 0, src_bit = 0;
6835
uint16 matchbits = 0, maskbits = 0;
6836
uint16 buff1 = 0, buff2 = 0;
6842
if ((src == NULL) || (dst == NULL))
6844
TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
6848
rowsize = ((bps * spp * width) + 7) / 8;
6850
maskbits = (uint16)-1 >> (16 - bps);
6852
for (row = 0; row < length; row++)
6854
bit_offset = col * bps * spp;
6855
for (sample = 0; sample < spp; sample++)
6859
src_byte = bit_offset / 8;
6860
src_bit = bit_offset % 8;
6864
src_byte = (bit_offset + (sample * bps)) / 8;
6865
src_bit = (bit_offset + (sample * bps)) % 8;
6870
case 90: next = src + src_byte - (row * rowsize);
6872
case 270: next = src + src_byte + (row * rowsize);
6874
default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
6877
matchbits = maskbits << (16 - src_bit - bps);
6880
swapbuff[1] = *next;
6881
swapbuff[0] = *(next + 1);
6885
swapbuff[0] = *next;
6886
swapbuff[1] = *(next + 1);
6889
buff1 = *((uint16 *)swapbuff);
6890
buff1 = (buff1 & matchbits) << (src_bit);
6892
/* If we have a full buffer's worth, write it out */
6893
if (ready_bits >= 8)
6895
bytebuff = (buff2 >> 8);
6898
/* shift in new bits */
6899
buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
6902
{ /* add another bps bits to the buffer */
6904
buff2 = (buff2 | (buff1 >> ready_bits));
6912
bytebuff = (buff2 >> 8);
6917
} /* end rotateContigSamples16bits */
6920
rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
6921
uint32 length, uint32 col, uint8 *src, uint8 *dst)
6924
uint32 row, rowsize, bit_offset;
6925
uint32 src_byte = 0, src_bit = 0;
6926
uint32 matchbits = 0, maskbits = 0;
6927
uint32 buff1 = 0, buff2 = 0;
6928
uint8 bytebuff1 = 0, bytebuff2 = 0;
6934
if ((src == NULL) || (dst == NULL))
6936
TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
6940
rowsize = ((bps * spp * width) + 7) / 8;
6942
maskbits = (uint32)-1 >> (32 - bps);
6944
for (row = 0; row < length; row++)
6946
bit_offset = col * bps * spp;
6947
for (sample = 0; sample < spp; sample++)
6951
src_byte = bit_offset / 8;
6952
src_bit = bit_offset % 8;
6956
src_byte = (bit_offset + (sample * bps)) / 8;
6957
src_bit = (bit_offset + (sample * bps)) % 8;
6962
case 90: next = src + src_byte - (row * rowsize);
6964
case 270: next = src + src_byte + (row * rowsize);
6966
default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
6969
matchbits = maskbits << (32 - src_bit - bps);
6972
swapbuff[3] = *next;
6973
swapbuff[2] = *(next + 1);
6974
swapbuff[1] = *(next + 2);
6975
swapbuff[0] = *(next + 3);
6979
swapbuff[0] = *next;
6980
swapbuff[1] = *(next + 1);
6981
swapbuff[2] = *(next + 2);
6982
swapbuff[3] = *(next + 3);
6985
buff1 = *((uint32 *)swapbuff);
6986
buff1 = (buff1 & matchbits) << (src_bit);
6988
/* If we have a full buffer's worth, write it out */
6989
if (ready_bits >= 16)
6991
bytebuff1 = (buff2 >> 24);
6993
bytebuff2 = (buff2 >> 16);
6997
/* shift in new bits */
6998
buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
7001
{ /* add another bps bits to the buffer */
7002
bytebuff1 = bytebuff2 = 0;
7003
buff2 = (buff2 | (buff1 >> ready_bits));
7009
/* catch any trailing bits at the end of the line */
7010
while (ready_bits > 0)
7012
bytebuff1 = (buff2 >> 24);
7015
buff2 = (buff2 << 8);
7016
bytebuff2 = bytebuff1;
7021
} /* end rotateContigSamples24bits */
7024
rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
7025
uint32 length, uint32 col, uint8 *src, uint8 *dst)
7027
int ready_bits = 0, shift_width = 0;
7028
int bytes_per_sample, bytes_per_pixel;
7029
uint32 row, rowsize, bit_offset;
7030
uint32 src_byte, src_bit;
7031
uint32 longbuff1 = 0, longbuff2 = 0;
7032
uint64 maskbits = 0, matchbits = 0;
7033
uint64 buff1 = 0, buff2 = 0, buff3 = 0;
7034
uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
7035
unsigned char swapbuff1[4];
7036
unsigned char swapbuff2[4];
7041
if ((src == NULL) || (dst == NULL))
7043
TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
7047
bytes_per_sample = (bps + 7) / 8;
7048
bytes_per_pixel = ((bps * spp) + 7) / 8;
7049
if (bytes_per_pixel < (bytes_per_sample + 1))
7050
shift_width = bytes_per_pixel;
7052
shift_width = bytes_per_sample + 1;
7054
rowsize = ((bps * spp * width) + 7) / 8;
7056
maskbits = (uint64)-1 >> (64 - bps);
7058
for (row = 0; row < length; row++)
7060
bit_offset = col * bps * spp;
7061
for (sample = 0; sample < spp; sample++)
7065
src_byte = bit_offset / 8;
7066
src_bit = bit_offset % 8;
7070
src_byte = (bit_offset + (sample * bps)) / 8;
7071
src_bit = (bit_offset + (sample * bps)) % 8;
7076
case 90: next = src + src_byte - (row * rowsize);
7078
case 270: next = src + src_byte + (row * rowsize);
7080
default: TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
7083
matchbits = maskbits << (64 - src_bit - bps);
7086
swapbuff1[3] = *next;
7087
swapbuff1[2] = *(next + 1);
7088
swapbuff1[1] = *(next + 2);
7089
swapbuff1[0] = *(next + 3);
7093
swapbuff1[0] = *next;
7094
swapbuff1[1] = *(next + 1);
7095
swapbuff1[2] = *(next + 2);
7096
swapbuff1[3] = *(next + 3);
7098
longbuff1 = *((uint32 *)swapbuff1);
7100
memset (swapbuff2, '\0', sizeof(swapbuff2));
7103
swapbuff2[3] = *next;
7104
swapbuff2[2] = *(next + 1);
7105
swapbuff2[1] = *(next + 2);
7106
swapbuff2[0] = *(next + 3);
7110
swapbuff2[0] = *next;
7111
swapbuff2[1] = *(next + 1);
7112
swapbuff2[2] = *(next + 2);
7113
swapbuff2[3] = *(next + 3);
7116
longbuff2 = *((uint32 *)swapbuff2);
7117
buff3 = ((uint64)longbuff1 << 32) | longbuff2;
7118
buff1 = (buff3 & matchbits) << (src_bit);
7120
if (ready_bits < 32)
7121
{ /* add another bps bits to the buffer */
7122
bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
7123
buff2 = (buff2 | (buff1 >> ready_bits));
7125
else /* If we have a full buffer's worth, write it out */
7127
bytebuff1 = (buff2 >> 56);
7129
bytebuff2 = (buff2 >> 48);
7131
bytebuff3 = (buff2 >> 40);
7133
bytebuff4 = (buff2 >> 32);
7137
/* shift in new bits */
7138
buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
7143
while (ready_bits > 0)
7145
bytebuff1 = (buff2 >> 56);
7147
buff2 = (buff2 << 8);
7152
} /* end rotateContigSamples32bits */
7155
/* Rotate an image by a multiple of 90 degrees clockwise */
7157
rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
7158
uint32 *img_length, unsigned char **ibuff_ptr)
7161
uint32 bytes_per_pixel, bytes_per_sample;
7162
uint32 row, rowsize, src_offset, dst_offset;
7163
uint32 i, col, width, length;
7164
uint32 colsize, buffsize, col_offset, pix_offset;
7165
unsigned char *ibuff;
7170
unsigned char *rbuff = NULL;
7173
length = *img_length;
7177
rowsize = ((bps * spp * width) + 7) / 8;
7178
colsize = ((bps * spp * length) + 7) / 8;
7179
if ((colsize * width) > (rowsize * length))
7180
buffsize = (colsize + 1) * width;
7182
buffsize = (rowsize + 1) * length;
7184
bytes_per_sample = (bps + 7) / 8;
7185
bytes_per_pixel = ((bps * spp) + 7) / 8;
7186
if (bytes_per_pixel < (bytes_per_sample + 1))
7187
shift_width = bytes_per_pixel;
7189
shift_width = bytes_per_sample + 1;
7194
case 360: return (0);
7198
default: TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
7202
if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
7204
TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
7207
_TIFFmemset(rbuff, '\0', buffsize);
7212
case 180: if ((bps % 8) == 0) /* byte alligned data */
7215
pix_offset = (spp * bps) / 8;
7216
for (row = 0; row < length; row++)
7218
dst_offset = (length - row - 1) * rowsize;
7219
for (col = 0; col < width; col++)
7221
col_offset = (width - col - 1) * pix_offset;
7222
dst = rbuff + dst_offset + col_offset;
7224
for (i = 0; i < bytes_per_pixel; i++)
7230
{ /* non 8 bit per sample data */
7231
for (row = 0; row < length; row++)
7233
src_offset = row * rowsize;
7234
dst_offset = (length - row - 1) * rowsize;
7235
src = ibuff + src_offset;
7236
dst = rbuff + dst_offset;
7237
switch (shift_width)
7239
case 1: if (reverseSamples8bits(spp, bps, width, src, dst))
7245
case 2: if (reverseSamples16bits(spp, bps, width, src, dst))
7251
case 3: if (reverseSamples24bits(spp, bps, width, src, dst))
7258
case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
7264
default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
7271
*(ibuff_ptr) = rbuff;
7274
case 90: if ((bps % 8) == 0) /* byte aligned data */
7276
for (col = 0; col < width; col++)
7278
src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
7279
dst_offset = col * colsize;
7280
src = ibuff + src_offset;
7281
dst = rbuff + dst_offset;
7282
for (row = length; row > 0; row--)
7284
for (i = 0; i < bytes_per_pixel; i++)
7285
*dst++ = *(src + i);
7291
{ /* non 8 bit per sample data */
7292
for (col = 0; col < width; col++)
7294
src_offset = (length - 1) * rowsize;
7295
dst_offset = col * colsize;
7296
src = ibuff + src_offset;
7297
dst = rbuff + dst_offset;
7298
switch (shift_width)
7300
case 1: if (rotateContigSamples8bits(rotation, spp, bps, width,
7301
length, col, src, dst))
7307
case 2: if (rotateContigSamples16bits(rotation, spp, bps, width,
7308
length, col, src, dst))
7314
case 3: if (rotateContigSamples24bits(rotation, spp, bps, width,
7315
length, col, src, dst))
7322
case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
7323
length, col, src, dst))
7329
default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
7336
*(ibuff_ptr) = rbuff;
7338
*img_width = length;
7339
*img_length = width;
7340
image->width = length;
7341
image->length = width;
7342
res_temp = image->xres;
7343
image->xres = image->yres;
7344
image->yres = res_temp;
7347
case 270: if ((bps % 8) == 0) /* byte aligned data */
7349
for (col = 0; col < width; col++)
7351
src_offset = col * bytes_per_pixel;
7352
dst_offset = (width - col - 1) * colsize;
7353
src = ibuff + src_offset;
7354
dst = rbuff + dst_offset;
7355
for (row = length; row > 0; row--)
7357
for (i = 0; i < bytes_per_pixel; i++)
7358
*dst++ = *(src + i);
7364
{ /* non 8 bit per sample data */
7365
for (col = 0; col < width; col++)
7368
dst_offset = (width - col - 1) * colsize;
7369
src = ibuff + src_offset;
7370
dst = rbuff + dst_offset;
7371
switch (shift_width)
7373
case 1: if (rotateContigSamples8bits(rotation, spp, bps, width,
7374
length, col, src, dst))
7380
case 2: if (rotateContigSamples16bits(rotation, spp, bps, width,
7381
length, col, src, dst))
7387
case 3: if (rotateContigSamples24bits(rotation, spp, bps, width,
7388
length, col, src, dst))
7395
case 5: if (rotateContigSamples32bits(rotation, spp, bps, width,
7396
length, col, src, dst))
7402
default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
7409
*(ibuff_ptr) = rbuff;
7411
*img_width = length;
7412
*img_length = width;
7413
image->width = length;
7414
image->length = width;
7415
res_temp = image->xres;
7416
image->xres = image->yres;
7417
image->yres = res_temp;
7424
} /* end rotateImage */
7427
reverseSamples8bits (uint16 spp, uint16 bps, uint32 width,
7428
uint8 *ibuff, uint8 *obuff)
7432
uint32 src_byte, src_bit;
7433
uint32 bit_offset = 0;
7434
uint8 matchbits = 0, maskbits = 0;
7435
uint8 buff1 = 0, buff2 = 0;
7440
if ((ibuff == NULL) || (obuff == NULL))
7442
TIFFError("reverseSamples8bits","Invalid image or work buffer");
7447
maskbits = (uint8)-1 >> ( 8 - bps);
7449
for (col = width; col > 0; col--)
7451
/* Compute src byte(s) and bits within byte(s) */
7452
bit_offset = (col - 1) * bps * spp;
7453
for (sample = 0; sample < spp; sample++)
7457
src_byte = bit_offset / 8;
7458
src_bit = bit_offset % 8;
7462
src_byte = (bit_offset + (sample * bps)) / 8;
7463
src_bit = (bit_offset + (sample * bps)) % 8;
7466
src = ibuff + src_byte;
7467
matchbits = maskbits << (8 - src_bit - bps);
7468
buff1 = ((*src) & matchbits) << (src_bit);
7471
buff2 = (buff2 | (buff1 >> ready_bits));
7472
else /* If we have a full buffer's worth, write it out */
7483
buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
7488
} /* end reverseSamples8bits */
7491
reverseSamples16bits (uint16 spp, uint16 bps, uint32 width,
7492
uint8 *ibuff, uint8 *obuff)
7496
uint32 src_byte = 0, src_bit = 0;
7497
uint32 bit_offset = 0;
7498
uint16 matchbits = 0, maskbits = 0;
7499
uint16 buff1 = 0, buff2 = 0;
7503
unsigned char swapbuff[2];
7506
if ((ibuff == NULL) || (obuff == NULL))
7508
TIFFError("reverseSample16bits","Invalid image or work buffer");
7513
maskbits = (uint16)-1 >> (16 - bps);
7515
for (col = width; col > 0; col--)
7517
/* Compute src byte(s) and bits within byte(s) */
7518
bit_offset = (col - 1) * bps * spp;
7519
for (sample = 0; sample < spp; sample++)
7523
src_byte = bit_offset / 8;
7524
src_bit = bit_offset % 8;
7528
src_byte = (bit_offset + (sample * bps)) / 8;
7529
src_bit = (bit_offset + (sample * bps)) % 8;
7532
src = ibuff + src_byte;
7533
matchbits = maskbits << (16 - src_bit - bps);
7537
swapbuff[0] = *(src + 1);
7542
swapbuff[1] = *(src + 1);
7545
buff1 = *((uint16 *)swapbuff);
7546
buff1 = (buff1 & matchbits) << (src_bit);
7549
{ /* add another bps bits to the buffer */
7551
buff2 = (buff2 | (buff1 >> ready_bits));
7553
else /* If we have a full buffer's worth, write it out */
7555
bytebuff = (buff2 >> 8);
7558
/* shift in new bits */
7559
buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
7567
bytebuff = (buff2 >> 8);
7572
} /* end reverseSamples16bits */
7575
reverseSamples24bits (uint16 spp, uint16 bps, uint32 width,
7576
uint8 *ibuff, uint8 *obuff)
7580
uint32 src_byte = 0, src_bit = 0;
7581
uint32 bit_offset = 0;
7582
uint32 matchbits = 0, maskbits = 0;
7583
uint32 buff1 = 0, buff2 = 0;
7584
uint8 bytebuff1 = 0, bytebuff2 = 0;
7587
unsigned char swapbuff[4];
7590
if ((ibuff == NULL) || (obuff == NULL))
7592
TIFFError("reverseSamples24bits","Invalid image or work buffer");
7597
maskbits = (uint32)-1 >> (32 - bps);
7599
for (col = width; col > 0; col--)
7601
/* Compute src byte(s) and bits within byte(s) */
7602
bit_offset = (col - 1) * bps * spp;
7603
for (sample = 0; sample < spp; sample++)
7607
src_byte = bit_offset / 8;
7608
src_bit = bit_offset % 8;
7612
src_byte = (bit_offset + (sample * bps)) / 8;
7613
src_bit = (bit_offset + (sample * bps)) % 8;
7616
src = ibuff + src_byte;
7617
matchbits = maskbits << (32 - src_bit - bps);
7621
swapbuff[2] = *(src + 1);
7622
swapbuff[1] = *(src + 2);
7623
swapbuff[0] = *(src + 3);
7628
swapbuff[1] = *(src + 1);
7629
swapbuff[2] = *(src + 2);
7630
swapbuff[3] = *(src + 3);
7633
buff1 = *((uint32 *)swapbuff);
7634
buff1 = (buff1 & matchbits) << (src_bit);
7636
if (ready_bits < 16)
7637
{ /* add another bps bits to the buffer */
7638
bytebuff1 = bytebuff2 = 0;
7639
buff2 = (buff2 | (buff1 >> ready_bits));
7641
else /* If we have a full buffer's worth, write it out */
7643
bytebuff1 = (buff2 >> 24);
7645
bytebuff2 = (buff2 >> 16);
7649
/* shift in new bits */
7650
buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
7656
/* catch any trailing bits at the end of the line */
7657
while (ready_bits > 0)
7659
bytebuff1 = (buff2 >> 24);
7662
buff2 = (buff2 << 8);
7663
bytebuff2 = bytebuff1;
7668
} /* end reverseSamples24bits */
7672
reverseSamples32bits (uint16 spp, uint16 bps, uint32 width,
7673
uint8 *ibuff, uint8 *obuff)
7675
int ready_bits = 0, shift_width = 0;
7676
int bytes_per_sample, bytes_per_pixel;
7678
uint32 src_byte = 0, src_bit = 0;
7680
uint32 longbuff1 = 0, longbuff2 = 0;
7681
uint64 maskbits = 0, matchbits = 0;
7682
uint64 buff1 = 0, buff2 = 0, buff3 = 0;
7683
uint8 bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
7686
unsigned char swapbuff1[4];
7687
unsigned char swapbuff2[4];
7690
if ((ibuff == NULL) || (obuff == NULL))
7692
TIFFError("reverseSamples32bits","Invalid image or work buffer");
7697
maskbits = (uint64)-1 >> (64 - bps);
7700
bytes_per_sample = (bps + 7) / 8;
7701
bytes_per_pixel = ((bps * spp) + 7) / 8;
7702
if (bytes_per_pixel < (bytes_per_sample + 1))
7703
shift_width = bytes_per_pixel;
7705
shift_width = bytes_per_sample + 1;
7707
for (col = width; col > 0; col--)
7709
/* Compute src byte(s) and bits within byte(s) */
7710
bit_offset = (col - 1) * bps * spp;
7711
for (sample = 0; sample < spp; sample++)
7715
src_byte = bit_offset / 8;
7716
src_bit = bit_offset % 8;
7720
src_byte = (bit_offset + (sample * bps)) / 8;
7721
src_bit = (bit_offset + (sample * bps)) % 8;
7724
src = ibuff + src_byte;
7725
matchbits = maskbits << (64 - src_bit - bps);
7728
swapbuff1[3] = *src;
7729
swapbuff1[2] = *(src + 1);
7730
swapbuff1[1] = *(src + 2);
7731
swapbuff1[0] = *(src + 3);
7735
swapbuff1[0] = *src;
7736
swapbuff1[1] = *(src + 1);
7737
swapbuff1[2] = *(src + 2);
7738
swapbuff1[3] = *(src + 3);
7740
longbuff1 = *((uint32 *)swapbuff1);
7742
memset (swapbuff2, '\0', sizeof(swapbuff2));
7745
swapbuff2[3] = *src;
7746
swapbuff2[2] = *(src + 1);
7747
swapbuff2[1] = *(src + 2);
7748
swapbuff2[0] = *(src + 3);
7752
swapbuff2[0] = *src;
7753
swapbuff2[1] = *(src + 1);
7754
swapbuff2[2] = *(src + 2);
7755
swapbuff2[3] = *(src + 3);
7758
longbuff2 = *((uint32 *)swapbuff2);
7759
buff3 = ((uint64)longbuff1 << 32) | longbuff2;
7760
buff1 = (buff3 & matchbits) << (src_bit);
7762
if (ready_bits < 32)
7763
{ /* add another bps bits to the buffer */
7764
bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
7765
buff2 = (buff2 | (buff1 >> ready_bits));
7767
else /* If we have a full buffer's worth, write it out */
7769
bytebuff1 = (buff2 >> 56);
7771
bytebuff2 = (buff2 >> 48);
7773
bytebuff3 = (buff2 >> 40);
7775
bytebuff4 = (buff2 >> 32);
7779
/* shift in new bits */
7780
buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
7785
while (ready_bits > 0)
7787
bytebuff1 = (buff2 >> 56);
7789
buff2 = (buff2 << 8);
7794
} /* end reverseSamples32bits */
7797
reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width,
7798
uint8 *src, uint8 *dst)
7801
uint32 col, bytes_per_pixel, col_offset;
7803
unsigned char swapbuff[32];
7805
if ((src == NULL) || (dst == NULL))
7807
TIFFError("reverseSamplesBytes","Invalid input or output buffer");
7811
bytes_per_pixel = ((bps * spp) + 7) / 8;
7814
case 8: /* Use memcpy for multiple bytes per sample data */
7817
case 2: for (col = 0; col < (width / 2); col++)
7819
col_offset = col * bytes_per_pixel;
7820
_TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
7821
_TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
7822
_TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
7825
case 1: /* Use byte copy only for single byte per sample data */
7826
for (col = 0; col < (width / 2); col++)
7828
for (i = 0; i < spp; i++)
7831
*src++ = *(dst - spp + i);
7832
*(dst - spp + i) = bytebuff1;
7837
default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
7841
} /* end reverseSamplesBytes */
7844
/* Mirror an image horizontally or vertically */
7846
mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
7849
uint32 bytes_per_pixel, bytes_per_sample;
7850
uint32 row, rowsize, row_offset;
7851
unsigned char *line_buff = NULL;
7856
rowsize = ((width * bps * spp) + 7) / 8;
7861
line_buff = (unsigned char *)_TIFFmalloc(rowsize);
7862
if (line_buff == NULL)
7864
TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
7868
dst = ibuff + (rowsize * (length - 1));
7869
for (row = 0; row < length / 2; row++)
7871
_TIFFmemcpy(line_buff, src, rowsize);
7872
_TIFFmemcpy(src, dst, rowsize);
7873
_TIFFmemcpy(dst, line_buff, rowsize);
7878
_TIFFfree(line_buff);
7879
if (mirror == MIRROR_VERT)
7882
if ((bps % 8) == 0) /* byte alligned data */
7884
for (row = 0; row < length; row++)
7886
row_offset = row * rowsize;
7887
src = ibuff + row_offset;
7888
dst = ibuff + row_offset + rowsize;
7889
if (reverseSamplesBytes(spp, bps, width, src, dst))
7896
{ /* non 8 bit per sample data */
7897
if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
7899
TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
7902
bytes_per_sample = (bps + 7) / 8;
7903
bytes_per_pixel = ((bps * spp) + 7) / 8;
7904
if (bytes_per_pixel < (bytes_per_sample + 1))
7905
shift_width = bytes_per_pixel;
7907
shift_width = bytes_per_sample + 1;
7909
for (row = 0; row < length; row++)
7911
row_offset = row * rowsize;
7912
src = ibuff + row_offset;
7913
_TIFFmemset (line_buff, '\0', rowsize);
7914
switch (shift_width)
7916
case 1: if (reverseSamples8bits(spp, bps, width, src, line_buff))
7918
_TIFFfree(line_buff);
7921
_TIFFmemcpy (src, line_buff, rowsize);
7923
case 2: if (reverseSamples16bits(spp, bps, width, src, line_buff))
7925
_TIFFfree(line_buff);
7928
_TIFFmemcpy (src, line_buff, rowsize);
7930
case 3: if (reverseSamples24bits(spp, bps, width, src, line_buff))
7932
_TIFFfree(line_buff);
7935
_TIFFmemcpy (src, line_buff, rowsize);
7938
case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
7940
_TIFFfree(line_buff);
7943
_TIFFmemcpy (src, line_buff, rowsize);
7945
default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
7946
_TIFFfree(line_buff);
7951
_TIFFfree(line_buff);
7955
default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
7963
/* Invert the light and dark values for a bilevel or grayscale image */
7965
invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
7968
unsigned char bytebuff1, bytebuff2, bytebuff3, bytebuff4;
7975
TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
7979
if (photometric != PHOTOMETRIC_MINISWHITE && photometric != PHOTOMETRIC_MINISBLACK)
7981
TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
7988
TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
7994
case 32: src_uint32 = (uint32 *)src;
7995
for (row = 0; row < length; row++)
7996
for (col = 0; col < width; col++)
7998
*src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
8002
case 16: src_uint16 = (uint16 *)src;
8003
for (row = 0; row < length; row++)
8004
for (col = 0; col < width; col++)
8006
*src_uint16 = (uint16)0xFFFF - *src_uint16;
8010
case 8: for (row = 0; row < length; row++)
8011
for (col = 0; col < width; col++)
8013
*src = (uint8)255 - *src;
8017
case 4: for (row = 0; row < length; row++)
8018
for (col = 0; col < width; col++)
8020
bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
8021
bytebuff2 = 16 - (*src & 15);
8022
*src = bytebuff1 << 4 & bytebuff2;
8026
case 2: for (row = 0; row < length; row++)
8027
for (col = 0; col < width; col++)
8029
bytebuff1 = 4 - (uint8)(*src & 192 >> 6);
8030
bytebuff2 = 4 - (uint8)(*src & 48 >> 4);
8031
bytebuff3 = 4 - (uint8)(*src & 12 >> 2);
8032
bytebuff4 = 4 - (uint8)(*src & 3);
8033
*src = (bytebuff1 << 6) || (bytebuff2 << 4) || (bytebuff3 << 2) || bytebuff4;
8037
case 1: for (row = 0; row < length; row++)
8038
for (col = 0; col < width; col += 8 /(spp * bps))
8044
default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
8051
/* vim: set ts=8 sts=8 sw=8 noet: */