~ubuntu-branches/ubuntu/oneiric/tiff/oneiric

« back to all changes in this revision

Viewing changes to tools/tiffcrop.c

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2009-08-28 15:44:23 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090828154423-7oisj77n302jrroa
Tags: 3.9.1-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tiffcrop.c,v 1.3.2.6 2009-08-20 22:31:00 bfriesen Exp $ */
 
2
 
 
3
/* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
 
4
 * the image data through additional options listed below
 
5
 *
 
6
 * Original code:
 
7
 * Copyright (c) 1988-1997 Sam Leffler
 
8
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 
9
 *
 
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.
 
17
 * 
 
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.  
 
21
 * 
 
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 
 
27
 * OF THIS SOFTWARE.
 
28
 *
 
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.
 
33
 *
 
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.
 
40
 *
 
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.
 
47
 *
 
48
 * Options: 
 
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
 
68
 *                units
 
69
 * -K #           Vertical margin of output page to # expressed in current
 
70
 *                units
 
71
 * -X #           Horizontal dimension of region to extract expressed in current
 
72
 *                units
 
73
 * -Y #           Vertical dimension of region to extract expressed in current
 
74
 *                units
 
75
 * -O orient      Orientation for output image, portrait, landscape, auto
 
76
 * -P page        Page size for output image segments, eg letter, legal, tabloid,
 
77
 *                etc.
 
78
 * -S cols:rows   Divide the image into equal sized segments using cols across
 
79
 *                and rows down
 
80
 * -E t|l|r|b     Edge to use as origin
 
81
 * -m #,#,#,#     Margins from edges for selection: top, left, bottom, right
 
82
 *                (commas separated)
 
83
 * -Z #:#,#:#     Zones of the image designated as zone X of Y, 
 
84
 *                eg 1:3 would be first of three equal portions measured
 
85
 *                from reference edge
 
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
 
93
 *                clockwise  
 
94
 * -F h|v         Flip (mirror) image or crop selection horizontally
 
95
 *                or vertically 
 
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.
 
112
 */
 
113
 
 
114
#include "tif_config.h"
 
115
#include "tiffiop.h"
 
116
 
 
117
#include <stdio.h>
 
118
#include <stdlib.h>
 
119
#include <string.h>
 
120
#include <math.h>
 
121
#include <ctype.h>
 
122
#include <limits.h>
 
123
#include <sys/stat.h>
 
124
#include <assert.h>
 
125
 
 
126
#ifdef HAVE_UNISTD_H
 
127
# include <unistd.h>
 
128
#endif
 
129
 
 
130
#ifndef HAVE_GETOPT
 
131
extern int getopt(int, char**, char*);
 
132
#endif
 
133
 
 
134
#include "tiffio.h"
 
135
 
 
136
#if defined(VMS)
 
137
# define unlink delete
 
138
#endif
 
139
 
 
140
#ifndef PATH_MAX
 
141
#define PATH_MAX 1024
 
142
#endif
 
143
 
 
144
#ifndef streq
 
145
#define streq(a,b)      (strcmp((a),(b)) == 0)
 
146
#endif
 
147
#define strneq(a,b,n)   (strncmp((a),(b),(n)) == 0)
 
148
 
 
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)
 
152
 
 
153
#define TRUE    1
 
154
#define FALSE   0
 
155
 
 
156
/*
 
157
 * Definitions and data structures required to support cropping and image
 
158
 * manipulations.
 
159
 */
 
160
 
 
161
#define EDGE_TOP      1
 
162
#define EDGE_LEFT     2
 
163
#define EDGE_BOTTOM   3
 
164
#define EDGE_RIGHT    4
 
165
#define EDGE_CENTER   5
 
166
 
 
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 
 
174
 
 
175
#define CROP_NONE     0
 
176
#define CROP_MARGINS  1
 
177
#define CROP_WIDTH    2
 
178
#define CROP_LENGTH   4
 
179
#define CROP_ZONES    8
 
180
#define CROP_REGIONS 16
 
181
#define CROP_ROTATE  32
 
182
#define CROP_MIRROR  64
 
183
#define CROP_INVERT 128
 
184
 
 
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 */
 
191
 
 
192
#define COMPOSITE_IMAGES         0 /* Selections combined into one image */  
 
193
#define SEPARATED_IMAGES         1 /* Selections saved to separate images */
 
194
 
 
195
#define STRIP    1
 
196
#define TILE     2
 
197
 
 
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 */
 
204
 
 
205
#define DUMP_NONE   0
 
206
#define DUMP_TEXT   1
 
207
#define DUMP_RAW    2
 
208
 
 
209
/* Offsets into buffer for margins and fixed width and length segments */
 
210
struct offset {
 
211
  uint32  tmargin;
 
212
  uint32  lmargin;
 
213
  uint32  bmargin;
 
214
  uint32  rmargin;
 
215
  uint32  crop_width;
 
216
  uint32  crop_length;
 
217
  uint32  startx;
 
218
  uint32  endx;
 
219
  uint32  starty;
 
220
  uint32  endy;
 
221
};
 
222
 
 
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.
 
227
 */
 
228
 
 
229
struct  buffinfo {
 
230
  uint32 size;           /* size of this buffer */
 
231
  unsigned char *buffer; /* address of the allocated buffer */
 
232
};
 
233
 
 
234
struct  zone {
 
235
  int   position;  /* ordinal of segment to be extracted */
 
236
  int   total;     /* total equal sized divisions of crop area */
 
237
  };
 
238
 
 
239
struct  pageseg {
 
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 */
 
247
};
 
248
 
 
249
struct  coordpairs {
 
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 */
 
254
};
 
255
 
 
256
struct  region {
 
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 */
 
265
};
 
266
 
 
267
/* Cropping parameters from command line and image data */
 
268
struct crop_mask {
 
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 */
 
292
};
 
293
 
 
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"
 
301
 
 
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
 
307
 
 
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
 
313
 
 
314
#define INVERT_DATA_ONLY      10
 
315
#define INVERT_DATA_AND_TAG   11
 
316
 
 
317
struct paperdef {
 
318
  char   name[MAX_PAPERNAME_LENGTH];
 
319
  double width;
 
320
  double length;
 
321
  double asratio;
 
322
  };
 
323
 
 
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},
 
375
};
 
376
 
 
377
/* Structure to define in input image parameters */
 
378
struct image_data {
 
379
  float  xres;
 
380
  float  yres;
 
381
  uint32 width;
 
382
  uint32 length;
 
383
  uint16 res_unit;
 
384
  uint16 bps;
 
385
  uint16 spp;
 
386
  uint16 planar;
 
387
  uint16 photometric;
 
388
  uint16 orientation;
 
389
  uint16 adjustments;
 
390
};
 
391
 
 
392
/* Structure to define the output image modifiers */
 
393
struct pagedef {
 
394
  char          name[16];
 
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 */
 
406
};
 
407
 
 
408
struct dump_opts {
 
409
  int  debug;
 
410
  int  format;
 
411
  int  level;
 
412
  char mode[4];
 
413
  char infilename[PATH_MAX + 1];
 
414
  char outfilename[PATH_MAX + 1];
 
415
  FILE *infile;
 
416
  FILE *outfile;
 
417
  };
 
418
 
 
419
/* globals */
 
420
static int    outtiled = -1;
 
421
static uint32 tilewidth;
 
422
static uint32 tilelength;
 
423
 
 
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;
 
438
 
 
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);
 
453
 
 
454
static int processCompressOptions(char*);
 
455
static void usage(void);
 
456
 
 
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 *);
 
462
 
 
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 *, 
 
467
                            struct dump_opts *, 
 
468
                            unsigned int *, unsigned int *);
 
469
static  int update_output_file (TIFF **, char *, int, char *, unsigned int *);
 
470
 
 
471
 
 
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 *, 
 
475
                                     struct offset *);
 
476
static int  computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
 
477
                                       struct pagedef *, struct pageseg *,
 
478
                                       struct dump_opts *);
 
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);
 
487
 
 
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 *, 
 
498
                               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);
 
505
 
 
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 *,
 
516
                       unsigned char **);
 
517
static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
 
518
                       unsigned char *);
 
519
static int invertImage(uint16, uint16, uint16, uint32, uint32,
 
520
                       unsigned char *);
 
521
 
 
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 *);
 
528
 
 
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,
 
552
                                             int);
 
553
static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
 
554
                                              tsample_t, uint16, uint16, 
 
555
                                              tsample_t, uint32, uint32,
 
556
                                              int);
 
557
static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
 
558
                                              tsample_t, uint16, uint16, 
 
559
                                              tsample_t, uint32, uint32,
 
560
                                              int);
 
561
static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
 
562
                                              tsample_t, uint16, uint16, 
 
563
                                              tsample_t, uint32, uint32,
 
564
                                              int);
 
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, 
 
576
                                       FILE *, int, int);
 
577
 
 
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 *);
 
586
 
 
587
/* End function declarations */
 
588
/* Functions derived in whole or in part from tiffcp */
 
589
 
 
590
/* The following functions are taken largely intact from tiffcp */
 
591
 
 
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",
 
599
" ",
 
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",
 
607
" ",
 
608
" -r #          Make each strip have no more than # rows",
 
609
" -w #          Set output tile width (pixels)",
 
610
" -l #          Set output tile length (pixels)",
 
611
" ",
 
612
" -f lsb2msb    Force lsb-to-msb FillOrder for output",
 
613
" -f msb2lsb    Force msb-to-lsb FillOrder for output",
 
614
"",
 
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",
 
622
" ",
 
623
"Group 3 options:",
 
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",
 
628
" ",
 
629
"JPEG options:",
 
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",
 
633
" ",
 
634
"LZW and deflate options:",
 
635
" #             Set predictor value",
 
636
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
 
637
" ",
 
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.",
 
644
" ",
 
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",
 
647
" ",
 
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",
 
655
"",
 
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.",
 
670
"",
 
671
"Output options:",
 
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",
 
676
" ",
 
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.",
 
680
" ",
 
681
" -F hor|vert|both",
 
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",
 
691
" ",
 
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.",
 
697
" ",
 
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",
 
701
"",
 
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.",
 
705
" ",
 
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.",
 
709
" ",
 
710
"   input:full-path-to-directory/input-dumpname",
 
711
" ",
 
712
"   output:full-path-to-directory/output-dumpnaem",
 
713
" ",
 
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.",
 
717
" ",
 
718
"             The four debug/dump options are independent, though it makes little sense to",
 
719
"             specify a dump file without specifying a detail level.",
 
720
" ",
 
721
NULL
 
722
};
 
723
 
 
724
static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, 
 
725
                                      uint32 imagelength, 
 
726
                                      uint32 imagewidth, 
 
727
                                      tsample_t spp)
 
728
{
 
729
        int status = 1;
 
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;
 
735
        uint32 tw, tl;
 
736
        uint32 row;
 
737
 
 
738
        (void) spp;
 
739
        if (tilebuf == 0)
 
740
                return 0;
 
741
        (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 
742
        (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
743
        
 
744
        for (row = 0; row < imagelength; row += tl) {
 
745
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
746
                uint32 colb = 0;
 
747
                uint32 col;
 
748
 
 
749
                for (col = 0; col < imagewidth; col += tw) {
 
750
                        if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
 
751
                            && !ignore) {
 
752
                                TIFFError(TIFFFileName(in),
 
753
                                          "Error, can't read tile at %lu %lu",
 
754
                                          (unsigned long) col,
 
755
                                          (unsigned long) row);
 
756
                                status = 0;
 
757
                                goto done;
 
758
                        }
 
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 );
 
765
                        } else
 
766
                                cpStripToTile(bufp + colb,
 
767
                                              tilebuf, nrow, tilew,
 
768
                                              iskew, 0);
 
769
                        colb += tilew;
 
770
                }
 
771
                bufp += imagew * nrow;
 
772
        }
 
773
done:
 
774
        _TIFFfree(tilebuf);
 
775
        return status;
 
776
}
 
777
 
 
778
static int  readSeparateTilesIntoBuffer (TIFF* in, uint8 *buf, 
 
779
            uint32 imagelength, uint32 imagewidth, uint16 spp)
 
780
{
 
781
        int status = 1;
 
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;
 
787
        uint32 tw, tl;
 
788
        uint32 row;
 
789
        uint16 bps, bytes_per_sample;
 
790
 
 
791
        if (tilebuf == 0)
 
792
                return 0;
 
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;
 
798
 
 
799
        for (row = 0; row < imagelength; row += tl) {
 
800
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
801
                uint32 colb = 0;
 
802
                uint32 col;
 
803
 
 
804
                for (col = 0; col < imagewidth; col += tw) {
 
805
                        tsample_t s;
 
806
 
 
807
                        for (s = 0; s < spp; s++) {
 
808
                                if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
 
809
                                    && !ignore) {
 
810
                                        TIFFError(TIFFFileName(in),
 
811
                                          "Error, can't read tile at %lu %lu, "
 
812
                                          "sample %lu",
 
813
                                          (unsigned long) col,
 
814
                                          (unsigned long) row,
 
815
                                          (unsigned long) s);
 
816
                                        status = 0;
 
817
                                        goto done;
 
818
                                }
 
819
                                /*
 
820
                                 * Tile is clipped horizontally.  Calculate
 
821
                                 * visible portion and skewing factors.
 
822
                                 */
 
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,
 
828
                                            tilebuf, nrow,
 
829
                                            width/(spp*bytes_per_sample),
 
830
                                            oskew + iskew,
 
831
                                            oskew/spp, spp,
 
832
                                            bytes_per_sample);
 
833
                                } else
 
834
                                        cpSeparateBufToContigBuf(
 
835
                                            bufp+colb+s*bytes_per_sample,
 
836
                                            tilebuf, nrow, tw,
 
837
                                            iskew, 0, spp,
 
838
                                            bytes_per_sample);
 
839
                        }
 
840
                        colb += tilew*spp;
 
841
                }
 
842
                bufp += imagew * nrow;
 
843
        }
 
844
done:
 
845
        _TIFFfree(tilebuf);
 
846
        return status;
 
847
}
 
848
 
 
849
static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength, 
 
850
                                     uint32 imagewidth, tsample_t spp)
 
851
{
 
852
        uint32 row, rowsperstrip;
 
853
        tstrip_t strip = 0;
 
854
 
 
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);
 
864
                        return 0;
 
865
                }
 
866
                buf += stripsize;
 
867
        }
 
868
        return 1;
 
869
}
 
870
 
 
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.
 
875
 */
 
876
static int 
 
877
writeBufferToSeparateStrips (TIFF* out, uint8* buf, 
 
878
                             uint32 length, uint32 width, uint16 spp,
 
879
                             struct dump_opts *dump)
 
880
  {
 
881
  uint8   *src;
 
882
  uint16   bps;
 
883
  uint32   row, nrows, rowsize, rowsperstrip;
 
884
  uint32   bytes_per_sample;
 
885
  tsample_t s;
 
886
  tstrip_t strip = 0;
 
887
  tsize_t  stripsize = TIFFStripSize(out);
 
888
  tsize_t  rowstripsize,  scanlinesize = TIFFScanlineSize(out);
 
889
  tsize_t  total_bytes = 0;
 
890
  tdata_t  obuf;
 
891
 
 
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);
 
897
 
 
898
  obuf = _TIFFmalloc (rowstripsize);
 
899
  if (obuf == NULL)
 
900
    return (0);
 
901
  
 
902
  for (s = 0; s < spp; s++)
 
903
    {
 
904
    for (row = 0; row < length; row += rowsperstrip)
 
905
      {
 
906
      nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
 
907
 
 
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))
 
913
        {
 
914
        _TIFFfree(obuf);
 
915
        return (0);
 
916
        }
 
917
      if ((dump->outfile != NULL) && (dump->level == 1))
 
918
        {
 
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);
 
923
        }
 
924
 
 
925
      if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
 
926
        {
 
927
        TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
 
928
        _TIFFfree(obuf);
 
929
        return 0;
 
930
        }
 
931
      }
 
932
    }      
 
933
 
 
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.
 
937
 
 
938
  tsize_t row_buffsize;
 
939
  row_buffsize = scanlinesize + (((spp + bps) + 7) / 8);
 
940
  obuf = _TIFFmalloc (row_buffsize);
 
941
  if (obuf == NULL)
 
942
    return (0);
 
943
 
 
944
 
 
945
 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); 
 
946
  for (row = 0; row < length; row++)
 
947
    {
 
948
    src = buf + (row * rowsize);
 
949
    total_bytes += scanlinesize;
 
950
    for (s = 0; s < spp; s++)
 
951
      {
 
952
      memset (obuf, '\0', row_buffsize);
 
953
      if (extractContigSamplesToBuffer(obuf, src, 1, width, 0, 0, s, spp, bps, dump))
 
954
        {
 
955
        _TIFFfree(obuf);
 
956
        return (0);
 
957
        }
 
958
      if ((dump->outfile != NULL) && (dump->level == 1))
 
959
        {
 
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);
 
964
        }
 
965
 
 
966
      if (TIFFWriteScanline(out, obuf, row, s) < 0)
 
967
        {
 
968
        TIFFError(TIFFFileName(out), "Error, can't write scanline %lu", row + 1);
 
969
        _TIFFfree(obuf);
 
970
        return 0;
 
971
        }
 
972
      }
 
973
    } 
 
974
*/   
 
975
 
 
976
  _TIFFfree(obuf);
 
977
  return 1;
 
978
}
 
979
 
 
980
static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
 
981
                                     uint32 imagewidth, tsample_t spp)
 
982
{
 
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;
 
988
        uint32 tl, tw;
 
989
        uint32 row;
 
990
 
 
991
        (void) spp;
 
992
        if (obuf == NULL)
 
993
                return 0;
 
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;
 
998
                uint32 colb = 0;
 
999
                uint32 col;
 
1000
 
 
1001
                for (col = 0; col < imagewidth; col += tw) {
 
1002
                        /*
 
1003
                         * Tile is clipped horizontally.  Calculate
 
1004
                         * visible portion and skewing factors.
 
1005
                         */
 
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);
 
1011
                        } else
 
1012
                                cpStripToTile(obuf, bufp + colb, nrow, tilew,
 
1013
                                    0, iskew);
 
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);
 
1019
                                _TIFFfree(obuf);
 
1020
                                return 0;
 
1021
                        }
 
1022
                        colb += tilew;
 
1023
                }
 
1024
                bufp += nrow * imagew;
 
1025
        }
 
1026
        _TIFFfree(obuf);
 
1027
        return 1;
 
1028
}
 
1029
 
 
1030
static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
 
1031
                                       uint32 imagewidth, tsample_t spp, 
 
1032
                                       struct dump_opts * dump)
 
1033
  {
 
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;
 
1040
        uint32 tl, tw;
 
1041
        uint32 row;
 
1042
        uint16 bps, bytes_per_sample;
 
1043
 
 
1044
        if (obuf == NULL)
 
1045
                return 0;
 
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;
 
1051
        
 
1052
        for (row = 0; row < imagelength; row += tl) {
 
1053
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
1054
                uint32 colb = 0;
 
1055
                uint32 col;
 
1056
 
 
1057
                for (col = 0; col < imagewidth; col += tw) {
 
1058
                        tsample_t s;
 
1059
                        for (s = 0; s < spp; s++) {
 
1060
                                /*
 
1061
                                 * Tile is clipped horizontally.  Calculate
 
1062
                                 * visible portion and skewing factors.
 
1063
                                 */
 
1064
                                if (colb + tilew > imagew) {
 
1065
                                        uint32 width = (imagew - colb);
 
1066
                                        int oskew = tilew - width;
 
1067
 
 
1068
                                  extractContigSamplesToBuffer(obuf,
 
1069
                                            bufp + (colb*spp) + s,
 
1070
                                            nrow, width/bytes_per_sample,
 
1071
                                            oskew, (oskew*spp)+iskew, s,
 
1072
                                            spp, bps, dump);
 
1073
                                } else
 
1074
                                    extractContigSamplesToBuffer(obuf,
 
1075
                                            bufp + (colb*spp) + s,
 
1076
                                            nrow, tilewidth,
 
1077
                                            0, iskew, s, spp,
 
1078
                                            bps, dump);
 
1079
                                if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
 
1080
                                        TIFFError(TIFFFileName(out),
 
1081
                                        "Error, can't write tile at %lu %lu "
 
1082
                                        "sample %lu",
 
1083
                                        (unsigned long) col,
 
1084
                                        (unsigned long) row,
 
1085
                                        (unsigned long) s);
 
1086
                                        _TIFFfree(obuf);
 
1087
                                        return 0;
 
1088
                                }
 
1089
                        }
 
1090
                        colb += tilew;
 
1091
                }
 
1092
                bufp += nrow * iimagew;
 
1093
        }
 
1094
        _TIFFfree(obuf);
 
1095
        return 1;
 
1096
}
 
1097
 
 
1098
 
 
1099
static void
 
1100
processG3Options(char* cp)
 
1101
{
 
1102
        if( (cp = strchr(cp, ':')) ) {
 
1103
                if (defg3opts == (uint32) -1)
 
1104
                        defg3opts = 0;
 
1105
                do {
 
1106
                        cp++;
 
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;
 
1113
                        else
 
1114
                                usage();
 
1115
                } while( (cp = strchr(cp, ':')) );
 
1116
        }
 
1117
}
 
1118
 
 
1119
static int
 
1120
processCompressOptions(char* opt)
 
1121
{
 
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, ':');
 
1128
 
 
1129
                defcompression = COMPRESSION_JPEG;
 
1130
                while( cp )
 
1131
                {
 
1132
                    if (isdigit((int)cp[1]))
 
1133
                        quality = atoi(cp+1);
 
1134
                    else if (cp[1] == 'r' )
 
1135
                        jpegcolormode = JPEGCOLORMODE_RAW;
 
1136
                    else
 
1137
                        usage();
 
1138
 
 
1139
                    cp = strchr(cp+1,':');
 
1140
                }
 
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, ':');
 
1148
                if (cp)
 
1149
                        defpredictor = atoi(cp+1);
 
1150
                defcompression = COMPRESSION_LZW;
 
1151
        } else if (strneq(opt, "zip", 3)) {
 
1152
                char* cp = strchr(opt, ':');
 
1153
                if (cp)
 
1154
                        defpredictor = atoi(cp+1);
 
1155
                defcompression = COMPRESSION_ADOBE_DEFLATE;
 
1156
        } else
 
1157
                return (0);
 
1158
        return (1);
 
1159
}
 
1160
 
 
1161
 
 
1162
static void
 
1163
usage(void)
 
1164
{
 
1165
        char buf[BUFSIZ];
 
1166
        int i;
 
1167
 
 
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]);
 
1172
        exit(-1);
 
1173
}
 
1174
 
 
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)
 
1183
 
 
1184
static void
 
1185
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
 
1186
{
 
1187
        switch (type) {
 
1188
        case TIFF_SHORT:
 
1189
                if (count == 1) {
 
1190
                        uint16 shortv;
 
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) {
 
1199
                        uint16 shortv1;
 
1200
                        uint16* shortav;
 
1201
                        CopyField2(tag, shortv1, shortav);
 
1202
                }
 
1203
                break;
 
1204
        case TIFF_LONG:
 
1205
                { uint32 longv;
 
1206
                  CopyField(tag, longv);
 
1207
                }
 
1208
                break;
 
1209
        case TIFF_RATIONAL:
 
1210
                if (count == 1) {
 
1211
                        float floatv;
 
1212
                        CopyField(tag, floatv);
 
1213
                } else if (count == (uint16) -1) {
 
1214
                        float* floatav;
 
1215
                        CopyField(tag, floatav);
 
1216
                }
 
1217
                break;
 
1218
        case TIFF_ASCII:
 
1219
                { char* stringv;
 
1220
                  CopyField(tag, stringv);
 
1221
                }
 
1222
                break;
 
1223
        case TIFF_DOUBLE:
 
1224
                if (count == 1) {
 
1225
                        double doublev;
 
1226
                        CopyField(tag, doublev);
 
1227
                } else if (count == (uint16) -1) {
 
1228
                        double* doubleav;
 
1229
                        CopyField(tag, doubleav);
 
1230
                }
 
1231
                break;
 
1232
          default:
 
1233
                TIFFError(TIFFFileName(in),
 
1234
                          "Data type %d is not supported, tag %d skipped.",
 
1235
                          tag, type);
 
1236
        }
 
1237
}
 
1238
 
 
1239
static struct cpTag {
 
1240
        uint16  tag;
 
1241
        uint16  count;
 
1242
        TIFFDataType type;
 
1243
} tags[] = {
 
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 },
 
1277
};
 
1278
#define NTAGS   (sizeof (tags) / sizeof (tags[0]))
 
1279
 
 
1280
#define CopyTag(tag, count, type)       cpTag(in, out, tag, count, type)
 
1281
 
 
1282
static void
 
1283
cpStripToTile(uint8* out, uint8* in,
 
1284
        uint32 rows, uint32 cols, int outskew, int inskew)
 
1285
{
 
1286
        while (rows-- > 0) {
 
1287
                uint32 j = cols;
 
1288
                while (j-- > 0)
 
1289
                        *out++ = *in++;
 
1290
                out += outskew;
 
1291
                in += inskew;
 
1292
        }
 
1293
}
 
1294
 
 
1295
 
 
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 )
 
1303
    {
 
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;
 
1309
    extern int   optind;
 
1310
    extern char* optarg;
 
1311
 
 
1312
    *mp++ = 'w';
 
1313
    *mp = '\0';
 
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)
 
1316
      {
 
1317
    good_args++;
 
1318
    switch (c) {
 
1319
      case 'a': mode[0] = 'a';  /* append to output */
 
1320
                break;
 
1321
      case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
 
1322
                  {
 
1323
                  TIFFError ("Unknown compression option", "%s", optarg);
 
1324
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1325
                  exit (-1);
 
1326
                  }
 
1327
                break;
 
1328
      case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
 
1329
                if (start == 0)
 
1330
                  {
 
1331
                  TIFFError ("","Directory offset must be greater than zero");
 
1332
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1333
                  exit (-1);
 
1334
                  }
 
1335
                *dirnum = start - 1;
 
1336
                break;
 
1337
      case 'e': switch (tolower(optarg[0])) /* image export modes*/
 
1338
                  {
 
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;
 
1347
                            break; /* Image */
 
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");
 
1356
                            exit (-1);
 
1357
                  }
 
1358
                break;
 
1359
      case 'f': if (streq(optarg, "lsb2msb"))      /* fill order */
 
1360
                  *deffillorder = FILLORDER_LSB2MSB;
 
1361
                else if (streq(optarg, "msb2lsb"))
 
1362
                  *deffillorder = FILLORDER_MSB2LSB;
 
1363
                else
 
1364
                  {
 
1365
                  TIFFError ("Unknown fill order", "%s", optarg);
 
1366
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1367
                  exit (-1);
 
1368
                  }
 
1369
                break;
 
1370
      case 'h': usage();
 
1371
                break;
 
1372
      case 'i': ignore = TRUE;          /* ignore errors */
 
1373
                break;
 
1374
      case 'l': outtiled = TRUE;         /* tile length */
 
1375
                *deftilelength = atoi(optarg);
 
1376
                break;
 
1377
      case 'p': /* planar configuration */
 
1378
                if (streq(optarg, "separate"))
 
1379
                  *defconfig = PLANARCONFIG_SEPARATE;
 
1380
                else if (streq(optarg, "contig"))
 
1381
                  *defconfig = PLANARCONFIG_CONTIG;
 
1382
                else
 
1383
                  {
 
1384
                  TIFFError ("Unkown planar configuration", "%s", optarg);
 
1385
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1386
                  exit (-1);
 
1387
                  }
 
1388
                break;
 
1389
      case 'r': /* rows/strip */
 
1390
                *defrowsperstrip = atol(optarg);
 
1391
                break;
 
1392
      case 's': /* generate stripped output */
 
1393
                outtiled = FALSE;
 
1394
                break;
 
1395
      case 't': /* generate tiled output */
 
1396
                outtiled = TRUE;
 
1397
                break;
 
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");
 
1403
                exit (0);
 
1404
                break;
 
1405
      case 'w': /* tile width */
 
1406
                outtiled = TRUE;
 
1407
                *deftilewidth = atoi(optarg);
 
1408
                break;
 
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++)
 
1414
                    {
 
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)
 
1419
                      {
 
1420
                      TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
 
1421
                      TIFFError ("For valid options type", "tiffcrop -h");
 
1422
                      exit (-1);
 
1423
                      }
 
1424
                    }
 
1425
                /*  check for remaining elements over MAX_REGIONS */
 
1426
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
 
1427
                  {
 
1428
                  TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
 
1429
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1430
                  exit (-1);;
 
1431
                  }
 
1432
                break;
 
1433
      /* options for file open modes */
 
1434
      case 'B': *mp++ = 'b'; *mp = '\0';
 
1435
                break;
 
1436
      case 'L': *mp++ = 'l'; *mp = '\0';
 
1437
                break;
 
1438
      case 'M': *mp++ = 'm'; *mp = '\0';
 
1439
                break;
 
1440
      case 'C': *mp++ = 'c'; *mp = '\0';
 
1441
                break;
 
1442
      /* options for Debugging / data dump */
 
1443
      case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
 
1444
                    (opt_ptr != NULL);
 
1445
                    (opt_ptr = strtok (NULL, ",")), i++)
 
1446
                    {
 
1447
                    opt_offset = strpbrk(opt_ptr, ":=");
 
1448
                    /*
 
1449
                    opt_offset = strchr(opt_ptr, ':');
 
1450
                    */
 
1451
                    if (opt_offset == NULL)
 
1452
                      {
 
1453
                      TIFFError("Invalid dump option", "%s", optarg);
 
1454
                      TIFFError ("For valid options type", "tiffcrop -h");
 
1455
                      exit (-1);
 
1456
                      }
 
1457
                      
 
1458
                    *opt_offset = '\0';
 
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)
 
1465
                      {
 
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)
 
1472
                        {
 
1473
                        dump->format = DUMP_TEXT;
 
1474
                        strcpy (dump->mode, "w");
 
1475
                        }
 
1476
                      else
 
1477
                        {
 
1478
                        if (strncmp(opt_offset + 1, "raw", 3) == 0)
 
1479
                          {
 
1480
                          dump->format = DUMP_RAW;
 
1481
                          strcpy (dump->mode, "wb");
 
1482
                          }
 
1483
                        else
 
1484
                          {
 
1485
                          TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
 
1486
                          TIFFError ("For valid options type", "tiffcrop -h");
 
1487
                          exit (-1);
 
1488
                          }
 
1489
                        }
 
1490
                      }
 
1491
                    else
 
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);
 
1503
                      }
 
1504
                    }
 
1505
                if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
 
1506
                  {
 
1507
                  if (dump->level == 1)
 
1508
                    TIFFError("","Defaulting to dump level 1, no data.");
 
1509
                  if (dump->format == DUMP_NONE)
 
1510
                    {
 
1511
                    TIFFError("", "You must specify a dump format for dump files");
 
1512
                    TIFFError ("For valid options type", "tiffcrop -h");
 
1513
                    exit (-1);
 
1514
                    }
 
1515
                  }
 
1516
                break;
 
1517
 
 
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++)
 
1525
                    {
 
1526
                    crop_data->margins[i] = atof(opt_ptr);
 
1527
                    }
 
1528
                break;
 
1529
      case 'E': /* edge reference */
 
1530
                switch (tolower(optarg[0]))
 
1531
                  {
 
1532
                  case 't': crop_data->edge_ref = EDGE_TOP;
 
1533
                            break;
 
1534
                  case 'b': crop_data->edge_ref = EDGE_BOTTOM;
 
1535
                             break;
 
1536
                  case 'l': crop_data->edge_ref = EDGE_LEFT;
 
1537
                            break;
 
1538
                  case 'r': crop_data->edge_ref = EDGE_RIGHT;
 
1539
                            break;
 
1540
                  default:  TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
 
1541
                            TIFFError ("For valid options type", "tiffcrop -h");
 
1542
                            exit (-1);
 
1543
                  }
 
1544
                break;
 
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]))
 
1548
                  {
 
1549
                  case  'h': crop_data->mirror = MIRROR_HORIZ;
 
1550
                             break;
 
1551
                  case  'v': crop_data->mirror = MIRROR_VERT;
 
1552
                             break;
 
1553
                  case  'b': crop_data->mirror = MIRROR_BOTH;
 
1554
                             break;
 
1555
                  default:   TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
 
1556
                             TIFFError ("For valid options type", "tiffcrop -h");
 
1557
                             exit (-1);
 
1558
                  }
 
1559
                break;
 
1560
      case 'H': /* set horizontal resolution to new value */
 
1561
                page->hres = atof (optarg);
 
1562
                page->mode |= PAGE_MODE_RESOLUTION;
 
1563
                break;
 
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"))
 
1568
                  {
 
1569
                  crop_data->photometric = PHOTOMETRIC_MINISBLACK;
 
1570
                  continue;
 
1571
                  }
 
1572
                if (streq(optarg, "white"))
 
1573
                  {
 
1574
                  crop_data->photometric = PHOTOMETRIC_MINISWHITE;
 
1575
                  continue;
 
1576
                  }
 
1577
                if (streq(optarg, "data")) 
 
1578
                  {
 
1579
                  crop_data->photometric = INVERT_DATA_ONLY;
 
1580
                  continue;
 
1581
                  }
 
1582
                if (streq(optarg, "both"))
 
1583
                  {
 
1584
                  crop_data->photometric = INVERT_DATA_AND_TAG;
 
1585
                  continue;
 
1586
                  }
 
1587
 
 
1588
                TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
 
1589
                TIFFError ("For valid options type", "tiffcrop -h");
 
1590
                exit (-1);
 
1591
                break;
 
1592
      case 'J': /* horizontal margin for sectioned ouput pages */ 
 
1593
                page->hmargin = atof(optarg);
 
1594
                page->mode |= PAGE_MODE_MARGINS;
 
1595
                break;
 
1596
      case 'K': /* vertical margin for sectioned ouput pages*/ 
 
1597
                page->vmargin = atof(optarg);
 
1598
                page->mode |= PAGE_MODE_MARGINS;
 
1599
                break;
 
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.
 
1609
                        */
 
1610
                     if (streq(opt_ptr, "odd"))
 
1611
                       {
 
1612
                       for (j = 1; j <= MAX_IMAGES; j += 2)
 
1613
                         imagelist[i++] = j;
 
1614
                       *image_count = (MAX_IMAGES - 1) / 2;
 
1615
                       break;
 
1616
                       }
 
1617
                     else
 
1618
                       {
 
1619
                       if (streq(opt_ptr, "even"))
 
1620
                         {
 
1621
                         for (j = 2; j <= MAX_IMAGES; j += 2)
 
1622
                           imagelist[i++] = j;
 
1623
                         *image_count = MAX_IMAGES / 2;
 
1624
                         break;
 
1625
                         }
 
1626
                       else
 
1627
                         {
 
1628
                         if (streq(opt_ptr, "last"))
 
1629
                           imagelist[i++] = MAX_IMAGES;
 
1630
                         else  /* single value between commas */
 
1631
                           {
 
1632
                           sep = strpbrk(opt_ptr, ":-");
 
1633
                           if (!sep)
 
1634
                             imagelist[i++] = atoi(opt_ptr) - 1;
 
1635
                           else
 
1636
                             {
 
1637
                             *sep = '\0';
 
1638
                             start = atoi (opt_ptr);
 
1639
                             if (!strcmp((sep + 1), "last"))
 
1640
                               end = MAX_IMAGES;
 
1641
                             else
 
1642
                               end = atoi (sep + 1);
 
1643
                             for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
 
1644
                               imagelist[i++] = j - 1;
 
1645
                             }
 
1646
                           }
 
1647
                         }
 
1648
                      }
 
1649
                    }
 
1650
                *image_count = i;
 
1651
                break;
 
1652
      case 'O': /* page orientation */ 
 
1653
                switch (tolower(optarg[0]))
 
1654
                  {
 
1655
                  case  'a': page->orient = ORIENTATION_AUTO;
 
1656
                             break;
 
1657
                  case  'p': page->orient = ORIENTATION_PORTRAIT;
 
1658
                             break;
 
1659
                  case  'l': page->orient = ORIENTATION_LANDSCAPE;
 
1660
                             break;
 
1661
                  default:  TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
 
1662
                            TIFFError ("For valid options type", "tiffcrop -h");
 
1663
                            exit (-1);
 
1664
                  }
 
1665
                break;
 
1666
      case 'P': /* page size selection */ 
 
1667
                if (get_page_geometry (optarg, page))
 
1668
                  {
 
1669
                  if (!strcmp(optarg, "list"))
 
1670
                    {
 
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);
 
1676
                    exit (-1);                   
 
1677
                    }
 
1678
     
 
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);
 
1686
                  exit (-1);
 
1687
                  }
 
1688
                else
 
1689
                  {
 
1690
                  page->mode |= PAGE_MODE_PAPERSIZE;
 
1691
                  }
 
1692
                break;
 
1693
      case 'R': /* rotate image or cropped segment */
 
1694
                crop_data->crop_mode |= CROP_ROTATE;
 
1695
                switch (strtoul(optarg, NULL, 0))
 
1696
                  {
 
1697
                  case  90:  crop_data->rotation = (uint16)90;
 
1698
                             break;
 
1699
                  case  180: crop_data->rotation = (uint16)180;
 
1700
                             break;
 
1701
                  case  270: crop_data->rotation = (uint16)270;
 
1702
                             break;
 
1703
                  default:   TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
 
1704
                             TIFFError ("For valid options type", "tiffcrop -h");
 
1705
                             exit (-1);
 
1706
                  }
 
1707
                break;
 
1708
      case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
 
1709
                sep = strpbrk(optarg, ",:");
 
1710
                if (sep)
 
1711
                  {
 
1712
                  *sep = '\0';
 
1713
                  page->cols = atoi(optarg);
 
1714
                  page->rows = atoi(sep +1);
 
1715
                  }
 
1716
                else
 
1717
                  {
 
1718
                  page->cols = atoi(optarg);
 
1719
                  page->rows = atoi(optarg);
 
1720
                  }
 
1721
                if ((page->cols * page->rows) > MAX_SECTIONS)
 
1722
                  {
 
1723
                  TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
 
1724
                  exit (-1);
 
1725
                  }
 
1726
                page->mode |= PAGE_MODE_ROWSCOLS;
 
1727
                break;
 
1728
      case 'U': /* units for measurements and offsets */
 
1729
                if (streq(optarg, "in"))
 
1730
                  {
 
1731
                  crop_data->res_unit = RESUNIT_INCH;
 
1732
                  page->res_unit = RESUNIT_INCH;
 
1733
                  }
 
1734
                else if (streq(optarg, "cm"))
 
1735
                  {
 
1736
                  crop_data->res_unit = RESUNIT_CENTIMETER;
 
1737
                  page->res_unit = RESUNIT_CENTIMETER;
 
1738
                  }
 
1739
                else if (streq(optarg, "px"))
 
1740
                  {
 
1741
                  crop_data->res_unit = RESUNIT_NONE;
 
1742
                  page->res_unit = RESUNIT_NONE;
 
1743
                  }
 
1744
                else
 
1745
                  {
 
1746
                  TIFFError ("Illegal unit of measure","%s", optarg);
 
1747
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1748
                  exit (-1);
 
1749
                  }
 
1750
                break;
 
1751
      case 'V': /* set vertical resolution to new value */
 
1752
                page->vres = atof (optarg);
 
1753
                page->mode |= PAGE_MODE_RESOLUTION;
 
1754
                break;
 
1755
      case 'X': /* selection width */
 
1756
                crop_data->crop_mode |= CROP_WIDTH;
 
1757
                crop_data->width = atof(optarg);
 
1758
                break;
 
1759
      case 'Y': /* selection length */
 
1760
                crop_data->crop_mode |= CROP_LENGTH;
 
1761
                crop_data->length = atof(optarg);
 
1762
                break;
 
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++)
 
1768
                    {
 
1769
                    crop_data->zones++;
 
1770
                    opt_offset = strchr(opt_ptr, ':');
 
1771
                    *opt_offset = '\0';
 
1772
                    crop_data->zonelist[i].position = atoi(opt_ptr);
 
1773
                    crop_data->zonelist[i].total    = atoi(opt_offset + 1);
 
1774
                    }
 
1775
                /*  check for remaining elements over MAX_REGIONS */
 
1776
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
 
1777
                  {
 
1778
                  TIFFError("Zone list exceeds region limit", "%d",  MAX_REGIONS);
 
1779
                  exit (-1);
 
1780
                  }
 
1781
                break;
 
1782
    case '?':   TIFFError ("For valid options type", "tiffcrop -h");
 
1783
                exit (-1);
 
1784
                /*NOTREACHED*/
 
1785
      }
 
1786
    }
 
1787
  }  /* end process_command_opts */
 
1788
 
 
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.
 
1792
 */
 
1793
static int 
 
1794
update_output_file (TIFF **tiffout, char *mode, int autoindex,
 
1795
                    char *outname, unsigned int *page)
 
1796
  {
 
1797
  static int findex = 0;    /* file sequence indicator */
 
1798
  char  *sep;
 
1799
  char   filenum[16];
 
1800
  char   export_ext[16];
 
1801
  char   exportname[PATH_MAX];
 
1802
 
 
1803
  strcpy (export_ext, ".tiff");
 
1804
  if (autoindex && (*tiffout != NULL))
 
1805
    {   
 
1806
    /* Close any export file that was previously opened */
 
1807
    TIFFClose (*tiffout);
 
1808
    *tiffout = NULL;
 
1809
    }
 
1810
 
 
1811
  strncpy (exportname, outname, PATH_MAX - 15);
 
1812
  if (*tiffout == NULL)   /* This is a new export file */
 
1813
    {
 
1814
    if (autoindex)
 
1815
      { /* create a new filename for each export */
 
1816
      findex++;
 
1817
      if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
 
1818
        {
 
1819
        strncpy (export_ext, sep, 5);
 
1820
        *sep = '\0';
 
1821
        }
 
1822
      else
 
1823
        strncpy (export_ext, ".tiff", 5);
 
1824
      export_ext[5] = '\0';
 
1825
 
 
1826
      sprintf (filenum, "-%03d%s", findex, export_ext);
 
1827
      filenum[15] = '\0';
 
1828
      strncat (exportname, filenum, 14);
 
1829
      }
 
1830
 
 
1831
    *tiffout = TIFFOpen(exportname, mode);
 
1832
    if (*tiffout == NULL)
 
1833
      {
 
1834
      TIFFError("update_output_file", "Unable to open output file %s\n", exportname);
 
1835
      return (1);
 
1836
      }
 
1837
    *page = 0; 
 
1838
 
 
1839
    return (0);
 
1840
    }
 
1841
  else 
 
1842
    (*page)++;
 
1843
 
 
1844
  return (0);
 
1845
  } /* end update_output_file */
 
1846
 
 
1847
 
 
1848
int
 
1849
main(int argc, char* argv[])
 
1850
  {
 
1851
  uint16 defconfig = (uint16) -1;
 
1852
  uint16 deffillorder = 0;
 
1853
  uint32 deftilewidth = (uint32) -1;
 
1854
  uint32 deftilelength = (uint32) -1;
 
1855
  uint32 defrowsperstrip = (uint32) 0;
 
1856
  uint32 dirnum = 0;
 
1857
 
 
1858
  TIFF *in = NULL;
 
1859
  TIFF *out = NULL;
 
1860
  char  mode[10];
 
1861
  char *mp = mode;
 
1862
 
 
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;
 
1882
  int    seg, length;
 
1883
  char   temp_filename[PATH_MAX + 1];
 
1884
  memset (temp_filename, '\0', PATH_MAX + 1);              
 
1885
  little_endian = *((unsigned char *)&little_endian) & '1';
 
1886
 
 
1887
  initImageData(&image);
 
1888
  initCropMasks(&crop);
 
1889
  initPageSetup(&page, sections, seg_buffs);
 
1890
  initDumpOptions(&dump);
 
1891
 
 
1892
  process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig, 
 
1893
                        &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
 
1894
                        &crop, &page, &dump, imagelist, &image_count);
 
1895
 
 
1896
  if (argc - optind < 2)
 
1897
    usage();
 
1898
 
 
1899
  if ((argc - optind) == 2)
 
1900
    pageNum = -1;
 
1901
  else
 
1902
    total_images = 0;
 
1903
  /* read multiple input files and write to output file(s) */
 
1904
  while (optind < argc - 1)
 
1905
    {
 
1906
    in = TIFFOpen (argv[optind], "r");
 
1907
    if (in == NULL)
 
1908
      return (-3);
 
1909
 
 
1910
    /* If only one input file is specified, we can use directory count */
 
1911
    total_images = TIFFNumberOfDirectories(in); 
 
1912
    if (image_count == 0)
 
1913
      {
 
1914
      dirnum = 0;
 
1915
      total_pages = total_images; /* Only valid with single input file */
 
1916
      }
 
1917
    else
 
1918
      {
 
1919
      dirnum = (tdir_t)(imagelist[next_image] - 1);
 
1920
      next_image++;
 
1921
 
 
1922
      /* Total pages only valid for enumerated list of pages not derived
 
1923
       * using odd, even, or last keywords.
 
1924
       */
 
1925
      if (image_count >  total_images)
 
1926
        image_count = total_images;
 
1927
      
 
1928
      total_pages = image_count;
 
1929
      }
 
1930
 
 
1931
    /* MAX_IMAGES is used for special case "last" in selection list */
 
1932
    if (dirnum == (MAX_IMAGES - 1))
 
1933
      dirnum = total_images - 1;
 
1934
 
 
1935
    if (dirnum > (total_images))
 
1936
      {
 
1937
      TIFFError (TIFFFileName(in), 
 
1938
      "Invalid image number %d, File contains only %d images", 
 
1939
                 (int)dirnum + 1, total_images);
 
1940
      if (out != NULL)
 
1941
        (void) TIFFClose(out);
 
1942
      return (1);
 
1943
      }
 
1944
 
 
1945
    if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
 
1946
      {
 
1947
      TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
 
1948
      if (out != NULL)
 
1949
        (void) TIFFClose(out);
 
1950
      return (1);
 
1951
      }
 
1952
 
 
1953
    end_of_input = FALSE;
 
1954
    while (end_of_input == FALSE)
 
1955
      {
 
1956
      config = defconfig;
 
1957
      compression = defcompression;
 
1958
      predictor = defpredictor;
 
1959
      fillorder = deffillorder;
 
1960
      rowsperstrip = defrowsperstrip;
 
1961
      tilewidth = deftilewidth;
 
1962
      tilelength = deftilelength;
 
1963
      g3opts = defg3opts;
 
1964
 
 
1965
      if (dump.format != DUMP_NONE)
 
1966
        {
 
1967
        /* manage input and/or output dump files here */
 
1968
        dump_images++;
 
1969
        length = strlen(dump.infilename);
 
1970
        if (length > 0)
 
1971
          {
 
1972
          if (dump.infile != NULL)
 
1973
            fclose (dump.infile);
 
1974
 
 
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)
 
1978
            {
 
1979
            TIFFError ("Unable to open dump file %s for writing", temp_filename);
 
1980
            exit (-1);
 
1981
            }
 
1982
          dump_info(dump.infile, dump.format, "Reading image","%d from %s", 
 
1983
                    dump_images, TIFFFileName(in));
 
1984
          } 
 
1985
        length = strlen(dump.outfilename);
 
1986
        if (length > 0)
 
1987
          {
 
1988
          if (dump.outfile != NULL)
 
1989
            fclose (dump.outfile);
 
1990
 
 
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)
 
1994
            {
 
1995
            TIFFError ("Unable to open dump file %s for writing", temp_filename);
 
1996
            exit (-1);
 
1997
            }
 
1998
          dump_info(dump.outfile, dump.format, "Writing image","%d from %s", 
 
1999
                    dump_images, TIFFFileName(in));
 
2000
          } 
 
2001
        }
 
2002
 
 
2003
      if (dump.debug)
 
2004
         TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
 
2005
 
 
2006
      if (loadImage(in, &image, &dump, &read_buff))
 
2007
        {
 
2008
        TIFFError("main", "Unable to load source image");
 
2009
        exit (-1);
 
2010
        }
 
2011
 
 
2012
      /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
 
2013
       */
 
2014
      if (image.adjustments != 0)
 
2015
        {
 
2016
        if (correct_orientation(&image, &read_buff))
 
2017
            TIFFError("main", "Unable to correct image orientation");
 
2018
        }
 
2019
 
 
2020
      if (getCropOffsets(&image, &crop, &dump))
 
2021
        {
 
2022
        TIFFError("main", "Unable to define crop regions");
 
2023
        exit (-1);
 
2024
        }
 
2025
 
 
2026
      if (crop.selections > 0)
 
2027
        {
 
2028
        if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
 
2029
          {
 
2030
          TIFFError("main", "Unable to process image selections");
 
2031
          exit (-1);
 
2032
          }
 
2033
        }
 
2034
      else  /* Single image segment without zones or regions */
 
2035
        {
 
2036
        if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
 
2037
          {
 
2038
          TIFFError("main", "Unable to create output image");
 
2039
          exit (-1);
 
2040
          }
 
2041
        }
 
2042
      if (page.mode == PAGE_MODE_NONE)
 
2043
        {  /* Whole image or sections not based on output page size */
 
2044
        if (crop.selections > 0)
 
2045
          {
 
2046
          writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
 
2047
                          mp, argv[argc - 1], &next_page, total_pages);
 
2048
          }
 
2049
        else  /* One file all images and sections */
 
2050
          {
 
2051
          if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
 
2052
                                  &next_page))
 
2053
             exit (1);
 
2054
          if (writeCroppedImage(in, out, &image, &dump,crop.combined_width, 
 
2055
                                crop.combined_length, crop_buff, next_page, total_pages))
 
2056
            {
 
2057
             TIFFError("main", "Unable to write new image");
 
2058
             exit (-1);
 
2059
            }
 
2060
          }
 
2061
        }
 
2062
      else
 
2063
        {
 
2064
        /* If we used a crop buffer, our data is there, otherwise it is
 
2065
         * in the read_buffer
 
2066
         */
 
2067
        if (crop_buff != NULL)  
 
2068
          sect_src = crop_buff;
 
2069
        else
 
2070
          sect_src = read_buff;
 
2071
        /* Break input image into pages or rows and columns */
 
2072
        if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
 
2073
          {
 
2074
          TIFFError("main", "Unable to compute output section data");
 
2075
          exit (-1);
 
2076
          }
 
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.
 
2079
         */
 
2080
        if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
 
2081
          exit (1);
 
2082
 
 
2083
        if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, &sect_buff))
 
2084
          {
 
2085
          TIFFError("main", "Unable to write image sections");
 
2086
          exit (-1);
 
2087
          }
 
2088
        }
 
2089
 
 
2090
      /* No image list specified, just read the next image */
 
2091
      if (image_count == 0)
 
2092
        dirnum++;
 
2093
      else
 
2094
        {
 
2095
        dirnum = (tdir_t)(imagelist[next_image] - 1);
 
2096
        next_image++;
 
2097
        }
 
2098
 
 
2099
      if (dirnum == MAX_IMAGES - 1)
 
2100
        dirnum = TIFFNumberOfDirectories(in) - 1;
 
2101
 
 
2102
      if (!TIFFSetDirectory(in, (tdir_t)dirnum))
 
2103
        end_of_input = TRUE;
 
2104
      }
 
2105
    TIFFClose(in);
 
2106
    optind++;
 
2107
    }
 
2108
 
 
2109
  /* If we did not use the read buffer as the crop buffer */
 
2110
  if (read_buff)
 
2111
    _TIFFfree(read_buff);
 
2112
 
 
2113
  if (crop_buff)
 
2114
    _TIFFfree(crop_buff);
 
2115
 
 
2116
  if (sect_buff)
 
2117
    _TIFFfree(sect_buff);
 
2118
 
 
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);
 
2122
 
 
2123
  if (dump.format != DUMP_NONE)
 
2124
    {
 
2125
    if (dump.infile != NULL)
 
2126
     fclose (dump.infile);
 
2127
 
 
2128
    if (dump.outfile != NULL)
 
2129
      {
 
2130
      dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
 
2131
      fclose (dump.outfile);
 
2132
      }
 
2133
    }
 
2134
 
 
2135
  TIFFClose(out);
 
2136
 
 
2137
  return (0);
 
2138
  } /* end main */
 
2139
 
 
2140
 
 
2141
/* Debugging functions */
 
2142
static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
 
2143
  {
 
2144
  int j, k;
 
2145
  uint32 i;
 
2146
  char  dump_array[10];
 
2147
  unsigned char bitset;
 
2148
 
 
2149
  if (dumpfile == NULL)
 
2150
    {
 
2151
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2152
    return (1);
 
2153
    }
 
2154
 
 
2155
  if (format == DUMP_TEXT)
 
2156
    {
 
2157
    fprintf (dumpfile," %s  ", dump_tag);
 
2158
    for (i = 0; i < count; i++)
 
2159
      {
 
2160
      for (j = 0, k = 7; j < 8; j++, k--)
 
2161
        {
 
2162
        bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
 
2163
        sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2164
        }
 
2165
      dump_array[8] = '\0';
 
2166
      fprintf (dumpfile," %s", dump_array);
 
2167
      }
 
2168
    fprintf (dumpfile,"\n");
 
2169
    }
 
2170
  else
 
2171
    {
 
2172
    if ((fwrite (data, 1, count, dumpfile)) != count)
 
2173
      {
 
2174
      TIFFError ("", "Unable to write binary data to dump file\n");
 
2175
      return (1);
 
2176
      }
 
2177
    }
 
2178
 
 
2179
  return (0);
 
2180
  }
 
2181
 
 
2182
static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
 
2183
  {
 
2184
  int j, k;
 
2185
  char  dump_array[10];
 
2186
  unsigned char bitset;
 
2187
 
 
2188
  if (dumpfile == NULL)
 
2189
    {
 
2190
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2191
    return (1);
 
2192
    }
 
2193
 
 
2194
  if (format == DUMP_TEXT)
 
2195
    {
 
2196
    fprintf (dumpfile," %s  ", dump_tag);
 
2197
    for (j = 0, k = 7; j < 8; j++, k--)
 
2198
      {
 
2199
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
 
2200
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2201
      }
 
2202
    dump_array[8] = '\0';
 
2203
    fprintf (dumpfile," %s\n", dump_array);
 
2204
    }
 
2205
  else
 
2206
    {
 
2207
    if ((fwrite (&data, 1, 1, dumpfile)) != 1)
 
2208
      {
 
2209
      TIFFError ("", "Unable to write binary data to dump file\n");
 
2210
      return (1);
 
2211
      }
 
2212
    }
 
2213
 
 
2214
  return (0);
 
2215
  }
 
2216
 
 
2217
static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
 
2218
  {
 
2219
  int j, k;
 
2220
  char  dump_array[20];
 
2221
  unsigned char bitset;
 
2222
 
 
2223
  if (dumpfile == NULL)
 
2224
    {
 
2225
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2226
    return (1);
 
2227
    }
 
2228
 
 
2229
  if (format == DUMP_TEXT)
 
2230
    {
 
2231
    fprintf (dumpfile," %s  ", dump_tag);
 
2232
    for (j = 0, k = 15; k >= 0; j++, k--)
 
2233
      {
 
2234
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
 
2235
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2236
      if ((k % 8) == 0)
 
2237
          sprintf(&dump_array[++j], " ");
 
2238
      }
 
2239
    dump_array[17] = '\0';
 
2240
    fprintf (dumpfile," %s\n", dump_array);
 
2241
    }
 
2242
  else
 
2243
    {
 
2244
    if ((fwrite (&data, 2, 1, dumpfile)) != 2)
 
2245
      {
 
2246
      TIFFError ("", "Unable to write binary data to dump file\n");
 
2247
      return (1);
 
2248
      }
 
2249
    }
 
2250
 
 
2251
  return (0);
 
2252
  }
 
2253
 
 
2254
static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
 
2255
  {
 
2256
  int j, k;
 
2257
  char  dump_array[40];
 
2258
  unsigned char bitset;
 
2259
 
 
2260
  if (dumpfile == NULL)
 
2261
    {
 
2262
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2263
    return (1);
 
2264
    }
 
2265
 
 
2266
  if (format == DUMP_TEXT)
 
2267
    {
 
2268
    fprintf (dumpfile," %s  ", dump_tag);
 
2269
    for (j = 0, k = 31; k >= 0; j++, k--)
 
2270
      {
 
2271
      bitset = data & (((uint32)1 << k)) ? 1 : 0;
 
2272
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2273
      if ((k % 8) == 0)
 
2274
          sprintf(&dump_array[++j], " ");
 
2275
      }
 
2276
    dump_array[35] = '\0';
 
2277
    fprintf (dumpfile," %s\n", dump_array);
 
2278
    }
 
2279
  else
 
2280
    {
 
2281
    if ((fwrite (&data, 4, 1, dumpfile)) != 4)
 
2282
      {
 
2283
      TIFFError ("", "Unable to write binary data to dump file\n");
 
2284
      return (1);
 
2285
      }
 
2286
    }
 
2287
  return (0);
 
2288
  }
 
2289
 
 
2290
static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
 
2291
  {
 
2292
  int j, k;
 
2293
  char  dump_array[80];
 
2294
  unsigned char bitset;
 
2295
 
 
2296
  if (dumpfile == NULL)
 
2297
    {
 
2298
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2299
    return (1);
 
2300
    }
 
2301
 
 
2302
  if (format == DUMP_TEXT)
 
2303
    {
 
2304
    fprintf (dumpfile," %s  ", dump_tag);
 
2305
    for (j = 0, k = 63; k >= 0; j++, k--)
 
2306
      {
 
2307
      bitset = data & (((uint64)1 << k)) ? 1 : 0;
 
2308
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2309
      if ((k % 8) == 0)
 
2310
          sprintf(&dump_array[++j], " ");
 
2311
      }
 
2312
    dump_array[71] = '\0';
 
2313
    fprintf (dumpfile," %s\n", dump_array);
 
2314
    }
 
2315
  else
 
2316
    {
 
2317
    if ((fwrite (&data, 8, 1, dumpfile)) != 8)
 
2318
      {
 
2319
      TIFFError ("", "Unable to write binary data to dump file\n");
 
2320
      return (1);
 
2321
      }
 
2322
    }
 
2323
 
 
2324
  return (0);
 
2325
  }
 
2326
 
 
2327
static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
 
2328
  {
 
2329
  if (format == DUMP_TEXT)
 
2330
    {
 
2331
    va_list ap;
 
2332
    va_start(ap, msg);
 
2333
    fprintf(dumpfile, "%s ", prefix);
 
2334
    vfprintf(dumpfile, msg, ap);
 
2335
    fprintf(dumpfile, "\n");
 
2336
    }
 
2337
  }
 
2338
 
 
2339
static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width, 
 
2340
                 uint32 row, unsigned char *buff)
 
2341
  {
 
2342
  int j, k;
 
2343
  uint32 i;
 
2344
  unsigned char * dump_ptr;
 
2345
 
 
2346
  if (dumpfile == NULL)
 
2347
    {
 
2348
    TIFFError ("", "Invalid FILE pointer for dump file\n");
 
2349
    return (1);
 
2350
    }
 
2351
 
 
2352
  for (i = 0; i < rows; i++)
 
2353
    {
 
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);
 
2359
     
 
2360
    for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
 
2361
      dump_data (dumpfile, format, "", dump_ptr, 10);
 
2362
    if (k > 0)
 
2363
      dump_data (dumpfile, format, "", dump_ptr, k);
 
2364
    }
 
2365
  return (0);
 
2366
  }
 
2367
 
 
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.
 
2372
 */
 
2373
 
 
2374
static int 
 
2375
extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols, 
 
2376
                           tsample_t sample, uint16 spp, uint16 bps, 
 
2377
                           tsample_t count, uint32 start, uint32 end)
 
2378
  {
 
2379
  int i, bytes_per_sample, sindex;
 
2380
  uint32 col, dst_rowsize, bit_offset;
 
2381
  uint32 src_byte, src_bit;
 
2382
  uint8 *src = in;
 
2383
  uint8 *dst = out;
 
2384
 
 
2385
  if ((src == NULL) || (dst == NULL))
 
2386
    {
 
2387
    TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
 
2388
    return (1);
 
2389
    }
 
2390
 
 
2391
  if ((start > end) || (start > cols))
 
2392
    {
 
2393
    TIFFError ("extractContigSamplesBytes", 
 
2394
               "Invalid start column value %d ignored", start);
 
2395
    start = 0;
 
2396
    }
 
2397
  if ((end == 0) || (end > cols))
 
2398
    {
 
2399
    TIFFError ("extractContigSamplesBytes", 
 
2400
               "Invalid end column value %d ignored", end);
 
2401
    end = cols;
 
2402
    }
 
2403
 
 
2404
  dst_rowsize = (bps * (end - start) * count) / 8;
 
2405
 
 
2406
  bytes_per_sample = (bps + 7) / 8; 
 
2407
  /* Optimize case for copying all samples */
 
2408
  if (count == spp)
 
2409
    {
 
2410
    src = in + (start * spp * bytes_per_sample);
 
2411
    _TIFFmemcpy (dst, src, dst_rowsize);
 
2412
    }
 
2413
  else
 
2414
    {
 
2415
    for (col = start; col < end; col++)
 
2416
      {
 
2417
      for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
2418
        {
 
2419
        bit_offset = col * bps * spp;
 
2420
        if (sindex == 0)
 
2421
          {
 
2422
          src_byte = bit_offset / 8;
 
2423
          src_bit  = bit_offset % 8;
 
2424
          }
 
2425
        else
 
2426
          {
 
2427
          src_byte = (bit_offset + (sindex * bps)) / 8;
 
2428
          src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2429
          }
 
2430
        src = in + src_byte;
 
2431
        for (i = 0; i < bytes_per_sample; i++)
 
2432
            *dst++ = *src++;
 
2433
        }
 
2434
      }
 
2435
    }
 
2436
 
 
2437
  return (0);
 
2438
  } /* end extractContigSamplesBytes */
 
2439
 
 
2440
static int
 
2441
extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
 
2442
                           tsample_t sample, uint16 spp, uint16 bps, 
 
2443
                           tsample_t count, uint32 start, uint32 end)
 
2444
  {
 
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;
 
2449
  uint8 *src = in;
 
2450
  uint8 *dst = out;
 
2451
 
 
2452
  if ((src == NULL) || (dst == NULL))
 
2453
    {
 
2454
    TIFFError("extractContigSamples8bits","Invalid input or output buffer");
 
2455
    return (1);
 
2456
    }
 
2457
 
 
2458
  if ((start > end) || (start > cols))
 
2459
    {
 
2460
    TIFFError ("extractContigSamples8bits", 
 
2461
               "Invalid start column value %d ignored", start);
 
2462
    start = 0;
 
2463
    }
 
2464
  if ((end == 0) || (end > cols))
 
2465
    {
 
2466
    TIFFError ("extractContigSamples8bits", 
 
2467
               "Invalid end column value %d ignored", end);
 
2468
    end = cols;
 
2469
    }
 
2470
  
 
2471
  ready_bits = 0;
 
2472
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
2473
  buff1 = buff2 = 0;
 
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++)
 
2478
      {
 
2479
      if (sindex == 0)
 
2480
        {
 
2481
        src_byte = bit_offset / 8;
 
2482
        src_bit  = bit_offset % 8;
 
2483
        }
 
2484
      else
 
2485
        {
 
2486
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2487
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2488
        }
 
2489
 
 
2490
      src = in + src_byte;
 
2491
      matchbits = maskbits << (8 - src_bit - bps); 
 
2492
      buff1 = ((*src) & matchbits) << (src_bit);
 
2493
 
 
2494
      /* If we have a full buffer's worth, write it out */
 
2495
      if (ready_bits >= 8)
 
2496
        {
 
2497
        *dst++ = buff2;
 
2498
        buff2 = buff1;
 
2499
        ready_bits -= 8;
 
2500
        }
 
2501
      else
 
2502
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2503
      ready_bits += bps;
 
2504
      }
 
2505
    }
 
2506
 
 
2507
  while (ready_bits > 0)
 
2508
    {
 
2509
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
2510
    *dst++ = buff1;
 
2511
    ready_bits -= 8;
 
2512
    }
 
2513
 
 
2514
  return (0);
 
2515
  } /* end extractContigSamples8bits */
 
2516
 
 
2517
static int
 
2518
extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols, 
 
2519
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2520
                            tsample_t count, uint32 start, uint32 end)
 
2521
  {
 
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;
 
2526
  uint8  bytebuff = 0;
 
2527
  uint8 *src = in;
 
2528
  uint8 *dst = out;
 
2529
  unsigned char swapbuff[2];
 
2530
 
 
2531
  if ((src == NULL) || (dst == NULL))
 
2532
    {
 
2533
    TIFFError("extractContigSamples16bits","Invalid input or output buffer");
 
2534
    return (1);
 
2535
    }
 
2536
 
 
2537
  if ((start > end) || (start > cols))
 
2538
    {
 
2539
    TIFFError ("extractContigSamples16bits", 
 
2540
               "Invalid start column value %d ignored", start);
 
2541
    start = 0;
 
2542
    }
 
2543
  if ((end == 0) || (end > cols))
 
2544
    {
 
2545
    TIFFError ("extractContigSamples16bits", 
 
2546
               "Invalid end column value %d ignored", end);
 
2547
    end = cols;
 
2548
    }
 
2549
 
 
2550
  ready_bits = 0;
 
2551
  maskbits = (uint16)-1 >> (16 - bps);
 
2552
 
 
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++)
 
2557
      {
 
2558
      if (sindex == 0)
 
2559
        {
 
2560
        src_byte = bit_offset / 8;
 
2561
        src_bit  = bit_offset % 8;
 
2562
        }
 
2563
      else
 
2564
        {
 
2565
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2566
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2567
        }
 
2568
 
 
2569
      src = in + src_byte;
 
2570
      matchbits = maskbits << (16 - src_bit - bps); 
 
2571
      if (little_endian)
 
2572
        {
 
2573
        swapbuff[1] = *src;
 
2574
        swapbuff[0] = *(src + 1);
 
2575
        }
 
2576
      else
 
2577
        {
 
2578
        swapbuff[0] = *src;
 
2579
        swapbuff[1] = *(src + 1);
 
2580
        }
 
2581
      buff1 = *((uint16 *)swapbuff);
 
2582
      buff1 = (buff1 & matchbits) << (src_bit);
 
2583
 
 
2584
      if (ready_bits < 8) /* add another bps bits to the buffer */
 
2585
        { 
 
2586
        bytebuff = 0;
 
2587
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2588
        }
 
2589
      else /* If we have a full buffer's worth, write it out */
 
2590
        {
 
2591
        bytebuff = (buff2 >> 8);
 
2592
        *dst++ = bytebuff;
 
2593
        ready_bits -= 8;
 
2594
        /* shift in new bits */
 
2595
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
2596
        }
 
2597
      ready_bits += bps;
 
2598
      }
 
2599
    }
 
2600
 
 
2601
  /* catch any trailing bits at the end of the line */
 
2602
  while (ready_bits > 0)
 
2603
    {
 
2604
    bytebuff = (buff2 >> 8);
 
2605
    *dst++ = bytebuff;
 
2606
    ready_bits -= 8;
 
2607
    }
 
2608
  
 
2609
  return (0);
 
2610
  } /* end extractContigSamples16bits */
 
2611
 
 
2612
 
 
2613
static int
 
2614
extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
 
2615
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2616
                            tsample_t count, uint32 start, uint32 end)
 
2617
  {
 
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;
 
2623
  uint8 *src = in;
 
2624
  uint8 *dst = out;
 
2625
  unsigned char  swapbuff[4];
 
2626
 
 
2627
  if ((in == NULL) || (out == NULL))
 
2628
    {
 
2629
    TIFFError("extractContigSamples24bits","Invalid input or output buffer");
 
2630
    return (1);
 
2631
    }
 
2632
 
 
2633
  if ((start > end) || (start > cols))
 
2634
    {
 
2635
    TIFFError ("extractContigSamples24bits", 
 
2636
               "Invalid start column value %d ignored", start);
 
2637
    start = 0;
 
2638
    }
 
2639
  if ((end == 0) || (end > cols))
 
2640
    {
 
2641
    TIFFError ("extractContigSamples24bits", 
 
2642
               "Invalid end column value %d ignored", end);
 
2643
    end = cols;
 
2644
    }
 
2645
 
 
2646
  ready_bits = 0;
 
2647
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
2648
  for (col = start; col < end; col++)
 
2649
    {
 
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++)
 
2653
      {
 
2654
      if (sindex == 0)
 
2655
        {
 
2656
        src_byte = bit_offset / 8;
 
2657
        src_bit  = bit_offset % 8;
 
2658
        }
 
2659
      else
 
2660
        {
 
2661
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2662
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2663
        }
 
2664
 
 
2665
      src = in + src_byte;
 
2666
      matchbits = maskbits << (32 - src_bit - bps); 
 
2667
      if (little_endian)
 
2668
        {
 
2669
        swapbuff[3] = *src;
 
2670
        swapbuff[2] = *(src + 1);
 
2671
        swapbuff[1] = *(src + 2);
 
2672
        swapbuff[0] = *(src + 3);
 
2673
        }
 
2674
      else
 
2675
        {
 
2676
        swapbuff[0] = *src;
 
2677
        swapbuff[1] = *(src + 1);
 
2678
        swapbuff[2] = *(src + 2);
 
2679
        swapbuff[3] = *(src + 3);
 
2680
        }
 
2681
 
 
2682
      buff1 = *((uint32 *)swapbuff);
 
2683
      buff1 = (buff1 & matchbits) << (src_bit);
 
2684
 
 
2685
      if (ready_bits < 16) /* add another bps bits to the buffer */
 
2686
        {
 
2687
        bytebuff1 = bytebuff2 = 0;
 
2688
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2689
        }
 
2690
      else /* If we have a full buffer's worth, write it out */
 
2691
        {
 
2692
        bytebuff1 = (buff2 >> 24);
 
2693
        *dst++ = bytebuff1;
 
2694
        bytebuff2 = (buff2 >> 16);
 
2695
        *dst++ = bytebuff2;
 
2696
        ready_bits -= 16;
 
2697
 
 
2698
        /* shift in new bits */
 
2699
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
2700
        }
 
2701
      ready_bits += bps;
 
2702
      }
 
2703
    }
 
2704
 
 
2705
  /* catch any trailing bits at the end of the line */
 
2706
  while (ready_bits > 0)
 
2707
    {
 
2708
    bytebuff1 = (buff2 >> 24);
 
2709
    *dst++ = bytebuff1;
 
2710
 
 
2711
    buff2 = (buff2 << 8);
 
2712
    bytebuff2 = bytebuff1;
 
2713
    ready_bits -= 8;
 
2714
    } 
 
2715
  
 
2716
  return (0);
 
2717
  } /* end extractContigSamples24bits */
 
2718
 
 
2719
static int
 
2720
extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
 
2721
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2722
                            tsample_t count, uint32 start, uint32 end)
 
2723
  {
 
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;
 
2730
  uint8 *src = in;
 
2731
  uint8 *dst = out;
 
2732
  unsigned char swapbuff1[4];
 
2733
  unsigned char swapbuff2[4];
 
2734
 
 
2735
  if ((in == NULL) || (out == NULL))
 
2736
    {
 
2737
    TIFFError("extractContigSamples32bits","Invalid input or output buffer");
 
2738
    return (1);
 
2739
    }
 
2740
 
 
2741
 
 
2742
  if ((start > end) || (start > cols))
 
2743
    {
 
2744
    TIFFError ("extractContigSamples32bits", 
 
2745
               "Invalid start column value %d ignored", start);
 
2746
    start = 0;
 
2747
    }
 
2748
  if ((end == 0) || (end > cols))
 
2749
    {
 
2750
    TIFFError ("extractContigSamples32bits", 
 
2751
               "Invalid end column value %d ignored", end);
 
2752
    end = cols;
 
2753
    }
 
2754
 
 
2755
  shift_width = ((bps + 7) / 8) + 1; 
 
2756
  ready_bits = 0;
 
2757
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
2758
  for (col = start; col < end; col++)
 
2759
    {
 
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++)
 
2763
      {
 
2764
      if (sindex == 0)
 
2765
        {
 
2766
        src_byte = bit_offset / 8;
 
2767
        src_bit  = bit_offset % 8;
 
2768
        }
 
2769
      else
 
2770
        {
 
2771
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2772
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2773
        }
 
2774
 
 
2775
      src = in + src_byte;
 
2776
      matchbits = maskbits << (64 - src_bit - bps); 
 
2777
      if (little_endian)
 
2778
        {
 
2779
        swapbuff1[3] = *src;
 
2780
        swapbuff1[2] = *(src + 1);
 
2781
        swapbuff1[1] = *(src + 2);
 
2782
        swapbuff1[0] = *(src + 3);
 
2783
        }
 
2784
      else
 
2785
        {
 
2786
        swapbuff1[0] = *src;
 
2787
        swapbuff1[1] = *(src + 1);
 
2788
        swapbuff1[2] = *(src + 2);
 
2789
        swapbuff1[3] = *(src + 3);
 
2790
        }
 
2791
      longbuff1 = *((uint32 *)swapbuff1);                  
 
2792
 
 
2793
      memset (swapbuff2, '\0', sizeof(swapbuff2));
 
2794
      if (little_endian)
 
2795
        {
 
2796
        swapbuff2[3] = *src;
 
2797
        swapbuff2[2] = *(src + 1);
 
2798
        swapbuff2[1] = *(src + 2);
 
2799
        swapbuff2[0] = *(src + 3);
 
2800
        }
 
2801
      else
 
2802
        {
 
2803
        swapbuff2[0] = *src;
 
2804
        swapbuff2[1] = *(src + 1);
 
2805
        swapbuff2[2] = *(src + 2);
 
2806
        swapbuff2[3] = *(src + 3);
 
2807
        }
 
2808
 
 
2809
      longbuff2 = *((uint32 *)swapbuff2);
 
2810
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
2811
      buff1 = (buff3 & matchbits) << (src_bit);
 
2812
 
 
2813
      /* If we have a full buffer's worth, write it out */
 
2814
      if (ready_bits >= 32)
 
2815
        {
 
2816
        bytebuff1 = (buff2 >> 56);
 
2817
        *dst++ = bytebuff1;
 
2818
        bytebuff2 = (buff2 >> 48);
 
2819
        *dst++ = bytebuff2;
 
2820
        bytebuff3 = (buff2 >> 40);
 
2821
        *dst++ = bytebuff3;
 
2822
        bytebuff4 = (buff2 >> 32);
 
2823
        *dst++ = bytebuff4;
 
2824
        ready_bits -= 32;
 
2825
                    
 
2826
        /* shift in new bits */
 
2827
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
2828
        }
 
2829
      else
 
2830
        { /* add another bps bits to the buffer */
 
2831
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
2832
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2833
        }
 
2834
      ready_bits += bps;
 
2835
      }
 
2836
    }
 
2837
  while (ready_bits > 0)
 
2838
    {
 
2839
    bytebuff1 = (buff2 >> 56);
 
2840
    *dst++ = bytebuff1;
 
2841
    buff2 = (buff2 << 8);
 
2842
    ready_bits -= 8;
 
2843
    }
 
2844
  
 
2845
  return (0);
 
2846
  } /* end extractContigSamples32bits */
 
2847
 
 
2848
static int
 
2849
extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
 
2850
                                  tsample_t sample, uint16 spp, uint16 bps, 
 
2851
                                  tsample_t count, uint32 start, uint32 end,
 
2852
                                  int shift)
 
2853
  {
 
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;
 
2858
  uint8 *src = in;
 
2859
  uint8 *dst = out;
 
2860
 
 
2861
  if ((src == NULL) || (dst == NULL))
 
2862
    {
 
2863
    TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
 
2864
    return (1);
 
2865
    }
 
2866
 
 
2867
  if ((start > end) || (start > cols))
 
2868
    {
 
2869
    TIFFError ("extractContigSamplesShifted8bits", 
 
2870
               "Invalid start column value %d ignored", start);
 
2871
    start = 0;
 
2872
    }
 
2873
  if ((end == 0) || (end > cols))
 
2874
    {
 
2875
    TIFFError ("extractContigSamplesShifted8bits", 
 
2876
               "Invalid end column value %d ignored", end);
 
2877
    end = cols;
 
2878
    }
 
2879
 
 
2880
  ready_bits = shift;
 
2881
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
2882
  buff1 = buff2 = 0;
 
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++)
 
2887
      {
 
2888
      if (sindex == 0)
 
2889
        {
 
2890
        src_byte = bit_offset / 8;
 
2891
        src_bit  = bit_offset % 8;
 
2892
        }
 
2893
      else
 
2894
        {
 
2895
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2896
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2897
        }
 
2898
 
 
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);
 
2904
 
 
2905
      /* If we have a full buffer's worth, write it out */
 
2906
      if (ready_bits >= 8)
 
2907
        {
 
2908
        *dst++ |= buff2;
 
2909
        buff2 = buff1;
 
2910
        ready_bits -= 8;
 
2911
        }
 
2912
      else
 
2913
        buff2 = buff2 | (buff1 >> ready_bits);
 
2914
      ready_bits += bps;
 
2915
      }
 
2916
    }
 
2917
 
 
2918
  while (ready_bits > 0)
 
2919
    {
 
2920
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
2921
    *dst++ = buff1;
 
2922
    ready_bits -= 8;
 
2923
    }
 
2924
 
 
2925
  return (0);
 
2926
  } /* end extractContigSamplesShifted8bits */
 
2927
 
 
2928
static int
 
2929
extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols, 
 
2930
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
2931
                                   tsample_t count, uint32 start, uint32 end,
 
2932
                                   int shift)
 
2933
  {
 
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;
 
2938
  uint8  bytebuff = 0;
 
2939
  uint8 *src = in;
 
2940
  uint8 *dst = out;
 
2941
  unsigned char swapbuff[2];
 
2942
 
 
2943
  if ((src == NULL) || (dst == NULL))
 
2944
    {
 
2945
    TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
 
2946
    return (1);
 
2947
    }
 
2948
 
 
2949
  if ((start > end) || (start > cols))
 
2950
    {
 
2951
    TIFFError ("extractContigSamplesShifted16bits", 
 
2952
               "Invalid start column value %d ignored", start);
 
2953
    start = 0;
 
2954
    }
 
2955
  if ((end == 0) || (end > cols))
 
2956
    {
 
2957
    TIFFError ("extractContigSamplesShifted16bits", 
 
2958
               "Invalid end column value %d ignored", end);
 
2959
    end = cols;
 
2960
    }
 
2961
 
 
2962
  ready_bits = shift;
 
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++)
 
2968
      {
 
2969
      if (sindex == 0)
 
2970
        {
 
2971
        src_byte = bit_offset / 8;
 
2972
        src_bit  = bit_offset % 8;
 
2973
        }
 
2974
      else
 
2975
        {
 
2976
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2977
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2978
        }
 
2979
 
 
2980
      src = in + src_byte;
 
2981
      matchbits = maskbits << (16 - src_bit - bps); 
 
2982
      if (little_endian)
 
2983
        {
 
2984
        swapbuff[1] = *src;
 
2985
        swapbuff[0] = *(src + 1);
 
2986
        }
 
2987
      else
 
2988
        {
 
2989
        swapbuff[0] = *src;
 
2990
        swapbuff[1] = *(src + 1);
 
2991
        }
 
2992
 
 
2993
      buff1 = *((uint16 *)swapbuff);
 
2994
      if ((col == start) && (sindex == sample))
 
2995
        buff2 = buff1 & ((uint16)-1) << (8 - shift);
 
2996
 
 
2997
      buff1 = (buff1 & matchbits) << (src_bit);
 
2998
 
 
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 */
 
3002
        {
 
3003
        bytebuff = (buff2 >> 8);
 
3004
        *dst++ = bytebuff;
 
3005
        ready_bits -= 8;
 
3006
        /* shift in new bits */
 
3007
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
3008
        }
 
3009
 
 
3010
      ready_bits += bps;
 
3011
      }
 
3012
    }
 
3013
 
 
3014
  /* catch any trailing bits at the end of the line */
 
3015
  while (ready_bits > 0)
 
3016
    {
 
3017
    bytebuff = (buff2 >> 8);
 
3018
    *dst++ = bytebuff;
 
3019
    ready_bits -= 8;
 
3020
    }
 
3021
  
 
3022
  return (0);
 
3023
  } /* end extractContigSamplesShifted16bits */
 
3024
 
 
3025
 
 
3026
static int
 
3027
extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
 
3028
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
3029
                                   tsample_t count, uint32 start, uint32 end,
 
3030
                                   int shift)
 
3031
  {
 
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;
 
3037
  uint8 *src = in;
 
3038
  uint8 *dst = out;
 
3039
  unsigned char  swapbuff[4];
 
3040
 
 
3041
  if ((in == NULL) || (out == NULL))
 
3042
    {
 
3043
    TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
 
3044
    return (1);
 
3045
    }
 
3046
 
 
3047
  if ((start > end) || (start > cols))
 
3048
    {
 
3049
    TIFFError ("extractContigSamplesShifted24bits", 
 
3050
               "Invalid start column value %d ignored", start);
 
3051
    start = 0;
 
3052
    }
 
3053
  if ((end == 0) || (end > cols))
 
3054
    {
 
3055
    TIFFError ("extractContigSamplesShifted24bits", 
 
3056
               "Invalid end column value %d ignored", end);
 
3057
    end = cols;
 
3058
    }
 
3059
 
 
3060
  ready_bits = shift;
 
3061
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
3062
  for (col = start; col < end; col++)
 
3063
    {
 
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++)
 
3067
      {
 
3068
      if (sindex == 0)
 
3069
        {
 
3070
        src_byte = bit_offset / 8;
 
3071
        src_bit  = bit_offset % 8;
 
3072
        }
 
3073
      else
 
3074
        {
 
3075
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3076
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3077
        }
 
3078
 
 
3079
      src = in + src_byte;
 
3080
      matchbits = maskbits << (32 - src_bit - bps); 
 
3081
      if (little_endian)
 
3082
        {
 
3083
        swapbuff[3] = *src;
 
3084
        swapbuff[2] = *(src + 1);
 
3085
        swapbuff[1] = *(src + 2);
 
3086
        swapbuff[0] = *(src + 3);
 
3087
        }
 
3088
      else
 
3089
        {
 
3090
        swapbuff[0] = *src;
 
3091
        swapbuff[1] = *(src + 1);
 
3092
        swapbuff[2] = *(src + 2);
 
3093
        swapbuff[3] = *(src + 3);
 
3094
        }
 
3095
 
 
3096
      buff1 = *((uint32 *)swapbuff);
 
3097
      if ((col == start) && (sindex == sample))
 
3098
        buff2 = buff1 & ((uint32)-1) << (16 - shift);
 
3099
 
 
3100
      buff1 = (buff1 & matchbits) << (src_bit);
 
3101
 
 
3102
      if (ready_bits < 16)  /* add another bps bits to the buffer */
 
3103
        {
 
3104
        bytebuff1 = bytebuff2 = 0;
 
3105
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3106
        }
 
3107
      else /* If we have a full buffer's worth, write it out */
 
3108
        {
 
3109
        bytebuff1 = (buff2 >> 24);
 
3110
        *dst++ = bytebuff1;
 
3111
        bytebuff2 = (buff2 >> 16);
 
3112
        *dst++ = bytebuff2;
 
3113
        ready_bits -= 16;
 
3114
 
 
3115
        /* shift in new bits */
 
3116
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
3117
        }
 
3118
      ready_bits += bps;
 
3119
      }
 
3120
    }
 
3121
 
 
3122
  /* catch any trailing bits at the end of the line */
 
3123
  while (ready_bits > 0)
 
3124
    {
 
3125
    bytebuff1 = (buff2 >> 24);
 
3126
    *dst++ = bytebuff1;
 
3127
 
 
3128
    buff2 = (buff2 << 8);
 
3129
    bytebuff2 = bytebuff1;
 
3130
    ready_bits -= 8;
 
3131
    }
 
3132
   
 
3133
  return (0);
 
3134
  } /* end extractContigSamplesShifted24bits */
 
3135
 
 
3136
static int
 
3137
extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
 
3138
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
3139
                                   tsample_t count, uint32 start, uint32 end,
 
3140
                                   int shift)
 
3141
  {
 
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;
 
3148
  uint8 *src = in;
 
3149
  uint8 *dst = out;
 
3150
  unsigned char swapbuff1[4];
 
3151
  unsigned char swapbuff2[4];
 
3152
 
 
3153
  if ((in == NULL) || (out == NULL))
 
3154
    {
 
3155
    TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
 
3156
    return (1);
 
3157
    }
 
3158
 
 
3159
 
 
3160
  if ((start > end) || (start > cols))
 
3161
    {
 
3162
    TIFFError ("extractContigSamplesShifted32bits", 
 
3163
               "Invalid start column value %d ignored", start);
 
3164
    start = 0;
 
3165
    }
 
3166
  if ((end == 0) || (end > cols))
 
3167
    {
 
3168
    TIFFError ("extractContigSamplesShifted32bits", 
 
3169
               "Invalid end column value %d ignored", end);
 
3170
    end = cols;
 
3171
    }
 
3172
 
 
3173
  shift_width = ((bps + 7) / 8) + 1; 
 
3174
  ready_bits = shift;
 
3175
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
3176
  for (col = start; col < end; col++)
 
3177
    {
 
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++)
 
3181
      {
 
3182
      if (sindex == 0)
 
3183
        {
 
3184
        src_byte = bit_offset / 8;
 
3185
        src_bit  = bit_offset % 8;
 
3186
        }
 
3187
      else
 
3188
        {
 
3189
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3190
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3191
        }
 
3192
 
 
3193
      src = in + src_byte;
 
3194
      matchbits = maskbits << (64 - src_bit - bps); 
 
3195
      if (little_endian)
 
3196
        {
 
3197
        swapbuff1[3] = *src;
 
3198
        swapbuff1[2] = *(src + 1);
 
3199
        swapbuff1[1] = *(src + 2);
 
3200
        swapbuff1[0] = *(src + 3);
 
3201
        }
 
3202
      else
 
3203
        {
 
3204
        swapbuff1[0] = *src;
 
3205
        swapbuff1[1] = *(src + 1);
 
3206
        swapbuff1[2] = *(src + 2);
 
3207
        swapbuff1[3] = *(src + 3);
 
3208
        }
 
3209
      longbuff1 = *((uint32 *)swapbuff1);                  
 
3210
 
 
3211
      memset (swapbuff2, '\0', sizeof(swapbuff2));
 
3212
      if (little_endian)
 
3213
        {
 
3214
        swapbuff2[3] = *src;
 
3215
        swapbuff2[2] = *(src + 1);
 
3216
        swapbuff2[1] = *(src + 2);
 
3217
        swapbuff2[0] = *(src + 3);
 
3218
        }
 
3219
      else
 
3220
        {
 
3221
        swapbuff2[0] = *src;
 
3222
        swapbuff2[1] = *(src + 1);
 
3223
        swapbuff2[2] = *(src + 2);
 
3224
        swapbuff2[3] = *(src + 3);
 
3225
        }
 
3226
 
 
3227
      longbuff2 = *((uint32 *)swapbuff2);
 
3228
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
3229
      if ((col == start) && (sindex == sample))
 
3230
        buff2 = buff3 & ((uint64)-1) << (32 - shift);
 
3231
 
 
3232
      buff1 = (buff3 & matchbits) << (src_bit);
 
3233
 
 
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));
 
3238
        }
 
3239
      else  /* If we have a full buffer's worth, write it out */
 
3240
        {
 
3241
        bytebuff1 = (buff2 >> 56);
 
3242
        *dst++ = bytebuff1;
 
3243
        bytebuff2 = (buff2 >> 48);
 
3244
        *dst++ = bytebuff2;
 
3245
        bytebuff3 = (buff2 >> 40);
 
3246
        *dst++ = bytebuff3;
 
3247
        bytebuff4 = (buff2 >> 32);
 
3248
        *dst++ = bytebuff4;
 
3249
        ready_bits -= 32;
 
3250
                    
 
3251
        /* shift in new bits */
 
3252
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
3253
        }
 
3254
      ready_bits += bps;
 
3255
      }
 
3256
    }
 
3257
  while (ready_bits > 0)
 
3258
    {
 
3259
    bytebuff1 = (buff2 >> 56);
 
3260
    *dst++ = bytebuff1;
 
3261
    buff2 = (buff2 << 8);
 
3262
    ready_bits -= 8;
 
3263
    }
 
3264
  
 
3265
  return (0);
 
3266
  } /* end extractContigSamplesShifted32bits */
 
3267
 
 
3268
 
 
3269
static int
 
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)
 
3273
  {
 
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;
 
3278
  uint8 *src, *dst;
 
3279
 
 
3280
  bytes_per_sample = (bps + 7) / 8; 
 
3281
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
3282
  if ((bps % 8) == 0)
 
3283
    shift_width = 0;
 
3284
  else
 
3285
    {
 
3286
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
3287
      shift_width = bytes_per_pixel;
 
3288
    else
 
3289
      shift_width = bytes_per_sample + 1;
 
3290
    }
 
3291
  src_rowsize = ((bps * spp * cols) + 7) / 8;
 
3292
  dst_rowsize = ((bps * cols) + 7) / 8;
 
3293
 
 
3294
  if ((dump->outfile != NULL) && (dump->level == 4))
 
3295
    {
 
3296
    dump_info  (dump->outfile, dump->format, "extractContigSamplesToBuffer", 
 
3297
                "Sample %d, %d rows", sample + 1, rows + 1);
 
3298
    }
 
3299
  for (row = 0; row < rows; row++)
 
3300
    {
 
3301
    src_offset = row * src_rowsize;
 
3302
    dst_offset = row * dst_rowsize;
 
3303
    src = in + src_offset;
 
3304
    dst = out + dst_offset;
 
3305
 
 
3306
    /* pack the data into the scanline */
 
3307
    switch (shift_width)
 
3308
      {  
 
3309
      case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
 
3310
                                             spp, bps,  count, first_col, cols))  
 
3311
                return (1);
 
3312
              break;
 
3313
      case 1: if (extractContigSamples8bits (src, dst, cols, sample,
 
3314
                                             spp, bps, count, first_col, cols))
 
3315
                 return (1);
 
3316
              break;
 
3317
      case 2: if (extractContigSamples16bits (src, dst, cols, sample,
 
3318
                                              spp, bps,  count, first_col, cols))
 
3319
                 return (1);
 
3320
              break;
 
3321
      case 3: if (extractContigSamples24bits (src, dst, cols, sample,
 
3322
                                              spp, bps,  count, first_col, cols))
 
3323
                 return (1);
 
3324
              break;
 
3325
      case 4: 
 
3326
      case 5: if (extractContigSamples32bits (src, dst, cols, sample,
 
3327
                                              spp, bps,  count, first_col, cols))
 
3328
                 return (1);
 
3329
              break;
 
3330
      default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
 
3331
               return (1);
 
3332
      }
 
3333
    if ((dump->outfile != NULL) && (dump->level == 4))
 
3334
      dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
 
3335
    
 
3336
    out += outskew;
 
3337
    in += inskew;
 
3338
    }
 
3339
 
 
3340
  return (0);
 
3341
  } /* end extractContigSamplesToBuffer */
 
3342
 
 
3343
/* This will not work unless bps is a multiple of 8 */
 
3344
static void
 
3345
cpSeparateBufToContigBuf(uint8  *out, uint8 *in, uint32 rows, uint32 cols, 
 
3346
                         int outskew, int inskew, tsample_t spp,
 
3347
                         int bytes_per_sample)
 
3348
  {
 
3349
  while (rows-- > 0)
 
3350
    {
 
3351
    uint32 j = cols;
 
3352
    while (j-- > 0)
 
3353
      {
 
3354
      int n = bytes_per_sample;
 
3355
      while( n-- )
 
3356
        {
 
3357
        *out++ = *in++;
 
3358
        }
 
3359
      out += (spp-1)*bytes_per_sample;
 
3360
      }
 
3361
    out += outskew;
 
3362
    in += inskew;
 
3363
    }
 
3364
  } /* end of cpSeparateBufToContifBuf */
 
3365
 
 
3366
static int readContigStripsIntoBuffer (TIFF* in, uint8* buf, uint32 imagelength, 
 
3367
                                         uint32 imagewidth, tsample_t spp)
 
3368
  {
 
3369
  tsize_t scanlinesize = TIFFScanlineSize(in);
 
3370
  uint8* bufp = buf;
 
3371
  uint32 row;
 
3372
 
 
3373
 (void) imagewidth; (void) spp;
 
3374
 for (row = 0; row < imagelength; row++)
 
3375
   {
 
3376
   if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
 
3377
         && !ignore)
 
3378
     {
 
3379
     TIFFError(TIFFFileName(in),"Error, can't read scanline %lu",
 
3380
               (unsigned long) row);
 
3381
     return 0;
 
3382
     }
 
3383
   bufp += scanlinesize;
 
3384
   }
 
3385
 
 
3386
 return 1;
 
3387
  } /* end readContigStripsIntoBuffer */
 
3388
 
 
3389
static int
 
3390
combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 row,
 
3391
                            uint32 cols, uint16 spp, uint16 bps, 
 
3392
                            FILE *dumpfile, int format, int level)
 
3393
  {
 
3394
  int    ready_bits = 0;
 
3395
  int    bytes_per_sample = 0;
 
3396
  uint32 dst_rowsize; 
 
3397
  uint32 bit_offset;
 
3398
  uint32 col, src_byte = 0, src_bit = 0;
 
3399
  uint8  maskbits = 0, matchbits = 0;
 
3400
  uint8  buff1 = 0, buff2 = 0;
 
3401
  tsample_t s;
 
3402
  unsigned char *src = in[0];
 
3403
  unsigned char *dst = out;
 
3404
  char           action[32];
 
3405
 
 
3406
  if ((src == NULL) || (dst == NULL))
 
3407
    {
 
3408
    TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
 
3409
    return (1);
 
3410
    }
 
3411
 
 
3412
  bytes_per_sample = (bps + 7) / 8; 
 
3413
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
3414
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
3415
 
 
3416
  ready_bits = 0;
 
3417
  buff1 = buff2 = 0;
 
3418
 
 
3419
  for (col = 0; col < cols; col++)
 
3420
    {
 
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;
 
3425
 
 
3426
    matchbits = maskbits << (8 - src_bit - bps); 
 
3427
    /* load up next sample from each plane */
 
3428
    for (s = 0; s < spp; s++)
 
3429
      {
 
3430
      src = in[s] + src_byte;
 
3431
      buff1 = ((*src) & matchbits) << (src_bit);
 
3432
 
 
3433
      /* If we have a full buffer's worth, write it out */
 
3434
      if (ready_bits >= 8)
 
3435
        {
 
3436
        *dst++ = buff2;
 
3437
        buff2 = buff1;
 
3438
        ready_bits -= 8;
 
3439
        strcpy (action, "Flush");
 
3440
        }
 
3441
      else
 
3442
        {
 
3443
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3444
        strcpy (action, "Update");
 
3445
        }
 
3446
      ready_bits += bps;
 
3447
 
 
3448
      if ((dumpfile != NULL) && (level == 3))
 
3449
        {
 
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); 
 
3458
        }
 
3459
      }
 
3460
    }
 
3461
 
 
3462
  if (ready_bits > 0)
 
3463
    {
 
3464
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
3465
    *dst++ = buff1;
 
3466
    if ((dumpfile != NULL) && (level == 3))
 
3467
      {
 
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);
 
3472
      }
 
3473
    }
 
3474
 
 
3475
  if ((dumpfile != NULL) && (level == 2))
 
3476
    {
 
3477
    dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
 
3478
    dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
3479
    }
 
3480
  
 
3481
  return (0);
 
3482
  } /* end combineSeparateSamples8bits */
 
3483
 
 
3484
static int
 
3485
combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 row,
 
3486
                              uint32 cols, uint16 spp, uint16 bps, 
 
3487
                              FILE *dumpfile, int format, int level)
 
3488
  {
 
3489
  int    ready_bits = 0, bytes_per_sample = 0;
 
3490
  uint32 dst_rowsize; 
 
3491
  uint32 bit_offset;
 
3492
  uint32 col, src_byte = 0, src_bit = 0;
 
3493
  uint16 maskbits = 0, matchbits = 0;
 
3494
  uint16 buff1 = 0, buff2 = 0;
 
3495
  uint8  bytebuff = 0;
 
3496
  tsample_t s;
 
3497
  unsigned char *src = in[0];
 
3498
  unsigned char *dst = out;
 
3499
  unsigned char  swapbuff[2];
 
3500
  char           action[8];
 
3501
 
 
3502
  if ((src == NULL) || (dst == NULL))
 
3503
    {
 
3504
    TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
 
3505
    return (1);
 
3506
    }
 
3507
 
 
3508
  bytes_per_sample = (bps + 7) / 8; 
 
3509
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
3510
  maskbits = (uint16)-1 >> (16 - bps);
 
3511
 
 
3512
  ready_bits = 0;
 
3513
  buff1 = buff2 = 0;
 
3514
  for (col = 0; col < cols; col++)
 
3515
    {
 
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;
 
3520
 
 
3521
    matchbits = maskbits << (16 - src_bit - bps); 
 
3522
    for (s = 0; s < spp; s++)
 
3523
      {
 
3524
      src = in[s] + src_byte;
 
3525
      if (little_endian)
 
3526
        {
 
3527
        swapbuff[1] = *src;
 
3528
        swapbuff[0] = *(src + 1);
 
3529
        }
 
3530
      else
 
3531
        {
 
3532
        swapbuff[0] = *src;
 
3533
        swapbuff[1] = *(src + 1);
 
3534
        }
 
3535
 
 
3536
      buff1 = *((uint16 *)swapbuff);
 
3537
      buff1 = (buff1 & matchbits) << (src_bit);
 
3538
 
 
3539
      /* If we have a full buffer's worth, write it out */
 
3540
      if (ready_bits >= 8)
 
3541
        {
 
3542
        bytebuff = (buff2 >> 8);
 
3543
        *dst++ = bytebuff;
 
3544
        ready_bits -= 8;
 
3545
        /* shift in new bits */
 
3546
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
3547
        strcpy (action, "Flush");
 
3548
        }
 
3549
      else
 
3550
        { /* add another bps bits to the buffer */
 
3551
        bytebuff = 0;
 
3552
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3553
        strcpy (action, "Update");
 
3554
        }
 
3555
      ready_bits += bps;
 
3556
 
 
3557
      if ((dumpfile != NULL) && (level == 3))
 
3558
        {
 
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);
 
3562
 
 
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); 
 
3569
        }
 
3570
      }
 
3571
    }
 
3572
  /* catch any trailing bits at the end of the line */
 
3573
  if (ready_bits > 0)
 
3574
    {
 
3575
    bytebuff = (buff2 >> 8);
 
3576
    *dst++ = bytebuff;
 
3577
    if ((dumpfile != NULL) && (level == 3))
 
3578
      {
 
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);
 
3583
      }
 
3584
    }
 
3585
 
 
3586
  if ((dumpfile != NULL) && (level == 2))
 
3587
    {
 
3588
    dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
 
3589
    dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
3590
    }
 
3591
  
 
3592
  return (0);
 
3593
  } /* end combineSeparateSamples16bits */
 
3594
 
 
3595
static int
 
3596
combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 row,
 
3597
                              uint32 cols, uint16 spp, uint16 bps, 
 
3598
                              FILE *dumpfile, int format, int level)
 
3599
  {
 
3600
  int    ready_bits = 0, bytes_per_sample = 0;
 
3601
  uint32 dst_rowsize; 
 
3602
  uint32 bit_offset;
 
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;
 
3607
  tsample_t s;
 
3608
  unsigned char *src = in[0];
 
3609
  unsigned char *dst = out;
 
3610
  unsigned char  swapbuff[4];
 
3611
  char           action[8];
 
3612
 
 
3613
  if ((src == NULL) || (dst == NULL))
 
3614
    {
 
3615
    TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
 
3616
    return (1);
 
3617
    }
 
3618
 
 
3619
  bytes_per_sample = (bps + 7) / 8; 
 
3620
  dst_rowsize = ((bps * cols) + 7) / 8;
 
3621
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
3622
 
 
3623
  ready_bits = 0;
 
3624
  buff1 = buff2 = 0;
 
3625
  for (col = 0; col < cols; col++)
 
3626
    {
 
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;
 
3631
 
 
3632
    matchbits = maskbits << (32 - src_bit - bps); 
 
3633
    for (s = 0; s < spp; s++)
 
3634
      {
 
3635
      src = in[s] + src_byte;
 
3636
      if (little_endian)
 
3637
        {
 
3638
        swapbuff[3] = *src;
 
3639
        swapbuff[2] = *(src + 1);
 
3640
        swapbuff[1] = *(src + 2);
 
3641
        swapbuff[0] = *(src + 3);
 
3642
        }
 
3643
      else
 
3644
        {
 
3645
        swapbuff[0] = *src;
 
3646
        swapbuff[1] = *(src + 1);
 
3647
        swapbuff[2] = *(src + 2);
 
3648
        swapbuff[3] = *(src + 3);
 
3649
        }
 
3650
 
 
3651
      buff1 = *((uint32 *)swapbuff);
 
3652
      buff1 = (buff1 & matchbits) << (src_bit);
 
3653
 
 
3654
      /* If we have a full buffer's worth, write it out */
 
3655
      if (ready_bits >= 16)
 
3656
        {
 
3657
        bytebuff1 = (buff2 >> 24);
 
3658
        *dst++ = bytebuff1;
 
3659
        bytebuff2 = (buff2 >> 16);
 
3660
        *dst++ = bytebuff2;
 
3661
        ready_bits -= 16;
 
3662
 
 
3663
        /* shift in new bits */
 
3664
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
3665
        strcpy (action, "Flush");
 
3666
        }
 
3667
      else
 
3668
        { /* add another bps bits to the buffer */
 
3669
        bytebuff1 = bytebuff2 = 0;
 
3670
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3671
        strcpy (action, "Update");
 
3672
        }
 
3673
      ready_bits += bps;
 
3674
 
 
3675
      if ((dumpfile != NULL) && (level == 3))
 
3676
        {
 
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); 
 
3687
        }
 
3688
      }
 
3689
    }
 
3690
 
 
3691
  /* catch any trailing bits at the end of the line */
 
3692
  while (ready_bits > 0)
 
3693
    {
 
3694
    bytebuff1 = (buff2 >> 24);
 
3695
    *dst++ = bytebuff1;
 
3696
 
 
3697
    buff2 = (buff2 << 8);
 
3698
    bytebuff2 = bytebuff1;
 
3699
    ready_bits -= 8;
 
3700
    }
 
3701
 
 
3702
  if ((dumpfile != NULL) && (level == 3))
 
3703
    {
 
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);
 
3707
 
 
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); 
 
3715
    }
 
3716
 
 
3717
  if ((dumpfile != NULL) && (level == 2))
 
3718
    {
 
3719
    dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
 
3720
    dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
3721
    }
 
3722
  
 
3723
  return (0);
 
3724
  } /* end combineSeparateSamples24bits */
 
3725
 
 
3726
static int
 
3727
combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 row,
 
3728
                              uint32 cols, uint16 spp, uint16 bps, 
 
3729
                              FILE *dumpfile, int format, int level)
 
3730
  {
 
3731
  int    ready_bits = 0, bytes_per_sample = 0, shift_width = 0;
 
3732
  uint32 dst_rowsize; 
 
3733
  uint32 bit_offset;
 
3734
  uint32 src_byte = 0, src_bit = 0;
 
3735
  uint32 col;
 
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;
 
3740
  tsample_t s;
 
3741
  unsigned char *src = in[0];
 
3742
  unsigned char *dst = out;
 
3743
  unsigned char  swapbuff1[4];
 
3744
  unsigned char  swapbuff2[4];
 
3745
  char           action[8];
 
3746
 
 
3747
  if ((src == NULL) || (dst == NULL))
 
3748
    {
 
3749
    TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
 
3750
    return (1);
 
3751
    }
 
3752
 
 
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; 
 
3757
 
 
3758
  ready_bits = 0;
 
3759
  buff1 = buff2 = 0;
 
3760
  for (col = 0; col < cols; col++)
 
3761
    {
 
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;
 
3766
 
 
3767
    matchbits = maskbits << (64 - src_bit - bps); 
 
3768
    for (s = 0; s < spp; s++)
 
3769
      {
 
3770
      src = in[s] + src_byte;
 
3771
      if (little_endian)
 
3772
        {
 
3773
        swapbuff1[3] = *src;
 
3774
        swapbuff1[2] = *(src + 1);
 
3775
        swapbuff1[1] = *(src + 2);
 
3776
        swapbuff1[0] = *(src + 3);
 
3777
        }
 
3778
      else
 
3779
        {
 
3780
        swapbuff1[0] = *src;
 
3781
        swapbuff1[1] = *(src + 1);
 
3782
        swapbuff1[2] = *(src + 2);
 
3783
        swapbuff1[3] = *(src + 3);
 
3784
        }
 
3785
      longbuff1 = *((uint32 *)swapbuff1);                  
 
3786
 
 
3787
      memset (swapbuff2, '\0', sizeof(swapbuff2));
 
3788
      if (little_endian)
 
3789
        {
 
3790
        swapbuff2[3] = *src;
 
3791
        swapbuff2[2] = *(src + 1);
 
3792
        swapbuff2[1] = *(src + 2);
 
3793
        swapbuff2[0] = *(src + 3);
 
3794
        }
 
3795
      else
 
3796
        {
 
3797
        swapbuff2[0] = *src;
 
3798
        swapbuff2[1] = *(src + 1);
 
3799
        swapbuff2[2] = *(src + 2);
 
3800
        swapbuff2[3] = *(src + 3);
 
3801
        }
 
3802
 
 
3803
      longbuff2 = *((uint32 *)swapbuff2);
 
3804
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
3805
      buff1 = (buff3 & matchbits) << (src_bit);
 
3806
 
 
3807
      /* If we have a full buffer's worth, write it out */
 
3808
      if (ready_bits >= 32)
 
3809
        {
 
3810
        bytebuff1 = (buff2 >> 56);
 
3811
        *dst++ = bytebuff1;
 
3812
        bytebuff2 = (buff2 >> 48);
 
3813
        *dst++ = bytebuff2;
 
3814
        bytebuff3 = (buff2 >> 40);
 
3815
        *dst++ = bytebuff3;
 
3816
        bytebuff4 = (buff2 >> 32);
 
3817
        *dst++ = bytebuff4;
 
3818
        ready_bits -= 32;
 
3819
                    
 
3820
        /* shift in new bits */
 
3821
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
3822
        strcpy (action, "Flush");
 
3823
        }
 
3824
      else
 
3825
        { /* add another bps bits to the buffer */
 
3826
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
3827
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3828
        strcpy (action, "Update");
 
3829
        }
 
3830
      ready_bits += bps;
 
3831
 
 
3832
      if ((dumpfile != NULL) && (level == 3))
 
3833
        { 
 
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); 
 
3842
        }
 
3843
      }
 
3844
    }
 
3845
  while (ready_bits > 0)
 
3846
    {
 
3847
    bytebuff1 = (buff2 >> 56);
 
3848
    *dst++ = bytebuff1;
 
3849
    buff2 = (buff2 << 8);
 
3850
    ready_bits -= 8;
 
3851
    }
 
3852
 
 
3853
  if ((dumpfile != NULL) && (level == 3))
 
3854
    {
 
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);
 
3858
 
 
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); 
 
3866
    }
 
3867
 
 
3868
  if ((dumpfile != NULL) && (level == 2))
 
3869
    {
 
3870
    dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
 
3871
    dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
3872
    }
 
3873
  
 
3874
  return (0);
 
3875
  } /* end combineSeparateSamples32bits */
 
3876
 
 
3877
static int 
 
3878
combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
 
3879
                             uint32 row, uint32 width, uint16 spp, uint16 bps, 
 
3880
                             FILE *dumpfile, int format, int level)
 
3881
  {
 
3882
  int i, bytes_per_sample, bytes_per_pixel, dst_rowsize, shift_width;
 
3883
  uint32 col, col_offset;
 
3884
  unsigned char *src;
 
3885
  unsigned char *dst;
 
3886
  tsample_t s;
 
3887
 
 
3888
  src = srcbuffs[0];
 
3889
  dst = out;
 
3890
  if ((src == NULL) || (dst == NULL))
 
3891
    {
 
3892
    TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
 
3893
    return (1);
 
3894
    }
 
3895
 
 
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;
 
3900
  else
 
3901
    shift_width = bytes_per_pixel;
 
3902
 
 
3903
  if ((dumpfile != NULL) && (level == 2))
 
3904
    {
 
3905
    for (s = 0; s < spp; s++)
 
3906
      {
 
3907
      dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
 
3908
      dump_buffer(dumpfile, format, 1, width, row, srcbuffs[s]);
 
3909
      }
 
3910
    }
 
3911
 
 
3912
  dst_rowsize = ((bps * spp * width) + 7) / 8;
 
3913
  for (col = 0; col < width; col++)
 
3914
    {
 
3915
    col_offset = col * (bps / 8); 
 
3916
    for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
3917
      {
 
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;
 
3923
      }   
 
3924
    }
 
3925
 
 
3926
  if ((dumpfile != NULL) && (level == 2))
 
3927
    {
 
3928
    dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
 
3929
    dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
3930
    }
 
3931
 
 
3932
  return (0);
 
3933
  } /* end combineSeparateSamplesBytes */
 
3934
 
 
3935
static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, 
 
3936
                                         uint32 width, uint16 spp,
 
3937
                                         struct dump_opts *dump)
 
3938
  {
 
3939
  int i, bytes_per_sample, bytes_per_pixel, shift_width;
 
3940
  uint16 bps;
 
3941
  uint32 row, src_rowsize, dst_rowsize;
 
3942
  tsample_t s;
 
3943
  tsize_t scanlinesize = TIFFScanlineSize(in);
 
3944
  unsigned char *srcbuffs[MAX_SAMPLES];
 
3945
  unsigned char *buff = NULL;
 
3946
  unsigned char *dst = NULL;
 
3947
 
 
3948
  (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
 
3949
 
 
3950
  if (obuf == NULL)
 
3951
    {
 
3952
    TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
 
3953
    return (0);
 
3954
    }
 
3955
 
 
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;
 
3960
  else
 
3961
    shift_width = bytes_per_sample + 1;
 
3962
 
 
3963
  src_rowsize = ((bps * width) + 7) / 8;
 
3964
  dst_rowsize = ((bps * width * spp) + 7) / 8;
 
3965
  dst = obuf;
 
3966
 
 
3967
  if ((dump->infile != NULL) && (dump->level == 3))
 
3968
    {
 
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);
 
3975
    }
 
3976
 
 
3977
  /* allocate scanline buffers for each sample */
 
3978
  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
3979
    {
 
3980
    srcbuffs[s] = NULL;
 
3981
    buff = _TIFFmalloc(src_rowsize);
 
3982
    if (!buff)
 
3983
      {
 
3984
      TIFFError ("readSeparateStripsIntoBuffer", 
 
3985
                 "Unable to allocate read buffer for sample %d", s);
 
3986
      for (i = 0; i < s; i++)
 
3987
        _TIFFfree (srcbuffs[i]);
 
3988
      return 0;
 
3989
      }
 
3990
    srcbuffs[s] = buff;
 
3991
    }
 
3992
 
 
3993
  /* read and process one scanline from each sample */
 
3994
  for (row = 0; row < length; row++)
 
3995
    {
 
3996
    for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
3997
      {
 
3998
      buff = srcbuffs[s];
 
3999
      /* read one scanline in the current sample color */
 
4000
      if (TIFFReadScanline(in, buff, row, s) < 0
 
4001
            && !ignore)
 
4002
        {
 
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]);
 
4008
        return (0);
 
4009
        }
 
4010
      }
 
4011
 
 
4012
    /* combine the samples in each scanline */
 
4013
    dst = obuf + (row * dst_rowsize);
 
4014
    if ((bps % 8) == 0)
 
4015
      {
 
4016
      if (combineSeparateSamplesBytes (srcbuffs, dst, row, width,
 
4017
                                      spp, bps, dump->infile,
 
4018
                                      dump->format, dump->level))
 
4019
        {
 
4020
        for (i = 0; i < spp; i++)
 
4021
         _TIFFfree (srcbuffs[i]);
 
4022
        return (0);
 
4023
        }
 
4024
      }
 
4025
    else
 
4026
      {
 
4027
      switch (shift_width)
 
4028
        {
 
4029
        case 1: if (combineSeparateSamples8bits (srcbuffs, dst, row, width,
 
4030
                                                spp, bps, dump->infile,
 
4031
                                                dump->format, dump->level))
 
4032
                  {
 
4033
                  for (i = 0; i < spp; i++)
 
4034
                    _TIFFfree (srcbuffs[i]);
 
4035
                  return (0);
 
4036
                  }
 
4037
                break;
 
4038
        case 2: if (combineSeparateSamples16bits (srcbuffs, dst, row, width,
 
4039
                                                 spp, bps, dump->infile,
 
4040
                                                 dump->format, dump->level))
 
4041
                  {
 
4042
                  for (i = 0; i < spp; i++)
 
4043
                    _TIFFfree (srcbuffs[i]);
 
4044
                  return (0);
 
4045
                  }
 
4046
                break;
 
4047
        case 3: if (combineSeparateSamples24bits (srcbuffs, dst, row, width,
 
4048
                                                 spp, bps, dump->infile,
 
4049
                                                 dump->format, dump->level))
 
4050
                  {
 
4051
                  for (i = 0; i < spp; i++)
 
4052
                    _TIFFfree (srcbuffs[i]);
 
4053
                  return (0);
 
4054
                  }
 
4055
 
 
4056
                break;
 
4057
        case 4: 
 
4058
        case 5:
 
4059
        case 6:
 
4060
        case 7:
 
4061
        case 8: if (combineSeparateSamples32bits (srcbuffs, dst, row, width,
 
4062
                                                 spp, bps, dump->infile,
 
4063
                                                 dump->format, dump->level))
 
4064
                  {
 
4065
                  for (i = 0; i < spp; i++)
 
4066
                    _TIFFfree (srcbuffs[i]);
 
4067
                  return (0);
 
4068
                  }
 
4069
                break;
 
4070
        default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
 
4071
                  for (i = 0; i < spp; i++)
 
4072
                    _TIFFfree (srcbuffs[i]);
 
4073
                  return (0);
 
4074
        }
 
4075
      }
 
4076
    }
 
4077
 
 
4078
  /* free any buffers allocated for each plane or scanline and 
 
4079
   * any temporary buffers 
 
4080
   */
 
4081
  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
4082
    {
 
4083
    buff = srcbuffs[s];
 
4084
    if (buff != NULL)
 
4085
      _TIFFfree(buff);
 
4086
    }
 
4087
 
 
4088
  return (1);
 
4089
  } /* end readSeparateStripsIntoBuffer */
 
4090
 
 
4091
static int
 
4092
get_page_geometry (char *name, struct pagedef *page)
 
4093
    {
 
4094
    char *ptr;
 
4095
    int n; 
 
4096
 
 
4097
    for (ptr = name; *ptr; ptr++)
 
4098
      *ptr = (char)tolower((int)*ptr);
 
4099
 
 
4100
    for (n = 0; n < MAX_PAPERNAMES; n++)
 
4101
      {
 
4102
      if (strcmp(name, PaperTable[n].name) == 0)
 
4103
        {
 
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';
 
4108
        return (0);
 
4109
        }
 
4110
      }
 
4111
 
 
4112
  return (1);
 
4113
  }
 
4114
 
 
4115
 
 
4116
static void
 
4117
initPageSetup (struct pagedef *page, struct pageseg *pagelist, 
 
4118
               struct buffinfo seg_buffs[])
 
4119
   {
 
4120
   int i; 
 
4121
 
 
4122
   strcpy (page->name, "");
 
4123
   page->mode = PAGE_MODE_NONE;
 
4124
   page->res_unit = RESUNIT_NONE;
 
4125
   page->hres = 0.0;
 
4126
   page->vres = 0.0;
 
4127
   page->width = 0.0;
 
4128
   page->length = 0.0;
 
4129
   page->hmargin = 0.0;
 
4130
   page->vmargin = 0.0;
 
4131
   page->rows = 0;
 
4132
   page->cols = 0;
 
4133
   page->orient = ORIENTATION_NONE;
 
4134
 
 
4135
   for (i = 0; i < MAX_SECTIONS; i++)
 
4136
     {
 
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;
 
4144
     }
 
4145
 
 
4146
   for (i = 0; i < MAX_OUTBUFFS; i++)
 
4147
     {
 
4148
     seg_buffs[i].size = 0;
 
4149
     seg_buffs[i].buffer = NULL;
 
4150
     }
 
4151
   }
 
4152
 
 
4153
static void
 
4154
initImageData (struct image_data *image)
 
4155
  {
 
4156
  image->xres = 0.0;
 
4157
  image->yres = 0.0;
 
4158
  image->width = 0;
 
4159
  image->length = 0;
 
4160
  image->res_unit = RESUNIT_NONE;
 
4161
  image->bps = 0;
 
4162
  image->spp = 0;
 
4163
  image->planar = 0;
 
4164
  image->photometric = 0;
 
4165
  image->orientation = 0;
 
4166
  image->adjustments = 0;
 
4167
  }
 
4168
 
 
4169
static void
 
4170
initCropMasks (struct crop_mask *cps)
 
4171
   {
 
4172
   int i;
 
4173
 
 
4174
   cps->crop_mode = CROP_NONE;
 
4175
   cps->res_unit  = RESUNIT_NONE;
 
4176
   cps->edge_ref  = EDGE_TOP;
 
4177
   cps->width = 0;
 
4178
   cps->length = 0;
 
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++)
 
4191
     {
 
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;
 
4206
     }
 
4207
   cps->exp_mode = ONE_FILE_COMPOSITE;
 
4208
   cps->img_mode = COMPOSITE_IMAGES;
 
4209
   }
 
4210
 
 
4211
static void initDumpOptions(struct dump_opts *dump)
 
4212
  {
 
4213
  dump->debug  = 0;
 
4214
  dump->format = DUMP_NONE;
 
4215
  dump->level  = 1;
 
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;
 
4221
  }
 
4222
 
 
4223
/* Compute pixel offsets into the image for margins and fixed regions */
 
4224
static int
 
4225
computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
 
4226
                         struct offset *off)
 
4227
  {
 
4228
  double scale;
 
4229
  float xres, yres;
 
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;
 
4238
 
 
4239
  if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
 
4240
    {
 
4241
    xres = 1.0;
 
4242
    yres = 1.0;
 
4243
    }
 
4244
  else
 
4245
    {
 
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)))
 
4249
      {
 
4250
      TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
 
4251
      TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
 
4252
      return (-1);
 
4253
      }
 
4254
    xres = image->xres;
 
4255
    yres = image->yres;
 
4256
    }
 
4257
 
 
4258
  /* Translate user units to image units */
 
4259
  scale = 1.0;
 
4260
  switch (crop->res_unit) {
 
4261
    case RESUNIT_CENTIMETER:
 
4262
         if (image->res_unit == RESUNIT_INCH)
 
4263
           scale = 1.0/2.54;
 
4264
         break;
 
4265
    case RESUNIT_INCH:
 
4266
         if (image->res_unit == RESUNIT_CENTIMETER)
 
4267
             scale = 2.54;
 
4268
         break;
 
4269
    case RESUNIT_NONE: /* Dimensions in pixels */
 
4270
    default:
 
4271
    break;
 
4272
    }
 
4273
 
 
4274
  if (crop->crop_mode & CROP_REGIONS)
 
4275
    {
 
4276
    max_width = max_length = 0;
 
4277
    for (i = 0; i < crop->regions; i++)
 
4278
      {
 
4279
      if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
 
4280
        {
 
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);
 
4285
        }
 
4286
      else
 
4287
        {
 
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);       
 
4292
        }
 
4293
      if (x1 < 1)
 
4294
        crop->regionlist[i].x1 = 0;
 
4295
      else
 
4296
        crop->regionlist[i].x1 = (uint32) (x1 - 1);
 
4297
 
 
4298
      if (x2 > image->width - 1)
 
4299
        crop->regionlist[i].x2 = image->width - 1;
 
4300
      else
 
4301
        crop->regionlist[i].x2 = (uint32) (x2 - 1);
 
4302
      zwidth  = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 
 
4303
 
 
4304
      if (y1 < 1)
 
4305
        crop->regionlist[i].y1 = 0;
 
4306
      else
 
4307
        crop->regionlist[i].y1 = (uint32) (y1 - 1);
 
4308
 
 
4309
      if (y2 > image->length - 1)
 
4310
        crop->regionlist[i].y2 = image->length - 1;
 
4311
      else
 
4312
        crop->regionlist[i].y2 = (uint32) (y2 - 1);
 
4313
 
 
4314
      zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 
 
4315
 
 
4316
      if (zwidth > max_width)
 
4317
        max_width = zwidth;
 
4318
      if (zlength > max_length)
 
4319
        max_length = zlength;
 
4320
 
 
4321
      buffsize = (uint32)
 
4322
          (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
 
4323
 
 
4324
      /*
 
4325
      buffsize = (uint32)
 
4326
          (((zwidth * image->bps + 7 ) / 8)  * image->spp * (zlength + 1));
 
4327
      */
 
4328
      crop->regionlist[i].buffsize = buffsize;
 
4329
      crop->bufftotal += buffsize;
 
4330
      if (crop->img_mode == COMPOSITE_IMAGES)
 
4331
        {
 
4332
        switch (crop->edge_ref)
 
4333
          {
 
4334
          case EDGE_LEFT:
 
4335
          case EDGE_RIGHT:
 
4336
               crop->combined_length = zlength;
 
4337
               crop->combined_width += zwidth;
 
4338
               break;
 
4339
          case EDGE_BOTTOM:
 
4340
          case EDGE_TOP:  /* width from left, length from top */
 
4341
          default:
 
4342
               crop->combined_width = zwidth;
 
4343
               crop->combined_length += zlength;
 
4344
               break;
 
4345
          }
 
4346
        }
 
4347
      }
 
4348
    return (0);
 
4349
    }
 
4350
  
 
4351
  /* Convert crop margins into offsets into image
 
4352
   * Margins are expressed as pixel rows and columns, not bytes
 
4353
   */
 
4354
  if (crop->crop_mode & CROP_MARGINS)
 
4355
    {
 
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]);
 
4362
      }
 
4363
    else
 
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);
 
4369
      }
 
4370
 
 
4371
    if ((lmargin + rmargin) > image->width)
 
4372
      {
 
4373
      TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
 
4374
      lmargin = (uint32) 0;
 
4375
      rmargin = (uint32) 0;
 
4376
      return (-1);
 
4377
      }
 
4378
    if ((tmargin + bmargin) > image->length)
 
4379
      {
 
4380
      TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length"); 
 
4381
      tmargin = (uint32) 0; 
 
4382
      bmargin = (uint32) 0;
 
4383
      return (-1);
 
4384
      }
 
4385
    }
 
4386
  else
 
4387
    { /* no margins requested */
 
4388
    tmargin = (uint32) 0;
 
4389
    lmargin = (uint32) 0;
 
4390
    bmargin = (uint32) 0;
 
4391
    rmargin = (uint32) 0;
 
4392
    }
 
4393
 
 
4394
  /* Width, height, and margins are expressed as pixel offsets into image */
 
4395
  if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
 
4396
    {
 
4397
    if (crop->crop_mode & CROP_WIDTH)
 
4398
      width = (uint32)crop->width;
 
4399
    else
 
4400
      width = image->width - lmargin - rmargin;
 
4401
 
 
4402
    if (crop->crop_mode & CROP_LENGTH)
 
4403
      length  = (uint32)crop->length;
 
4404
    else
 
4405
      length = image->length - tmargin - bmargin;
 
4406
    }
 
4407
  else
 
4408
    {
 
4409
    if (crop->crop_mode & CROP_WIDTH)
 
4410
      width = (uint32)(crop->width * scale * image->xres);
 
4411
    else
 
4412
      width = image->width - lmargin - rmargin;
 
4413
 
 
4414
    if (crop->crop_mode & CROP_LENGTH)
 
4415
      length  = (uint32)(crop->length * scale * image->yres);
 
4416
    else
 
4417
      length = image->length - tmargin - bmargin;
 
4418
    }
 
4419
 
 
4420
  off->tmargin = tmargin;
 
4421
  off->bmargin = bmargin;
 
4422
  off->lmargin = lmargin;
 
4423
  off->rmargin = rmargin;
 
4424
 
 
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) {
 
4429
    case EDGE_BOTTOM:
 
4430
         startx = lmargin;
 
4431
         if ((startx + width) >= (image->width - rmargin))
 
4432
           endx = image->width - rmargin - 1;
 
4433
         else
 
4434
           endx = startx + width - 1;
 
4435
 
 
4436
         endy = image->length - bmargin - 1;
 
4437
         if ((endy - length) <= tmargin)
 
4438
           starty = tmargin;
 
4439
         else
 
4440
           starty = endy - length + 1;
 
4441
         break;
 
4442
    case EDGE_RIGHT:
 
4443
         endx = image->width - rmargin - 1;
 
4444
         if ((endx - width) <= lmargin)
 
4445
           startx = lmargin;
 
4446
         else
 
4447
           startx = endx - width + 1;
 
4448
 
 
4449
         starty = tmargin;
 
4450
         if ((starty + length) >= (image->length - bmargin))
 
4451
           endy = image->length - bmargin - 1;
 
4452
         else
 
4453
           endy = starty + length - 1;
 
4454
         break;
 
4455
    case EDGE_TOP:  /* width from left, length from top */
 
4456
    case EDGE_LEFT:
 
4457
    default:
 
4458
         startx = lmargin;
 
4459
         if ((startx + width) >= (image->width - rmargin))
 
4460
           endx = image->width - rmargin - 1;
 
4461
         else
 
4462
           endx = startx + width - 1;
 
4463
 
 
4464
         starty = tmargin;
 
4465
         if ((starty + length) >= (image->length - bmargin))
 
4466
           endy = image->length - bmargin - 1;
 
4467
         else
 
4468
           endy = starty + length - 1;
 
4469
         break;
 
4470
    }
 
4471
  off->startx = startx;
 
4472
  off->starty = starty;
 
4473
  off->endx   = endx;
 
4474
  off->endy   = endy;
 
4475
 
 
4476
  crop_width  = endx - startx + 1;
 
4477
  crop_length = endy - starty + 1;
 
4478
 
 
4479
  if (crop_width <= 0)
 
4480
    {
 
4481
    TIFFError("computeInputPixelOffsets", 
 
4482
               "Invalid left/right margins and /or image crop width requested");
 
4483
    return (-1);
 
4484
    }
 
4485
  if (crop_width > image->width)
 
4486
    crop_width = image->width;
 
4487
 
 
4488
  if (crop_length <= 0)
 
4489
    {
 
4490
    TIFFError("computeInputPixelOffsets", 
 
4491
              "Invalid top/bottom margins and /or image crop length requested");
 
4492
    return (-1);
 
4493
    }
 
4494
  if (crop_length > image->length)
 
4495
    crop_length = image->length;
 
4496
 
 
4497
  off->crop_width = crop_width;
 
4498
  off->crop_length = crop_length;
 
4499
 
 
4500
  return (0);
 
4501
  } /* end computeInputPixelOffsets */
 
4502
 
 
4503
/* 
 
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.
 
4512
 */
 
4513
 
 
4514
static int
 
4515
getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
 
4516
  {
 
4517
  struct offset offsets;
 
4518
  int    i;
 
4519
  int32  test2;
 
4520
  uint32 test, seg, total, need_buff = 0;
 
4521
  uint32 buffsize;
 
4522
  uint32 zwidth, zlength;
 
4523
 
 
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;
 
4529
 
 
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))
 
4535
    {
 
4536
    if (computeInputPixelOffsets(crop, image, &offsets))
 
4537
      {
 
4538
      TIFFError ("getCropOffsets", "Unable to compute crop margins");
 
4539
      return (-1);
 
4540
      }
 
4541
    need_buff = TRUE;
 
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)
 
4545
      return (0);
 
4546
    }
 
4547
  else
 
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;
 
4555
    offsets.startx = 0;
 
4556
    offsets.endx = image->width - 1;
 
4557
    offsets.starty = 0;
 
4558
    offsets.endy = image->length - 1;
 
4559
    need_buff = FALSE;
 
4560
    }
 
4561
 
 
4562
  if (dump->outfile != NULL)
 
4563
    {
 
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);
 
4568
    }
 
4569
 
 
4570
  if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
 
4571
    {
 
4572
    if (need_buff == FALSE)  /* No margins or fixed width or length areas */
 
4573
      {
 
4574
      crop->selections = 0;
 
4575
      crop->combined_width  = image->width;
 
4576
      crop->combined_length = image->length;
 
4577
      return (0);
 
4578
      }
 
4579
    else 
 
4580
      {
 
4581
      /* Use one region for margins and fixed width or length areas
 
4582
       * even though it was not formally declared as a region.
 
4583
       */
 
4584
      crop->selections = 1;
 
4585
      crop->zones = 1;
 
4586
      crop->zonelist[0].total = 1;
 
4587
      crop->zonelist[0].position = 1;
 
4588
      }
 
4589
    }     
 
4590
  else
 
4591
    crop->selections = crop->zones;
 
4592
 
 
4593
  for (i = 0; i < crop->zones; i++)
 
4594
    {
 
4595
    seg = crop->zonelist[i].position;
 
4596
    total = crop->zonelist[i].total;
 
4597
 
 
4598
    switch (crop->edge_ref) 
 
4599
      {
 
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;
 
4604
 
 
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;
 
4611
           else
 
4612
             crop->regionlist[i].x2 = test - 1;
 
4613
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
 
4614
 
 
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;
 
4619
           else
 
4620
             crop->combined_width = (uint32)zwidth;
 
4621
           break;
 
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;
 
4626
 
 
4627
           test2 = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
 
4628
           if (test2 < 1 )
 
4629
             crop->regionlist[i].y1 = 0;
 
4630
           else
 
4631
             crop->regionlist[i].y1 = test2 + 1;
 
4632
 
 
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;
 
4636
           else 
 
4637
             crop->regionlist[i].y2 = test;
 
4638
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
 
4639
 
 
4640
           /* This is passed to extractCropZone or extractCompositeZones */
 
4641
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
4642
             crop->combined_length += (uint32)zlength;
 
4643
           else
 
4644
             crop->combined_length = (uint32)zlength;
 
4645
           crop->combined_width = (uint32)zwidth;
 
4646
           break;
 
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;
 
4651
 
 
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);
 
4656
 
 
4657
           if (test > image->width - 1)
 
4658
             crop->regionlist[i].x2 = image->width - 1;
 
4659
           else
 
4660
             crop->regionlist[i].x2 = test - 1;
 
4661
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
 
4662
 
 
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;
 
4667
           else
 
4668
             crop->combined_width = (uint32)zwidth;
 
4669
           break;
 
4670
      case EDGE_TOP: /* width from left, zones from top to bottom */
 
4671
      default:
 
4672
           zwidth = offsets.crop_width;
 
4673
           crop->regionlist[i].x1 = offsets.startx;
 
4674
           crop->regionlist[i].x2 = offsets.endx;
 
4675
 
 
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;
 
4680
           else
 
4681
             crop->regionlist[i].y2 = test - 1;
 
4682
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
 
4683
 
 
4684
           /* This is passed to extractCropZone or extractCompositeZones */
 
4685
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
4686
             crop->combined_length += (uint32)zlength;
 
4687
           else
 
4688
             crop->combined_length = (uint32)zlength;
 
4689
           crop->combined_width = (uint32)zwidth;
 
4690
           break;
 
4691
      } /* end switch statement */
 
4692
 
 
4693
    buffsize = (uint32)
 
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;
 
4699
 
 
4700
 
 
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);
 
4706
    }
 
4707
 
 
4708
  return (0);
 
4709
  } /* end getCropOffsets */
 
4710
 
 
4711
 
 
4712
static int
 
4713
computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
 
4714
                           struct pagedef *page, struct pageseg *sections,
 
4715
                           struct dump_opts* dump)
 
4716
  {
 
4717
  double scale;
 
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;
 
4725
  uint32 i, j, k;
 
4726
 
 
4727
  scale = 1.0;
 
4728
  if (page->res_unit == RESUNIT_NONE)
 
4729
    page->res_unit = image->res_unit;
 
4730
 
 
4731
  switch (image->res_unit) {
 
4732
    case RESUNIT_CENTIMETER:
 
4733
         if (page->res_unit == RESUNIT_INCH)
 
4734
           scale = 1.0/2.54;
 
4735
         break;
 
4736
    case RESUNIT_INCH:
 
4737
         if (page->res_unit == RESUNIT_CENTIMETER)
 
4738
             scale = 2.54;
 
4739
         break;
 
4740
    case RESUNIT_NONE: /* Dimensions in pixels */
 
4741
    default:
 
4742
    break;
 
4743
    }
 
4744
 
 
4745
  /* get width, height, resolutions of input image selection */
 
4746
  if (crop->combined_width > 0)
 
4747
    iwidth = crop->combined_width;
 
4748
  else
 
4749
    iwidth = image->width;
 
4750
  if (crop->combined_length > 0)
 
4751
    ilength = crop->combined_length;
 
4752
  else
 
4753
    ilength = image->length;
 
4754
 
 
4755
  if (page->hres <= 1.0)
 
4756
    page->hres = image->xres;
 
4757
  if (page->vres <= 1.0)
 
4758
    page->vres = image->yres;
 
4759
 
 
4760
  if ((page->hres < 1.0) || (page->vres < 1.0))
 
4761
    {
 
4762
    TIFFError("computeOutputPixelOffsets",
 
4763
    "Invalid horizontal or vertical resolution specified or read from input image");
 
4764
    return (1);
 
4765
    }
 
4766
 
 
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.
 
4769
   */
 
4770
  if (page->width <= 0)
 
4771
    pwidth = iwidth;
 
4772
  else
 
4773
    pwidth = page->width;
 
4774
 
 
4775
  if (page->length <= 0)
 
4776
    plength = ilength;
 
4777
  else
 
4778
    plength = page->length;
 
4779
 
 
4780
  if (dump->debug)
 
4781
    {
 
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);
 
4788
    }
 
4789
 
 
4790
  /* compute margins at specified unit and resolution */
 
4791
  if (page->mode & PAGE_MODE_MARGINS)
 
4792
    {
 
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));
 
4797
      }
 
4798
    else
 
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));
 
4802
      }
 
4803
 
 
4804
    if ((hmargin * 2.0) > (pwidth * page->hres))
 
4805
      {
 
4806
      TIFFError("computeOutputPixelOffsets", 
 
4807
                "Combined left and right margins exceed page width");
 
4808
      hmargin = (uint32) 0;
 
4809
      return (-1);
 
4810
      }
 
4811
    if ((vmargin * 2.0) > (plength * page->vres))
 
4812
      {
 
4813
      TIFFError("computeOutputPixelOffsets", 
 
4814
                "Combined top and bottom margins exceed page length"); 
 
4815
      vmargin = (uint32) 0; 
 
4816
      return (-1);
 
4817
      }
 
4818
    }
 
4819
  else
 
4820
    {
 
4821
    hmargin = 0;
 
4822
    vmargin = 0;
 
4823
    }
 
4824
 
 
4825
  if (page->mode & PAGE_MODE_ROWSCOLS )
 
4826
    {
 
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"); 
 
4831
 
 
4832
    owidth  = TIFFhowmany(iwidth, page->cols);
 
4833
    olength = TIFFhowmany(ilength, page->rows);
 
4834
    }
 
4835
  else
 
4836
    {
 
4837
    if (page->mode & PAGE_MODE_PAPERSIZE )
 
4838
      {
 
4839
      owidth  = (uint32)((pwidth * page->hres) - (hmargin * 2));
 
4840
      olength = (uint32)((plength * page->vres) - (vmargin * 2));
 
4841
      }
 
4842
    else
 
4843
      {
 
4844
      owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
 
4845
      olength = (uint32)(ilength - (vmargin * 2 * page->vres));
 
4846
      }
 
4847
    }
 
4848
 
 
4849
  if (owidth > iwidth)
 
4850
    owidth = iwidth;
 
4851
  if (olength > ilength)
 
4852
    olength = ilength;
 
4853
 
 
4854
  /* Compute the number of pages required for Portrait or Landscape */
 
4855
  switch (page->orient)
 
4856
    {
 
4857
    case ORIENTATION_NONE:
 
4858
    case ORIENTATION_PORTRAIT:
 
4859
         ocols = TIFFhowmany(iwidth, owidth);
 
4860
         orows = TIFFhowmany(ilength, olength);
 
4861
         orientation = ORIENTATION_PORTRAIT;
 
4862
         break;
 
4863
 
 
4864
    case ORIENTATION_LANDSCAPE:
 
4865
         ocols = TIFFhowmany(iwidth, olength);
 
4866
         orows = TIFFhowmany(ilength, owidth);
 
4867
         x1 = olength;
 
4868
         olength = owidth;
 
4869
         owidth = x1;
 
4870
         orientation = ORIENTATION_LANDSCAPE;
 
4871
         break;
 
4872
 
 
4873
    case ORIENTATION_AUTO:
 
4874
    default:
 
4875
         x1 = TIFFhowmany(iwidth, owidth);
 
4876
         x2 = TIFFhowmany(ilength, olength); 
 
4877
         y1 = TIFFhowmany(iwidth, olength);
 
4878
         y2 = TIFFhowmany(ilength, owidth); 
 
4879
 
 
4880
         if ( (x1 * x2) < (y1 * y2))
 
4881
           { /* Portrait */
 
4882
           ocols = x1;
 
4883
           orows = x2;
 
4884
           orientation = ORIENTATION_PORTRAIT;
 
4885
           }
 
4886
         else
 
4887
           { /* Landscape */
 
4888
           ocols = y1;
 
4889
           orows = y2;
 
4890
           x1 = olength;
 
4891
           olength = owidth;
 
4892
           owidth = x1;
 
4893
           orientation = ORIENTATION_LANDSCAPE;
 
4894
           }
 
4895
    }
 
4896
 
 
4897
  if (ocols < 1)
 
4898
    ocols = 1;
 
4899
  if (orows < 1)
 
4900
    orows = 1;
 
4901
 
 
4902
  /* If user did not specify rows and cols, set them from calcuation */
 
4903
  if (page->rows < 1)
 
4904
    page->rows = orows;
 
4905
  if (page->cols < 1)
 
4906
    page->cols = ocols;
 
4907
 
 
4908
  line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
 
4909
 
 
4910
  if ((page->rows * page->cols) > MAX_SECTIONS)
 
4911
   {
 
4912
   TIFFError("computeOutputPixelOffsets",
 
4913
             "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
 
4914
   return (-1);
 
4915
   }
 
4916
 
 
4917
  /* build the list of offsets for each output section */
 
4918
  for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
 
4919
    {
 
4920
    y1 = (uint32)(olength * i);
 
4921
    y2 = (uint32)(olength * (i +  1) - 1);
 
4922
    if (y2 >= ilength)
 
4923
      y2 = ilength - 1;
 
4924
    for (j = 0; j < ocols; j++, k++)
 
4925
      {
 
4926
      x1 = (uint32)(owidth * j); 
 
4927
      x2 = (uint32)(owidth * (j + 1) - 1);
 
4928
      if (x2 >= iwidth)
 
4929
        x2 = iwidth - 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;
 
4937
      } 
 
4938
    } 
 
4939
  return (0);
 
4940
  } /* end computeOutputPixelOffsets */
 
4941
 
 
4942
static int
 
4943
loadImage(TIFF* in, struct image_data *image, struct dump_opts * dump, unsigned char **read_ptr)
 
4944
  {
 
4945
  uint32   i;
 
4946
  float    xres, yres;
 
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;
 
4952
  int      readunit = 0;
 
4953
  static   uint32  prev_readsize = 0;
 
4954
 
 
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);
 
4966
 
 
4967
  image->bps = bps;
 
4968
  image->spp = spp;
 
4969
  image->planar = planar;
 
4970
  image->width = width;
 
4971
  image->length = length;
 
4972
  image->xres = xres;
 
4973
  image->yres = yres;
 
4974
  image->res_unit = res_unit;
 
4975
  image->photometric = photometric;
 
4976
  image->orientation = orientation;
 
4977
  switch (orientation)
 
4978
    {
 
4979
    case 0:
 
4980
    case ORIENTATION_TOPLEFT:
 
4981
         image->adjustments = 0;
 
4982
         break;
 
4983
    case ORIENTATION_TOPRIGHT:
 
4984
         image->adjustments = MIRROR_HORIZ;
 
4985
         break;
 
4986
    case ORIENTATION_BOTRIGHT:
 
4987
         image->adjustments = ROTATECW_180;
 
4988
         break;
 
4989
    case ORIENTATION_BOTLEFT:
 
4990
         image->adjustments = MIRROR_VERT; 
 
4991
         break;
 
4992
    case ORIENTATION_LEFTTOP:
 
4993
         image->adjustments = MIRROR_VERT | ROTATECW_90;
 
4994
         break;
 
4995
    case ORIENTATION_RIGHTTOP:
 
4996
         image->adjustments = ROTATECW_90;
 
4997
         break;
 
4998
    case ORIENTATION_RIGHTBOT:
 
4999
         image->adjustments = MIRROR_VERT | ROTATECW_270;
 
5000
         break; 
 
5001
    case ORIENTATION_LEFTBOT:
 
5002
         image->adjustments = ROTATECW_270;
 
5003
         break;
 
5004
    default:
 
5005
         image->adjustments = 0;
 
5006
         image->orientation = ORIENTATION_TOPLEFT;
 
5007
   }
 
5008
 
 
5009
  if ((bps == 0) || (spp == 0))
 
5010
    {
 
5011
    TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
 
5012
               spp, bps);
 
5013
    return (-1);
 
5014
    }
 
5015
 
 
5016
  if (TIFFIsTiled(in))
 
5017
    {
 
5018
    readunit = TILE;
 
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);
 
5026
    }
 
5027
  else
 
5028
    {
 
5029
    readunit = STRIP;
 
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);
 
5038
    }
 
5039
 
 
5040
  read_buff = *read_ptr;
 
5041
  if (!read_buff)
 
5042
    read_buff = (unsigned char *)_TIFFmalloc(buffsize);
 
5043
  else
 
5044
    {
 
5045
    if (prev_readsize < buffsize)
 
5046
      {
 
5047
      new_buff = _TIFFrealloc(read_buff, buffsize);
 
5048
      if (!new_buff)
 
5049
        {
 
5050
        free (read_buff);
 
5051
        read_buff = (unsigned char *)_TIFFmalloc(buffsize);
 
5052
        }
 
5053
      else
 
5054
        read_buff = new_buff;
 
5055
      }
 
5056
    }
 
5057
 
 
5058
  if (!read_buff)
 
5059
    {
 
5060
    TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
 
5061
    return (-1);
 
5062
    }
 
5063
  _TIFFmemset(read_buff, '\0', buffsize);
 
5064
  prev_readsize = buffsize;
 
5065
  *read_ptr = read_buff;
 
5066
 
 
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.
 
5070
   */
 
5071
  switch (readunit) {
 
5072
    case STRIP:
 
5073
         if (planar == PLANARCONFIG_CONTIG)
 
5074
           {
 
5075
           if (!(readContigStripsIntoBuffer(in, read_buff, length, width, spp)))
 
5076
             {
 
5077
             TIFFError("loadImage", "Unable to read contiguous strips into buffer");
 
5078
             return (-1);
 
5079
             }
 
5080
           }
 
5081
         else
 
5082
           {
 
5083
           if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
 
5084
             {
 
5085
             TIFFError("loadImage", "Unable to read separate strips into buffer");
 
5086
             return (-1);
 
5087
             }
 
5088
           }
 
5089
         break;
 
5090
 
 
5091
    case TILE:
 
5092
         if (planar == PLANARCONFIG_CONTIG)
 
5093
           {
 
5094
           if (!(readContigTilesIntoBuffer(in, read_buff, length, width, spp)))
 
5095
             {
 
5096
             TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
 
5097
             return (-1);
 
5098
             }
 
5099
           }
 
5100
         else
 
5101
           {
 
5102
           if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, spp)))
 
5103
             {
 
5104
             TIFFError("loadImage", "Unable to read separate tiles into buffer");
 
5105
             return (-1);
 
5106
             }
 
5107
           }
 
5108
         break;
 
5109
    default: TIFFError("loadImage", "Unsupported image file format");
 
5110
          return (-1);
 
5111
          break;
 
5112
    }
 
5113
  if ((dump->infile != NULL) && (dump->level == 2))
 
5114
    {
 
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);
 
5120
 
 
5121
    for (i = 0; i < length; i++)
 
5122
      dump_buffer(dump->infile, dump->format, 1, scanlinesize, 
 
5123
                  i, read_buff + (i * scanlinesize));
 
5124
    }
 
5125
  return (0);
 
5126
  }   /* end loadImage */
 
5127
 
 
5128
static int  correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
 
5129
  {
 
5130
  uint16 mirror, rotation;
 
5131
  unsigned char *work_buff;
 
5132
 
 
5133
  work_buff = *work_buff_ptr;
 
5134
  if ((image == NULL) || (work_buff == NULL))
 
5135
    {
 
5136
    TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
 
5137
    return (-1);
 
5138
    }
 
5139
 
 
5140
  if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
 
5141
    {
 
5142
    mirror = (uint16)(image->adjustments & MIRROR_BOTH);
 
5143
    if (mirrorImage(image->spp, image->bps, mirror, 
 
5144
        image->width, image->length, work_buff))
 
5145
      {
 
5146
      TIFFError ("correct_orientation", "Unable to mirror image");
 
5147
      return (-1);
 
5148
      }
 
5149
    }
 
5150
 
 
5151
  if (image->adjustments & ROTATE_ANY)
 
5152
    {
 
5153
    if (image->adjustments & ROTATECW_90)
 
5154
      rotation = (uint16) 90;
 
5155
    else
 
5156
    if (image->adjustments & ROTATECW_180)
 
5157
      rotation = (uint16) 180;
 
5158
    else
 
5159
    if (image->adjustments & ROTATECW_270)
 
5160
      rotation = (uint16) 270;
 
5161
    else
 
5162
      {
 
5163
      TIFFError ("correct_orientation", "Invalid rotation value: %d", 
 
5164
                  image->adjustments & ROTATE_ANY);
 
5165
      return (-1);
 
5166
      }
 
5167
 
 
5168
    if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
 
5169
      {
 
5170
      TIFFError ("correct_orientation", "Unable to rotate image");
 
5171
      return (-1);
 
5172
      }
 
5173
    image->orientation = ORIENTATION_TOPLEFT;
 
5174
    }
 
5175
 
 
5176
  return (0);
 
5177
  } /* end correct_orientation */
 
5178
 
 
5179
 
 
5180
/* Extract multiple zones from an image and combine into a single composite image */
 
5181
static int
 
5182
extractCompositeRegions(struct image_data *image,  struct crop_mask *crop, 
 
5183
                        unsigned char *read_buff, unsigned char *crop_buff)
 
5184
  {
 
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;
 
5191
  uint16    bps, spp;
 
5192
  uint8    *src, *dst;
 
5193
  tsample_t count, sample = 0;   /* Update to extract one or more samples */
 
5194
 
 
5195
  img_width = image->width;
 
5196
  img_length = image->length;
 
5197
  bps = image->bps;
 
5198
  spp = image->spp;
 
5199
  count = spp;
 
5200
 
 
5201
  bytes_per_sample = (bps + 7) / 8; 
 
5202
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
5203
  if ((bps % 8) == 0)
 
5204
    shift_width = 0;
 
5205
  else
 
5206
    {
 
5207
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
5208
      shift_width = bytes_per_pixel;
 
5209
    else
 
5210
      shift_width = bytes_per_sample + 1;
 
5211
    }
 
5212
  src = read_buff;
 
5213
  dst = crop_buff;
 
5214
 
 
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;
 
5221
 
 
5222
  for (i = 0; i < crop->selections; i++)
 
5223
    {
 
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;
 
5229
 
 
5230
    crop_width = last_col - first_col + 1;
 
5231
    crop_length = last_row - first_row + 1;
 
5232
 
 
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;
 
5237
 
 
5238
    src_rowsize = ((img_width * bps * spp) + 7) / 8;
 
5239
    dst_rowsize = (((crop_width * bps * count) + 7) / 8);
 
5240
 
 
5241
    switch (crop->edge_ref)
 
5242
      {
 
5243
      default:
 
5244
      case EDGE_TOP:
 
5245
      case EDGE_BOTTOM:
 
5246
           if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
 
5247
             {
 
5248
             TIFFError ("extractCompositeRegions", 
 
5249
                          "Only equal width regions can be combined for -E top or bottom");
 
5250
             return (1);
 
5251
             }
 
5252
 
 
5253
           crop->combined_width = crop_width;
 
5254
           crop->combined_length += crop_length;
 
5255
 
 
5256
           for (row = first_row; row <= last_row; row++)
 
5257
             {
 
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)
 
5263
               {
 
5264
               case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
 
5265
                                                      spp, bps, count, first_col,
 
5266
                                                      last_col + 1))
 
5267
                         {
 
5268
                         TIFFError("extractCompositeRegions",
 
5269
                                   "Unable to extract row %d", row);
 
5270
                         return (1);
 
5271
                         }
 
5272
                       break;
 
5273
               case 1:  if (extractContigSamplesShifted8bits (src, dst, img_width,
 
5274
                                                              sample, spp, bps, count, 
 
5275
                                                              first_col, last_col + 1,
 
5276
                                                              prev_trailing_bits))
 
5277
                          {
 
5278
                          TIFFError("extractCompositeRegions",
 
5279
                                    "Unable to extract row %d", row);
 
5280
                          return (1);
 
5281
                          }
 
5282
                        break;
 
5283
               case 2:  if (extractContigSamplesShifted16bits (src, dst, img_width,
 
5284
                                                               sample, spp, bps, count, 
 
5285
                                                               first_col, last_col + 1,
 
5286
                                                               prev_trailing_bits))
 
5287
                          {
 
5288
                          TIFFError("extractCompositeRegions",
 
5289
                                    "Unable to extract row %d", row);
 
5290
                          return (1);
 
5291
                          }
 
5292
                        break;
 
5293
               case 3:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
5294
                                                               sample, spp, bps, count, 
 
5295
                                                               first_col, last_col + 1,
 
5296
                                                               prev_trailing_bits))
 
5297
                          {
 
5298
                          TIFFError("extractCompositeRegions",
 
5299
                                    "Unable to extract row %d", row);
 
5300
                          return (1);
 
5301
                          }
 
5302
                        break;
 
5303
               case 4:
 
5304
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
5305
                                                               sample, spp, bps, count, 
 
5306
                                                               first_col, last_col + 1,
 
5307
                                                               prev_trailing_bits))
 
5308
                          {
 
5309
                          TIFFError("extractCompositeRegions",
 
5310
                                    "Unable to extract row %d", row);
 
5311
                          return (1);
 
5312
                          }
 
5313
                        break;
 
5314
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
 
5315
                        return (1);
 
5316
               }
 
5317
             }
 
5318
           prev_length += crop_length;
 
5319
           break;
 
5320
      case EDGE_LEFT:  /* splice the pieces of each row together, side by side */
 
5321
      case EDGE_RIGHT:
 
5322
           if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
 
5323
             {
 
5324
             TIFFError ("extractCompositeRegions", 
 
5325
                          "Only equal length regions can be combined for -E left or right");
 
5326
             return (1);
 
5327
             }
 
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++)
 
5333
             {
 
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;
 
5338
 
 
5339
             switch (shift_width)
 
5340
               {
 
5341
               case 0: if (extractContigSamplesBytes (src, dst, img_width,
 
5342
                                                      sample, spp, bps, count,
 
5343
                                                      first_col, last_col + 1))
 
5344
                         {
 
5345
                         TIFFError("extractCompositeRegions",
 
5346
                                   "Unable to extract row %d", row);
 
5347
                         return (1);
 
5348
                         }
 
5349
                       break;
 
5350
               case 1:  if (extractContigSamplesShifted8bits (src, dst, img_width,
 
5351
                                                              sample, spp, bps, count, 
 
5352
                                                              first_col, last_col + 1,
 
5353
                                                              prev_trailing_bits))
 
5354
                          {
 
5355
                          TIFFError("extractCompositeRegions",
 
5356
                                    "Unable to extract row %d", row);
 
5357
                          return (1);
 
5358
                          }
 
5359
                        break;
 
5360
               case 2:  if (extractContigSamplesShifted16bits (src, dst, img_width,
 
5361
                                                               sample, spp, bps, count, 
 
5362
                                                               first_col, last_col + 1,
 
5363
                                                               prev_trailing_bits))
 
5364
                          {
 
5365
                          TIFFError("extractCompositeRegions",
 
5366
                                    "Unable to extract row %d", row);
 
5367
                          return (1);
 
5368
                          }
 
5369
                        break;
 
5370
               case 3:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
5371
                                                               sample, spp, bps, count, 
 
5372
                                                               first_col, last_col + 1,
 
5373
                                                               prev_trailing_bits))
 
5374
                          {
 
5375
                          TIFFError("extractCompositeRegions",
 
5376
                                    "Unable to extract row %d", row);
 
5377
                          return (1);
 
5378
                          }
 
5379
                        break;
 
5380
               case 4:
 
5381
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
5382
                                                               sample, spp, bps, count, 
 
5383
                                                               first_col, last_col + 1,
 
5384
                                                               prev_trailing_bits))
 
5385
                          {
 
5386
                          TIFFError("extractCompositeRegions",
 
5387
                                    "Unable to extract row %d", row);
 
5388
                          return (1);
 
5389
                          }
 
5390
                        break;
 
5391
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
 
5392
                        return (1);
 
5393
               }
 
5394
             }
 
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;
 
5399
           break;
 
5400
      }
 
5401
    }
 
5402
  if (crop->combined_width != composite_width)
 
5403
    TIFFError("combineSeparateRegions","Combined width does not match composite width");
 
5404
      
 
5405
  return (0);
 
5406
  }  /* end extractCompositeRegions */
 
5407
 
 
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.
 
5417
 */
 
5418
 
 
5419
static int
 
5420
extractSeparateRegion(struct image_data *image,  struct crop_mask *crop,
 
5421
                      unsigned char *read_buff, unsigned char *crop_buff,
 
5422
                      int region)
 
5423
  {
 
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;
 
5430
  uint16  bps, spp;
 
5431
  uint8  *src, *dst;
 
5432
  tsample_t count, sample = 0;   /* Update to extract more or more samples */
 
5433
 
 
5434
  img_width = image->width;
 
5435
  img_length = image->length;
 
5436
  bps = image->bps;
 
5437
  spp = image->spp;
 
5438
  count = spp;
 
5439
 
 
5440
  bytes_per_sample = (bps + 7) / 8; 
 
5441
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
5442
  if ((bps % 8) == 0)
 
5443
    shift_width = 0; /* Byte aligned data only */
 
5444
  else
 
5445
    {
 
5446
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
5447
      shift_width = bytes_per_pixel;
 
5448
    else
 
5449
      shift_width = bytes_per_sample + 1;
 
5450
    }
 
5451
 
 
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;
 
5457
 
 
5458
  crop_width = last_col - first_col + 1;
 
5459
  crop_length = last_row - first_row + 1;
 
5460
 
 
5461
  crop->regionlist[region].width = crop_width;
 
5462
  crop->regionlist[region].length = crop_length;
 
5463
  crop->regionlist[region].buffptr = crop_buff;
 
5464
 
 
5465
  src = read_buff;
 
5466
  dst = crop_buff;
 
5467
  src_rowsize = ((img_width * bps * spp) + 7) / 8;
 
5468
  dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
 
5469
 
 
5470
  for (row = first_row; row <= last_row; row++)
 
5471
    {
 
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;
 
5476
 
 
5477
    switch (shift_width)
 
5478
      {
 
5479
      case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
 
5480
                                             spp, bps, count, first_col,
 
5481
                                             last_col + 1))
 
5482
                {
 
5483
                TIFFError("extractSeparateRegion",
 
5484
                          "Unable to extract row %d", row);
 
5485
                return (1);
 
5486
                }
 
5487
              break;
 
5488
      case 1: if (extractContigSamplesShifted8bits (src, dst, img_width,
 
5489
                                                    sample, spp, bps, count, 
 
5490
                                                    first_col, last_col + 1,
 
5491
                                                    prev_trailing_bits))
 
5492
                {
 
5493
                TIFFError("extractSeparateRegion",
 
5494
                         "Unable to extract row %d", row);
 
5495
                return (1);
 
5496
                }
 
5497
              break;
 
5498
     case 2:  if (extractContigSamplesShifted16bits (src, dst, img_width,
 
5499
                                                     sample, spp, bps, count, 
 
5500
                                                     first_col, last_col + 1,
 
5501
                                                     prev_trailing_bits))
 
5502
                {
 
5503
                TIFFError("extractSeparateRegion",
 
5504
                          "Unable to extract row %d", row);
 
5505
                return (1);
 
5506
                }
 
5507
              break;
 
5508
     case 3:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
5509
                                                     sample, spp, bps, count, 
 
5510
                                                     first_col, last_col + 1,
 
5511
                                                     prev_trailing_bits))
 
5512
                {
 
5513
                TIFFError("extractSeparateRegion",
 
5514
                          "Unable to extract row %d", row);
 
5515
                return (1);
 
5516
                }
 
5517
              break;
 
5518
     case 4:
 
5519
     case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
5520
                                                     sample, spp, bps, count, 
 
5521
                                                     first_col, last_col + 1,
 
5522
                                                     prev_trailing_bits))
 
5523
                {
 
5524
                TIFFError("extractSeparateRegion",
 
5525
                          "Unable to extract row %d", row);
 
5526
                return (1);
 
5527
                }
 
5528
              break;
 
5529
      default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
 
5530
               return (1);
 
5531
      }
 
5532
    }
 
5533
          
 
5534
  return (0);
 
5535
  }  /* end extractSeparateRegion */
 
5536
 
 
5537
static int
 
5538
extractImageSection(struct image_data *image, struct pageseg *section, 
 
5539
                    unsigned char *src_buff, unsigned char *sect_buff)
 
5540
  {
 
5541
  unsigned  char  bytebuff1, bytebuff2;
 
5542
  unsigned  char *src, *dst;
 
5543
 
 
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;
 
5550
  uint16    bps, spp;
 
5551
 
 
5552
#ifdef DEBUG2
 
5553
  int      k;
 
5554
  unsigned char bitset;
 
5555
  static char *bitarray = NULL;
 
5556
#endif
 
5557
 
 
5558
  img_width = image->width;
 
5559
  img_length = image->length;
 
5560
  bps = image->bps;
 
5561
  spp = image->spp;
 
5562
 
 
5563
  src = src_buff;
 
5564
  dst = sect_buff;
 
5565
  src_offset = 0;
 
5566
  dst_offset = 0;
 
5567
 
 
5568
#ifdef DEBUG2
 
5569
  if (bitarray == NULL)
 
5570
    {
 
5571
    if ((bitarray = (char *)malloc(img_width)) == NULL)
 
5572
      {
 
5573
      TIFFError ("", "DEBUG: Unable to allocate debugging bitarray\n");
 
5574
      return (-1);
 
5575
      }
 
5576
    }
 
5577
#endif
 
5578
 
 
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;
 
5584
 
 
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;
 
5590
 
 
5591
#ifdef DEBUG2
 
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);
 
5598
#endif
 
5599
 
 
5600
  if ((bps % 8) == 0)
 
5601
    {
 
5602
    col_offset = first_col * spp * bps / 8;
 
5603
    for (row = first_row; row <= last_row; row++)
 
5604
      {
 
5605
      /* row_offset = row * img_width * spp * bps / 8; */
 
5606
      row_offset = row * img_rowsize;
 
5607
      src_offset = row_offset + col_offset;
 
5608
 
 
5609
#ifdef DEBUG2
 
5610
        TIFFError ("", "Src offset: %8d, Dst offset: %8d\n", src_offset, dst_offset); 
 
5611
#endif
 
5612
      _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
 
5613
      dst_offset += full_bytes;
 
5614
      }        
 
5615
    }
 
5616
  else
 
5617
    { /* bps != 8 */
 
5618
    shift1  = spp * ((first_col * bps) % 8);
 
5619
    shift2  = spp * ((last_col * bps) % 8);
 
5620
    for (row = first_row; row <= last_row; row++)
 
5621
      {
 
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);
 
5626
 
 
5627
#ifdef DEBUG2
 
5628
      for (j = 0, k = 7; j < 8; j++, k--)
 
5629
        {
 
5630
        bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
 
5631
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5632
        }
 
5633
      sprintf(&bitarray[8], " ");
 
5634
      sprintf(&bitarray[9], " ");
 
5635
      for (j = 10, k = 7; j < 18; j++, k--)
 
5636
        {
 
5637
        bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
 
5638
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5639
        }
 
5640
      bitarray[18] = '\0';
 
5641
      TIFFError ("", "Row: %3d Offset1: %d,  Shift1: %d,    Offset2: %d,  Shift2:  %d\n", 
 
5642
                 row, offset1, shift1, offset2, shift2); 
 
5643
#endif
 
5644
 
 
5645
      bytebuff1 = bytebuff2 = 0;
 
5646
      if (shift1 == 0) /* the region is byte and sample alligned */
 
5647
        {
 
5648
        _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
 
5649
 
 
5650
#ifdef DEBUG2
 
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--)
 
5655
          {
 
5656
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
5657
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5658
          }
 
5659
        bitarray[28] = ' ';
 
5660
        bitarray[29] = ' ';
 
5661
#endif
 
5662
        dst_offset += full_bytes;
 
5663
 
 
5664
        if (trailing_bits != 0)
 
5665
          {
 
5666
          bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
 
5667
          sect_buff[dst_offset] = bytebuff2;
 
5668
#ifdef DEBUG2
 
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--)
 
5672
            {
 
5673
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
5674
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5675
            }
 
5676
          bitarray[38] = '\0';
 
5677
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
 
5678
#endif
 
5679
          dst_offset++;
 
5680
          }
 
5681
        }
 
5682
      else   /* each destination byte will have to be built from two source bytes*/
 
5683
        {
 
5684
#ifdef DEBUG2
 
5685
          TIFFError ("", "        Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset); 
 
5686
#endif
 
5687
        for (j = 0; j <= full_bytes; j++) 
 
5688
          {
 
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));
 
5692
          }
 
5693
#ifdef DEBUG2
 
5694
        sprintf(&bitarray[18], "\n");
 
5695
        sprintf(&bitarray[19], "\t");
 
5696
        for (j = 20, k = 7; j < 28; j++, k--)
 
5697
          {
 
5698
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
5699
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5700
          }
 
5701
        bitarray[28] = ' ';
 
5702
        bitarray[29] = ' ';
 
5703
#endif
 
5704
        dst_offset += full_bytes;
 
5705
 
 
5706
        if (trailing_bits != 0)
 
5707
          {
 
5708
#ifdef DEBUG2
 
5709
            TIFFError ("", "        Trailing bits   src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset); 
 
5710
#endif
 
5711
          if (shift2 > shift1)
 
5712
            {
 
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;
 
5716
#ifdef DEBUG2
 
5717
            TIFFError ("", "        Shift2 > Shift1\n"); 
 
5718
#endif
 
5719
            }
 
5720
          else
 
5721
            {
 
5722
            if (shift2 < shift1)
 
5723
              {
 
5724
              bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
 
5725
              sect_buff[dst_offset] &= bytebuff2;
 
5726
#ifdef DEBUG2
 
5727
              TIFFError ("", "        Shift2 < Shift1\n"); 
 
5728
#endif
 
5729
              }
 
5730
#ifdef DEBUG2
 
5731
            else
 
5732
              TIFFError ("", "        Shift2 == Shift1\n"); 
 
5733
#endif
 
5734
            }
 
5735
          }
 
5736
#ifdef DEBUG2
 
5737
          sprintf(&bitarray[28], " ");
 
5738
          sprintf(&bitarray[29], " ");
 
5739
          for (j = 30, k = 7; j < 38; j++, k--)
 
5740
            {
 
5741
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
5742
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
5743
            }
 
5744
          bitarray[38] = '\0';
 
5745
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
 
5746
#endif
 
5747
        dst_offset++;
 
5748
        }
 
5749
      }
 
5750
    }
 
5751
 
 
5752
  return (0);
 
5753
  } /* end extractImageSection */
 
5754
 
 
5755
static int 
 
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)
 
5760
  {
 
5761
  int i, page_count;
 
5762
  int autoindex = 0;
 
5763
  unsigned char *crop_buff = NULL;
 
5764
 
 
5765
  /* Where we open a new file depends on the export mode */  
 
5766
  switch (crop->exp_mode)
 
5767
    {
 
5768
    case ONE_FILE_COMPOSITE: /* Regions combined into single image */
 
5769
         autoindex = 0;
 
5770
         crop_buff = seg_buffs[0].buffer;
 
5771
         if (update_output_file (out, mp, autoindex, filename, page))
 
5772
           return (1);
 
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))
 
5778
            {
 
5779
             TIFFError("writeRegions", "Unable to write new image");
 
5780
             return (-1);
 
5781
             }
 
5782
         break;
 
5783
    case ONE_FILE_SEPARATED: /* Regions as separated images */
 
5784
         autoindex = 0;
 
5785
         if (update_output_file (out, mp, autoindex, filename, page))
 
5786
           return (1);
 
5787
         page_count = crop->selections * total_pages;
 
5788
         for (i = 0; i < crop->selections; i++)
 
5789
           {
 
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))
 
5795
             {
 
5796
             TIFFError("writeRegions", "Unable to write new image");
 
5797
             return (-1);
 
5798
             }
 
5799
           }
 
5800
         break;
 
5801
    case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
 
5802
         autoindex = 1;
 
5803
         if (update_output_file (out, mp, autoindex, filename, page))
 
5804
           return (1);
 
5805
 
 
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))
 
5811
           {
 
5812
           TIFFError("writeRegions", "Unable to write new image");
 
5813
           return (-1);
 
5814
           }
 
5815
         break;
 
5816
    case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
 
5817
         autoindex = 1;
 
5818
         page_count = crop->selections;
 
5819
         if (update_output_file (out, mp, autoindex, filename, page))
 
5820
           return (1);
 
5821
                
 
5822
         for (i = 0; i < crop->selections; i++)
 
5823
           {
 
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))
 
5830
             {
 
5831
             TIFFError("writeRegions", "Unable to write new image");
 
5832
             return (-1);
 
5833
             }
 
5834
           }
 
5835
         break;
 
5836
    case FILE_PER_SELECTION:
 
5837
         autoindex = 1;
 
5838
         page_count = 1;
 
5839
         for (i = 0; i < crop->selections; i++)
 
5840
           {
 
5841
           if (update_output_file (out, mp, autoindex, filename, page))
 
5842
             return (1);
 
5843
 
 
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))
 
5850
             {
 
5851
             TIFFError("writeRegions", "Unable to write new image");
 
5852
             return (-1);
 
5853
             }
 
5854
           }
 
5855
         break;
 
5856
    default: return (1);
 
5857
    }
 
5858
 
 
5859
  return (0);
 
5860
  } /* end writeRegions */
 
5861
 
 
5862
static int
 
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)
 
5867
  {
 
5868
  double  hres, vres;
 
5869
  uint32  i, k, width, length, sectsize;
 
5870
  unsigned char *sect_buff = *sect_buff_ptr;
 
5871
 
 
5872
  hres = page->hres;
 
5873
  vres = page->vres;
 
5874
 
 
5875
#ifdef DEBUG
 
5876
  TIFFError("",
 
5877
    "Writing %d sections for each original page. Hres: %3.2f Vres: %3.2f\n", 
 
5878
          page->rows * page->cols, hres, vres);
 
5879
#endif
 
5880
  k = page->cols * page->rows;
 
5881
  if ((k < 1) || (k > MAX_SECTIONS))
 
5882
   {
 
5883
   TIFFError("writeImageSections",
 
5884
             "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
 
5885
   return (-1);
 
5886
   }
 
5887
 
 
5888
  for (i = 0; i < k; i++)
 
5889
    {
 
5890
    width  = sections[i].x2 - sections[i].x1 + 1;
 
5891
    length = sections[i].y2 - sections[i].y1 + 1;
 
5892
    sectsize = (uint32)
 
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))
 
5896
      {
 
5897
      TIFFError("writeImageSections", "Unable to allocate section buffer");
 
5898
      exit (-1);
 
5899
      }
 
5900
    sect_buff = *sect_buff_ptr;
 
5901
 
 
5902
#ifdef DEBUG
 
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);
 
5905
#endif
 
5906
 
 
5907
    if (extractImageSection (image, &sections[i], src_buff, sect_buff))
 
5908
      {
 
5909
      TIFFError("writeImageSections", "Unable to extract image sections");
 
5910
      exit (-1);
 
5911
      }
 
5912
 
 
5913
  /* call the write routine here instead of outside the loop */
 
5914
    if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
 
5915
      {
 
5916
      TIFFError("writeImageSections", "Unable to write image section");
 
5917
      exit (-1);
 
5918
      }
 
5919
    }
 
5920
 
 
5921
  return (0);
 
5922
  } /* end writeImageSections */
 
5923
 
 
5924
/* Code in this function is heavily indebted to code in tiffcp
 
5925
 * with modifications by Richard Nolde to handle orientation correctly.
 
5926
 */
 
5927
static int  
 
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)
 
5932
  {
 
5933
  uint16 bps, spp;
 
5934
  struct cpTag* p;
 
5935
 
 
5936
#ifdef DEBUG
 
5937
  TIFFError ("",
 
5938
"\nWriting single section: Width %d Length: %d Hres: %4.1f, Vres: %4.1f\n\n",
 
5939
           width, length, hres, vres);
 
5940
#endif
 
5941
  TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
 
5942
  TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
 
5943
 
 
5944
  CopyField(TIFFTAG_BITSPERSAMPLE, bps);
 
5945
  CopyField(TIFFTAG_SAMPLESPERPIXEL, spp);
 
5946
  if (compression != (uint16)-1)
 
5947
    TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
5948
  else
 
5949
    CopyField(TIFFTAG_COMPRESSION, compression);
 
5950
 
 
5951
  if (compression == COMPRESSION_JPEG) {
 
5952
    uint16 input_compression, input_photometric;
 
5953
 
 
5954
    if (TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression)
 
5955
        && input_compression == COMPRESSION_JPEG) {
 
5956
          TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
5957
        }
 
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);
 
5962
           else
 
5963
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
5964
           } else
 
5965
              TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
 
5966
        }
 
5967
      }
 
5968
  else 
 
5969
    {
 
5970
    if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
 
5971
       TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
 
5972
                        PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
5973
    else
 
5974
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
 
5975
    }
 
5976
  if (fillorder != 0)
 
5977
    TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
 
5978
  else
 
5979
    CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
 
5980
 
 
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.
 
5987
   */
 
5988
  TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
 
5989
 
 
5990
  /*
 
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.
 
5994
   */
 
5995
  if (outtiled == -1)
 
5996
    outtiled = TIFFIsTiled(in);
 
5997
  if (outtiled) {
 
5998
    /*
 
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
 
6002
     * library default.
 
6003
     */
 
6004
    if (tilewidth == (uint32) -1)
 
6005
      TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
 
6006
    if (tilelength == (uint32) -1)
 
6007
      TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
 
6008
 
 
6009
    if (tilewidth > width)
 
6010
      tilewidth = width;
 
6011
    if (tilelength > length)
 
6012
      tilelength = length;
 
6013
 
 
6014
    TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
6015
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
 
6016
    TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
 
6017
    } else {
 
6018
       /*
 
6019
        * RowsPerStrip is left unspecified: use either the
 
6020
        * value from the input image or, if nothing is defined,
 
6021
        * use the library default.
 
6022
        */
 
6023
        if (rowsperstrip == (uint32) 0) {
 
6024
          if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip)) {
 
6025
              rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
 
6026
             }
 
6027
          if (rowsperstrip > length && rowsperstrip != (uint32)-1)
 
6028
               rowsperstrip = length;
 
6029
          }
 
6030
        else if (rowsperstrip == (uint32) -1)
 
6031
                rowsperstrip = length;
 
6032
                TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
6033
        }
 
6034
  if (config != (uint16) -1)
 
6035
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
6036
  else
 
6037
    CopyField(TIFFTAG_PLANARCONFIG, config);
 
6038
  if (spp <= 4)
 
6039
    CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
 
6040
  CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
 
6041
 
 
6042
/* SMinSampleValue & SMaxSampleValue */
 
6043
  switch (compression) {
 
6044
    case COMPRESSION_JPEG:
 
6045
         TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
6046
         TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
 
6047
         break;
 
6048
   case COMPRESSION_LZW:
 
6049
   case COMPRESSION_ADOBE_DEFLATE:
 
6050
   case COMPRESSION_DEFLATE:
 
6051
        if (predictor != (uint16)-1)
 
6052
          TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
6053
        else
 
6054
          CopyField(TIFFTAG_PREDICTOR, predictor);
 
6055
        break;
 
6056
   case COMPRESSION_CCITTFAX3:
 
6057
   case COMPRESSION_CCITTFAX4:
 
6058
        if (compression == COMPRESSION_CCITTFAX3) {
 
6059
          if (g3opts != (uint32) -1)
 
6060
            TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
 
6061
          else
 
6062
            CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
 
6063
        } else
 
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);
 
6071
        break;
 
6072
   }
 
6073
   { uint32 len32;
 
6074
     void** data;
 
6075
     if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
 
6076
       TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
 
6077
   }
 
6078
   { uint16 ninks;
 
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;
 
6085
         while (ninks > 1) {
 
6086
           cp = strchr(cp, '\0');
 
6087
           if (cp) {
 
6088
             cp++;
 
6089
             inknameslen += (strlen(cp) + 1);
 
6090
           }
 
6091
           ninks--;
 
6092
         }
 
6093
         TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
 
6094
       }
 
6095
     }
 
6096
   }
 
6097
   {
 
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);
 
6102
     else 
 
6103
        TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
 
6104
     }
 
6105
   }
 
6106
 
 
6107
  for (p = tags; p < &tags[NTAGS]; p++)
 
6108
                CopyTag(p->tag, p->count, p->type);
 
6109
 
 
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);
 
6113
 
 
6114
  /* Compute the tile or strip dimensions and write to disk */
 
6115
  if (outtiled)
 
6116
    {
 
6117
    if (config == PLANARCONFIG_CONTIG)
 
6118
      {
 
6119
      writeBufferToContigTiles (out, sect_buff, length, width, spp);
 
6120
      }
 
6121
    else
 
6122
      writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
 
6123
    }
 
6124
  else
 
6125
    {
 
6126
    if (config == PLANARCONFIG_CONTIG)
 
6127
      {
 
6128
      writeBufferToContigStrips (out, sect_buff, length, width, spp);
 
6129
      }
 
6130
    else
 
6131
      {
 
6132
      writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
 
6133
      }
 
6134
    }
 
6135
 
 
6136
  if (!TIFFWriteDirectory(out))
 
6137
    {
 
6138
    TIFFClose(out);
 
6139
    return (-1);
 
6140
    }
 
6141
 
 
6142
  return (0);
 
6143
  } /* end writeSingleSection */
 
6144
 
 
6145
 
 
6146
/* Create a buffer to write one section at a time */
 
6147
static int
 
6148
createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
 
6149
  {
 
6150
  unsigned  char *sect_buff = NULL;
 
6151
  unsigned  char *new_buff  = NULL;
 
6152
  static    uint32  prev_sectsize = 0;
 
6153
  
 
6154
  sect_buff = *sect_buff_ptr;
 
6155
 
 
6156
  if (!sect_buff)
 
6157
    {
 
6158
    sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
 
6159
    *sect_buff_ptr = sect_buff;
 
6160
    _TIFFmemset(sect_buff, 0, sectsize);
 
6161
    }
 
6162
  else
 
6163
    {
 
6164
    if (prev_sectsize < sectsize)
 
6165
      {
 
6166
      new_buff = _TIFFrealloc(sect_buff, sectsize);
 
6167
      if (!new_buff)
 
6168
        {
 
6169
        free (sect_buff);
 
6170
        sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
 
6171
        }
 
6172
      else
 
6173
        sect_buff = new_buff;
 
6174
 
 
6175
      _TIFFmemset(sect_buff, 0, sectsize);
 
6176
      }
 
6177
    }
 
6178
 
 
6179
  if (!sect_buff)
 
6180
    {
 
6181
    TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
 
6182
    return (-1);
 
6183
    }
 
6184
  prev_sectsize = sectsize;
 
6185
  *sect_buff_ptr = sect_buff;
 
6186
 
 
6187
  return (0);
 
6188
  }  /* end createImageSection */
 
6189
 
 
6190
 
 
6191
/* Process selections defined by regions, zones, margins, or fixed sized areas */
 
6192
static int
 
6193
processCropSelections(struct image_data *image, struct crop_mask *crop, 
 
6194
                      unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
 
6195
  {
 
6196
  int       i;
 
6197
  uint32    width, length, total_width, total_length;
 
6198
  tsize_t   cropsize;
 
6199
  unsigned  char *crop_buff = NULL;
 
6200
  unsigned  char *read_buff = NULL;
 
6201
  unsigned  char *next_buff = NULL;
 
6202
  tsize_t   prev_cropsize = 0;
 
6203
 
 
6204
  read_buff = *read_buff_ptr;
 
6205
 
 
6206
  if (crop->img_mode == COMPOSITE_IMAGES)
 
6207
    {
 
6208
    cropsize = crop->bufftotal;
 
6209
    crop_buff = seg_buffs[0].buffer; 
 
6210
    if (!crop_buff)
 
6211
      crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6212
    else
 
6213
      {
 
6214
      prev_cropsize = seg_buffs[0].size;
 
6215
      if (prev_cropsize < cropsize)
 
6216
        {
 
6217
        next_buff = _TIFFrealloc(crop_buff, cropsize);
 
6218
        if (! next_buff)
 
6219
          {
 
6220
          _TIFFfree (crop_buff);
 
6221
          crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6222
          }
 
6223
        else
 
6224
          crop_buff = next_buff;
 
6225
        }
 
6226
      }
 
6227
 
 
6228
    if (!crop_buff)
 
6229
      {
 
6230
      TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
 
6231
      return (-1);
 
6232
      }
 
6233
 
 
6234
    _TIFFmemset(crop_buff, 0, cropsize);
 
6235
    seg_buffs[0].buffer = crop_buff;
 
6236
    seg_buffs[0].size = cropsize;
 
6237
 
 
6238
    /* Checks for matching width or length as required */
 
6239
    if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
 
6240
      return (1);
 
6241
 
 
6242
    if (crop->crop_mode & CROP_INVERT)
 
6243
      {
 
6244
      switch (crop->photometric)
 
6245
        {
 
6246
        /* Just change the interpretation */
 
6247
        case PHOTOMETRIC_MINISWHITE:
 
6248
        case PHOTOMETRIC_MINISBLACK:
 
6249
             image->photometric = crop->photometric;
 
6250
             break;
 
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))
 
6255
               {
 
6256
               TIFFError("processCropSelections", 
 
6257
                         "Failed to invert colorspace for composite regions");
 
6258
               return (-1);
 
6259
               }
 
6260
             if (crop->photometric == INVERT_DATA_AND_TAG)
 
6261
               {
 
6262
               switch (image->photometric)
 
6263
                 {
 
6264
                 case PHOTOMETRIC_MINISWHITE:
 
6265
                      image->photometric = PHOTOMETRIC_MINISBLACK;
 
6266
                      break;
 
6267
                 case PHOTOMETRIC_MINISBLACK:
 
6268
                      image->photometric = PHOTOMETRIC_MINISWHITE;
 
6269
                      break;
 
6270
                 default:
 
6271
                      break;
 
6272
                 }
 
6273
               }
 
6274
             break;
 
6275
        default: break;
 
6276
        }
 
6277
      }
 
6278
 
 
6279
    /* Mirror and Rotate will not work with multiple regions unless they are the same width */
 
6280
    if (crop->crop_mode & CROP_MIRROR)
 
6281
      {
 
6282
      if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
6283
                      crop->combined_width, crop->combined_length, crop_buff))
 
6284
        {
 
6285
        TIFFError("processCropSelections", "Failed to mirror composite regions %s", 
 
6286
                 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
6287
        return (-1);
 
6288
        }
 
6289
      }
 
6290
 
 
6291
    if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
6292
      {
 
6293
      if (rotateImage(crop->rotation, image, &crop->combined_width, 
 
6294
                      &crop->combined_length, &crop_buff))
 
6295
        {
 
6296
        TIFFError("processCropSelections", 
 
6297
                  "Failed to rotate composite regions by %d degrees", crop->rotation);
 
6298
        return (-1);
 
6299
        }
 
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; 
 
6303
      }
 
6304
    }
 
6305
  else  /* Separated Images */
 
6306
    {
 
6307
    total_width = total_length = 0;
 
6308
    for (i = 0; i < crop->selections; i++)
 
6309
      {
 
6310
      cropsize = crop->bufftotal;
 
6311
      crop_buff = seg_buffs[i].buffer; 
 
6312
      if (!crop_buff)
 
6313
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6314
      else
 
6315
        {
 
6316
        prev_cropsize = seg_buffs[0].size;
 
6317
        if (prev_cropsize < cropsize)
 
6318
          {
 
6319
          next_buff = _TIFFrealloc(crop_buff, cropsize);
 
6320
          if (! next_buff)
 
6321
            {
 
6322
            _TIFFfree (crop_buff);
 
6323
            crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6324
            }
 
6325
          else
 
6326
            crop_buff = next_buff;
 
6327
          }
 
6328
        }
 
6329
 
 
6330
      if (!crop_buff)
 
6331
        {
 
6332
        TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
 
6333
        return (-1);
 
6334
        }
 
6335
 
 
6336
      _TIFFmemset(crop_buff, 0, cropsize);
 
6337
      seg_buffs[i].buffer = crop_buff;
 
6338
      seg_buffs[i].size = cropsize;
 
6339
 
 
6340
      if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
 
6341
        {
 
6342
        TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
 
6343
        return (-1);
 
6344
        }
 
6345
    
 
6346
      width  = crop->regionlist[i].width;
 
6347
      length = crop->regionlist[i].length;
 
6348
 
 
6349
      if (crop->crop_mode & CROP_INVERT)
 
6350
        {
 
6351
        switch (crop->photometric)
 
6352
          {
 
6353
          /* Just change the interpretation */
 
6354
          case PHOTOMETRIC_MINISWHITE:
 
6355
          case PHOTOMETRIC_MINISBLACK:
 
6356
               image->photometric = crop->photometric;
 
6357
               break;
 
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))
 
6362
                 {
 
6363
                 TIFFError("processCropSelections", 
 
6364
                           "Failed to invert colorspace for region");
 
6365
                 return (-1);
 
6366
                 }
 
6367
               if (crop->photometric == INVERT_DATA_AND_TAG)
 
6368
                 {
 
6369
                 switch (image->photometric)
 
6370
                   {
 
6371
                   case PHOTOMETRIC_MINISWHITE:
 
6372
                        image->photometric = PHOTOMETRIC_MINISBLACK;
 
6373
                        break;
 
6374
                   case PHOTOMETRIC_MINISBLACK:
 
6375
                        image->photometric = PHOTOMETRIC_MINISWHITE;
 
6376
                        break;
 
6377
                   default:
 
6378
                        break;
 
6379
                   }
 
6380
                 }
 
6381
               break;
 
6382
          default: break;
 
6383
          }
 
6384
        }
 
6385
 
 
6386
      if (crop->crop_mode & CROP_MIRROR)
 
6387
        {
 
6388
        if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
6389
                        width, length, crop_buff))
 
6390
          {
 
6391
          TIFFError("processCropSelections", "Failed to mirror crop region %s", 
 
6392
                   (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
6393
          return (-1);
 
6394
          }
 
6395
        }
 
6396
 
 
6397
      if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
6398
        {
 
6399
        if (rotateImage(crop->rotation, image, &crop->regionlist[i].width, 
 
6400
                        &crop->regionlist[i].length, &crop_buff))
 
6401
          {
 
6402
          TIFFError("processCropSelections", 
 
6403
                    "Failed to rotate crop region by %d degrees", crop->rotation);
 
6404
          return (-1);
 
6405
          }
 
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; 
 
6413
        }
 
6414
      }
 
6415
    }
 
6416
  return (0);
 
6417
  } /* end processCropSelections */
 
6418
 
 
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.
 
6422
 *
 
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.
 
6426
 */
 
6427
static int
 
6428
createCroppedImage(struct image_data *image, struct crop_mask *crop, 
 
6429
                   unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
 
6430
  {
 
6431
  tsize_t   cropsize;
 
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;
 
6436
 
 
6437
  read_buff = *read_buff_ptr;
 
6438
 
 
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;
 
6444
 
 
6445
  cropsize = crop->bufftotal;
 
6446
  crop_buff = *crop_buff_ptr;
 
6447
  if (!crop_buff)
 
6448
    {
 
6449
    crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6450
    *crop_buff_ptr = crop_buff;
 
6451
    _TIFFmemset(crop_buff, 0, cropsize);
 
6452
    prev_cropsize = cropsize;
 
6453
    }
 
6454
  else
 
6455
    {
 
6456
    if (prev_cropsize < cropsize)
 
6457
      {
 
6458
      new_buff = _TIFFrealloc(crop_buff, cropsize);
 
6459
      if (!new_buff)
 
6460
        {
 
6461
        free (crop_buff);
 
6462
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
6463
        }
 
6464
      else
 
6465
        crop_buff = new_buff;
 
6466
      _TIFFmemset(crop_buff, 0, cropsize);
 
6467
      }
 
6468
    }
 
6469
 
 
6470
  if (!crop_buff)
 
6471
    {
 
6472
    TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
 
6473
    return (-1);
 
6474
    }
 
6475
  *crop_buff_ptr = crop_buff;
 
6476
 
 
6477
  if (crop->crop_mode & CROP_INVERT)
 
6478
    {
 
6479
    switch (crop->photometric)
 
6480
      {
 
6481
      /* Just change the interpretation */
 
6482
      case PHOTOMETRIC_MINISWHITE:
 
6483
      case PHOTOMETRIC_MINISBLACK:
 
6484
           image->photometric = crop->photometric;
 
6485
           break;
 
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))
 
6490
             {
 
6491
             TIFFError("createCroppedImage", 
 
6492
                       "Failed to invert colorspace for image or cropped selection");
 
6493
             return (-1);
 
6494
             }
 
6495
           if (crop->photometric == INVERT_DATA_AND_TAG)
 
6496
             {
 
6497
             switch (image->photometric)
 
6498
               {
 
6499
               case PHOTOMETRIC_MINISWHITE:
 
6500
                    image->photometric = PHOTOMETRIC_MINISBLACK;
 
6501
                    break;
 
6502
               case PHOTOMETRIC_MINISBLACK:
 
6503
                    image->photometric = PHOTOMETRIC_MINISWHITE;
 
6504
                    break;
 
6505
               default:
 
6506
                    break;
 
6507
               }
 
6508
             }
 
6509
           break;
 
6510
      default: break;
 
6511
      }
 
6512
    }
 
6513
 
 
6514
  if (crop->crop_mode & CROP_MIRROR)
 
6515
    {
 
6516
    if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
6517
                    crop->combined_width, crop->combined_length, crop_buff))
 
6518
      {
 
6519
      TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s", 
 
6520
               (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
6521
      return (-1);
 
6522
      }
 
6523
    }
 
6524
 
 
6525
  if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
6526
    {
 
6527
    if (rotateImage(crop->rotation, image, &crop->combined_width, 
 
6528
                    &crop->combined_length, crop_buff_ptr))
 
6529
      {
 
6530
      TIFFError("createCroppedImage", 
 
6531
                "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
 
6532
      return (-1);
 
6533
      }
 
6534
    }
 
6535
 
 
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 */
 
6538
 
 
6539
  return (0);
 
6540
  } /* end createCroppedImage */
 
6541
 
 
6542
 
 
6543
/* The code in this function is heavily indebted to code from tiffcp. */
 
6544
static int  
 
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)
 
6548
  {
 
6549
  uint16 bps, spp;
 
6550
  struct cpTag* p;
 
6551
 
 
6552
  TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
 
6553
  TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
 
6554
 
 
6555
  CopyField(TIFFTAG_BITSPERSAMPLE, bps);
 
6556
  CopyField(TIFFTAG_SAMPLESPERPIXEL, spp);
 
6557
  if (compression != (uint16)-1)
 
6558
    TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
6559
  else
 
6560
    CopyField(TIFFTAG_COMPRESSION, compression);
 
6561
 
 
6562
  if (compression == COMPRESSION_JPEG) {
 
6563
    uint16 input_compression, input_photometric;
 
6564
 
 
6565
    if (TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression)
 
6566
        && input_compression == COMPRESSION_JPEG) {
 
6567
          TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
6568
        }
 
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);
 
6573
           else
 
6574
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
6575
           } else
 
6576
              TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
 
6577
        }
 
6578
  }
 
6579
  else
 
6580
    {
 
6581
    if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
 
6582
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
 
6583
                        PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
6584
    else
 
6585
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
 
6586
    }
 
6587
  if (fillorder != 0)
 
6588
    TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
 
6589
  else
 
6590
    CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
 
6591
 
 
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. 
 
6598
   */
 
6599
  TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
 
6600
        
 
6601
  /*
 
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.
 
6605
   */
 
6606
  if (outtiled == -1)
 
6607
    outtiled = TIFFIsTiled(in);
 
6608
  if (outtiled) {
 
6609
    /*
 
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
 
6613
     * library default.
 
6614
     */
 
6615
    if (tilewidth == (uint32) -1)
 
6616
      TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
 
6617
    if (tilelength == (uint32) -1)
 
6618
      TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
 
6619
 
 
6620
    if (tilewidth > width)
 
6621
      tilewidth = width;
 
6622
    if (tilelength > length)
 
6623
      tilelength = length;
 
6624
 
 
6625
    TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
6626
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
 
6627
    TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
 
6628
    } else {
 
6629
       /*
 
6630
        * RowsPerStrip is left unspecified: use either the
 
6631
        * value from the input image or, if nothing is defined,
 
6632
        * use the library default.
 
6633
        */
 
6634
        if (rowsperstrip == (uint32) 0)
 
6635
          {
 
6636
          if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
 
6637
            {
 
6638
            rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
 
6639
            }
 
6640
          if (rowsperstrip > length)
 
6641
            rowsperstrip = length;
 
6642
          }
 
6643
        else 
 
6644
          if (rowsperstrip == (uint32) -1)
 
6645
            rowsperstrip = length;
 
6646
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
6647
        }
 
6648
  if (config != (uint16) -1)
 
6649
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
6650
  else
 
6651
    CopyField(TIFFTAG_PLANARCONFIG, config);
 
6652
  if (spp <= 4)
 
6653
    CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
 
6654
  CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
 
6655
 
 
6656
/* SMinSampleValue & SMaxSampleValue */
 
6657
  switch (compression) {
 
6658
    case COMPRESSION_JPEG:
 
6659
         TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
6660
         TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
 
6661
         break;
 
6662
   case COMPRESSION_LZW:
 
6663
   case COMPRESSION_ADOBE_DEFLATE:
 
6664
   case COMPRESSION_DEFLATE:
 
6665
        if (predictor != (uint16)-1)
 
6666
          TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
6667
        else
 
6668
          CopyField(TIFFTAG_PREDICTOR, predictor);
 
6669
        break;
 
6670
   case COMPRESSION_CCITTFAX3:
 
6671
   case COMPRESSION_CCITTFAX4:
 
6672
        if (compression == COMPRESSION_CCITTFAX3) {
 
6673
          if (g3opts != (uint32) -1)
 
6674
            TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
 
6675
          else
 
6676
            CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
 
6677
        } else
 
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);
 
6685
        break;
 
6686
   }
 
6687
   { uint32 len32;
 
6688
     void** data;
 
6689
     if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
 
6690
       TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
 
6691
   }
 
6692
   { uint16 ninks;
 
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;
 
6699
         while (ninks > 1) {
 
6700
           cp = strchr(cp, '\0');
 
6701
           if (cp) {
 
6702
             cp++;
 
6703
             inknameslen += (strlen(cp) + 1);
 
6704
           }
 
6705
           ninks--;
 
6706
         }
 
6707
         TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
 
6708
       }
 
6709
     }
 
6710
   }
 
6711
   {
 
6712
   unsigned short pg0, pg1;
 
6713
   if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
 
6714
     TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
 
6715
     }
 
6716
   }
 
6717
 
 
6718
  for (p = tags; p < &tags[NTAGS]; p++)
 
6719
                CopyTag(p->tag, p->count, p->type);
 
6720
 
 
6721
  /* Compute the tile or strip dimensions and write to disk */
 
6722
  if (outtiled)
 
6723
    {
 
6724
    if (config == PLANARCONFIG_CONTIG)
 
6725
      {
 
6726
      writeBufferToContigTiles (out, crop_buff, length, width, spp);
 
6727
      }
 
6728
    else
 
6729
      writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump);
 
6730
    }
 
6731
  else
 
6732
    {
 
6733
    if (config == PLANARCONFIG_CONTIG)
 
6734
      {
 
6735
      writeBufferToContigStrips (out, crop_buff, length, width, spp);
 
6736
      }
 
6737
    else
 
6738
      {
 
6739
      writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump);
 
6740
      }
 
6741
    }
 
6742
 
 
6743
  if (!TIFFWriteDirectory(out))
 
6744
    {
 
6745
    TIFFClose(out);
 
6746
    return (-1);
 
6747
    }
 
6748
 
 
6749
  return (0);
 
6750
  } /* end writeCroppedImage */
 
6751
 
 
6752
static int
 
6753
rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
6754
                         uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
6755
  {
 
6756
  int      ready_bits = 0;
 
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;
 
6761
  uint8   *next;
 
6762
  tsample_t sample;
 
6763
 
 
6764
  if ((src == NULL) || (dst == NULL))
 
6765
    {
 
6766
    TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
 
6767
    return (1);
 
6768
    }
 
6769
 
 
6770
  rowsize = ((bps * spp * width) + 7) / 8;
 
6771
  ready_bits = 0;
 
6772
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
6773
  buff1 = buff2 = 0;
 
6774
 
 
6775
  for (row = 0; row < length ; row++)
 
6776
    {
 
6777
    bit_offset = col * bps * spp;
 
6778
    for (sample = 0; sample < spp; sample++)
 
6779
      {
 
6780
      if (sample == 0)
 
6781
        {
 
6782
        src_byte = bit_offset / 8;
 
6783
        src_bit  = bit_offset % 8;
 
6784
        }
 
6785
      else
 
6786
        {
 
6787
        src_byte = (bit_offset + (sample * bps)) / 8;
 
6788
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
6789
        }
 
6790
 
 
6791
      switch (rotation)
 
6792
        {
 
6793
        case  90: next = src + src_byte - (row * rowsize);
 
6794
                  break;
 
6795
        case 270: next = src + src_byte + (row * rowsize);
 
6796
                  break;
 
6797
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
6798
                  return (1);
 
6799
        }
 
6800
      matchbits = maskbits << (8 - src_bit - bps); 
 
6801
      buff1 = ((*next) & matchbits) << (src_bit);
 
6802
 
 
6803
       /* If we have a full buffer's worth, write it out */
 
6804
      if (ready_bits >= 8)
 
6805
        {
 
6806
        *dst++ = buff2;
 
6807
        buff2 = buff1;
 
6808
        ready_bits -= 8;
 
6809
        }
 
6810
      else
 
6811
        {
 
6812
        buff2 = (buff2 | (buff1 >> ready_bits));
 
6813
        }
 
6814
      ready_bits += bps;
 
6815
      }
 
6816
    }
 
6817
 
 
6818
  if (ready_bits > 0)
 
6819
    {
 
6820
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
6821
    *dst++ = buff1;
 
6822
    }
 
6823
 
 
6824
  return (0);
 
6825
  }  /* end rotateContigSamples8bits */
 
6826
 
 
6827
 
 
6828
static int
 
6829
rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
6830
                         uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
6831
  {
 
6832
  int      ready_bits = 0;
 
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;
 
6837
  uint8    bytebuff = 0;
 
6838
  uint8    swapbuff[2];
 
6839
  uint8   *next;
 
6840
  tsample_t sample;
 
6841
 
 
6842
  if ((src == NULL) || (dst == NULL))
 
6843
    {
 
6844
    TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
 
6845
    return (1);
 
6846
    }
 
6847
 
 
6848
  rowsize = ((bps * spp * width) + 7) / 8;
 
6849
  ready_bits = 0;
 
6850
  maskbits =  (uint16)-1 >> (16 - bps);
 
6851
  buff1 = buff2 = 0;
 
6852
  for (row = 0; row < length; row++)
 
6853
    {
 
6854
    bit_offset = col * bps * spp;
 
6855
    for (sample = 0; sample < spp; sample++)
 
6856
      {
 
6857
      if (sample == 0)
 
6858
        {
 
6859
        src_byte = bit_offset / 8;
 
6860
        src_bit  = bit_offset % 8;
 
6861
        }
 
6862
      else
 
6863
        {
 
6864
        src_byte = (bit_offset + (sample * bps)) / 8;
 
6865
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
6866
        }
 
6867
 
 
6868
      switch (rotation)
 
6869
        {
 
6870
        case  90: next = src + src_byte - (row * rowsize);
 
6871
                  break;
 
6872
        case 270: next = src + src_byte + (row * rowsize);
 
6873
                  break;
 
6874
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
6875
                  return (1);
 
6876
        }
 
6877
      matchbits = maskbits << (16 - src_bit - bps); 
 
6878
      if (little_endian)
 
6879
        {
 
6880
        swapbuff[1] = *next;
 
6881
        swapbuff[0] = *(next + 1);
 
6882
        }
 
6883
      else
 
6884
        {
 
6885
        swapbuff[0] = *next;
 
6886
        swapbuff[1] = *(next + 1);
 
6887
        }
 
6888
 
 
6889
      buff1 = *((uint16 *)swapbuff);
 
6890
      buff1 = (buff1 & matchbits) << (src_bit);
 
6891
 
 
6892
      /* If we have a full buffer's worth, write it out */
 
6893
      if (ready_bits >= 8)
 
6894
        {
 
6895
        bytebuff = (buff2 >> 8);
 
6896
        *dst++ = bytebuff;
 
6897
        ready_bits -= 8;
 
6898
        /* shift in new bits */
 
6899
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
6900
        }
 
6901
      else
 
6902
        { /* add another bps bits to the buffer */
 
6903
        bytebuff = 0;
 
6904
        buff2 = (buff2 | (buff1 >> ready_bits));
 
6905
        }
 
6906
      ready_bits += bps;
 
6907
      }
 
6908
    }
 
6909
 
 
6910
  if (ready_bits > 0)
 
6911
    {
 
6912
    bytebuff = (buff2 >> 8);
 
6913
    *dst++ = bytebuff;
 
6914
    }
 
6915
 
 
6916
  return (0);
 
6917
  }  /* end rotateContigSamples16bits */
 
6918
 
 
6919
static int
 
6920
rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
6921
                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
6922
  {
 
6923
  int      ready_bits = 0;
 
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;
 
6929
  uint8    swapbuff[4];
 
6930
  uint8   *next;
 
6931
  tsample_t sample;
 
6932
 
 
6933
 
 
6934
  if ((src == NULL) || (dst == NULL))
 
6935
    {
 
6936
    TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
 
6937
    return (1);
 
6938
    }
 
6939
 
 
6940
  rowsize = ((bps * spp * width) + 7) / 8;
 
6941
  ready_bits = 0;
 
6942
  maskbits =  (uint32)-1 >> (32 - bps);
 
6943
  buff1 = buff2 = 0;
 
6944
  for (row = 0; row < length; row++)
 
6945
    {
 
6946
    bit_offset = col * bps * spp;
 
6947
    for (sample = 0; sample < spp; sample++)
 
6948
      {
 
6949
      if (sample == 0)
 
6950
        {
 
6951
        src_byte = bit_offset / 8;
 
6952
        src_bit  = bit_offset % 8;
 
6953
        }
 
6954
      else
 
6955
        {
 
6956
        src_byte = (bit_offset + (sample * bps)) / 8;
 
6957
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
6958
        }
 
6959
 
 
6960
      switch (rotation)
 
6961
        {
 
6962
        case  90: next = src + src_byte - (row * rowsize);
 
6963
                  break;
 
6964
        case 270: next = src + src_byte + (row * rowsize);
 
6965
                  break;
 
6966
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
6967
                  return (1);
 
6968
        }
 
6969
      matchbits = maskbits << (32 - src_bit - bps); 
 
6970
      if (little_endian)
 
6971
        {
 
6972
        swapbuff[3] = *next;
 
6973
        swapbuff[2] = *(next + 1);
 
6974
        swapbuff[1] = *(next + 2);
 
6975
        swapbuff[0] = *(next + 3);
 
6976
        }
 
6977
      else
 
6978
        {
 
6979
        swapbuff[0] = *next;
 
6980
        swapbuff[1] = *(next + 1);
 
6981
        swapbuff[2] = *(next + 2);
 
6982
        swapbuff[3] = *(next + 3);
 
6983
        }
 
6984
 
 
6985
      buff1 = *((uint32 *)swapbuff);
 
6986
      buff1 = (buff1 & matchbits) << (src_bit);
 
6987
 
 
6988
      /* If we have a full buffer's worth, write it out */
 
6989
      if (ready_bits >= 16)
 
6990
        {
 
6991
        bytebuff1 = (buff2 >> 24);
 
6992
        *dst++ = bytebuff1;
 
6993
        bytebuff2 = (buff2 >> 16);
 
6994
        *dst++ = bytebuff2;
 
6995
        ready_bits -= 16;
 
6996
 
 
6997
        /* shift in new bits */
 
6998
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
6999
        }
 
7000
      else
 
7001
        { /* add another bps bits to the buffer */
 
7002
        bytebuff1 = bytebuff2 = 0;
 
7003
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7004
        }
 
7005
      ready_bits += bps;
 
7006
      }
 
7007
    }
 
7008
 
 
7009
 /* catch any trailing bits at the end of the line */
 
7010
  while (ready_bits > 0)
 
7011
    {
 
7012
    bytebuff1 = (buff2 >> 24);
 
7013
    *dst++ = bytebuff1;
 
7014
 
 
7015
    buff2 = (buff2 << 8);
 
7016
    bytebuff2 = bytebuff1;
 
7017
    ready_bits -= 8;
 
7018
    }
 
7019
 
 
7020
  return (0);
 
7021
  }  /* end rotateContigSamples24bits */
 
7022
 
 
7023
static int
 
7024
rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
7025
                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
7026
  {
 
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];
 
7037
  uint8   *next;
 
7038
  tsample_t sample;
 
7039
 
 
7040
 
 
7041
  if ((src == NULL) || (dst == NULL))
 
7042
    {
 
7043
    TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
 
7044
    return (1);
 
7045
    }
 
7046
 
 
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;
 
7051
  else
 
7052
    shift_width = bytes_per_sample + 1;
 
7053
 
 
7054
  rowsize = ((bps * spp * width) + 7) / 8;
 
7055
  ready_bits = 0;
 
7056
  maskbits =  (uint64)-1 >> (64 - bps);
 
7057
  buff1 = buff2 = 0;
 
7058
  for (row = 0; row < length; row++)
 
7059
    {
 
7060
    bit_offset = col * bps * spp;
 
7061
    for (sample = 0; sample < spp; sample++)
 
7062
      {
 
7063
      if (sample == 0)
 
7064
        {
 
7065
        src_byte = bit_offset / 8;
 
7066
        src_bit  = bit_offset % 8;
 
7067
        }
 
7068
      else
 
7069
        {
 
7070
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7071
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7072
        }
 
7073
 
 
7074
      switch (rotation)
 
7075
        {
 
7076
        case  90: next = src + src_byte - (row * rowsize);
 
7077
                  break;
 
7078
        case 270: next = src + src_byte + (row * rowsize);
 
7079
                  break;
 
7080
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
7081
                  return (1);
 
7082
        }
 
7083
      matchbits = maskbits << (64 - src_bit - bps); 
 
7084
      if (little_endian)
 
7085
        {
 
7086
        swapbuff1[3] = *next;
 
7087
        swapbuff1[2] = *(next + 1);
 
7088
        swapbuff1[1] = *(next + 2);
 
7089
        swapbuff1[0] = *(next + 3);
 
7090
        }
 
7091
      else
 
7092
        {
 
7093
        swapbuff1[0] = *next;
 
7094
        swapbuff1[1] = *(next + 1);
 
7095
        swapbuff1[2] = *(next + 2);
 
7096
        swapbuff1[3] = *(next + 3);
 
7097
        }
 
7098
      longbuff1 = *((uint32 *)swapbuff1);                  
 
7099
 
 
7100
      memset (swapbuff2, '\0', sizeof(swapbuff2));
 
7101
      if (little_endian)
 
7102
        {
 
7103
        swapbuff2[3] = *next;
 
7104
        swapbuff2[2] = *(next + 1);
 
7105
        swapbuff2[1] = *(next + 2);
 
7106
        swapbuff2[0] = *(next + 3);
 
7107
        }
 
7108
      else
 
7109
        {
 
7110
        swapbuff2[0] = *next;
 
7111
        swapbuff2[1] = *(next + 1);
 
7112
        swapbuff2[2] = *(next + 2);
 
7113
        swapbuff2[3] = *(next + 3);
 
7114
        }
 
7115
 
 
7116
      longbuff2 = *((uint32 *)swapbuff2);
 
7117
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
7118
      buff1 = (buff3 & matchbits) << (src_bit);
 
7119
 
 
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));
 
7124
        }
 
7125
      else /* If we have a full buffer's worth, write it out */
 
7126
        {
 
7127
        bytebuff1 = (buff2 >> 56);
 
7128
        *dst++ = bytebuff1;
 
7129
        bytebuff2 = (buff2 >> 48);
 
7130
        *dst++ = bytebuff2;
 
7131
        bytebuff3 = (buff2 >> 40);
 
7132
        *dst++ = bytebuff3;
 
7133
        bytebuff4 = (buff2 >> 32);
 
7134
        *dst++ = bytebuff4;
 
7135
        ready_bits -= 32;
 
7136
                    
 
7137
        /* shift in new bits */
 
7138
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
7139
        }
 
7140
      ready_bits += bps;
 
7141
      }
 
7142
    }
 
7143
  while (ready_bits > 0)
 
7144
    {
 
7145
    bytebuff1 = (buff2 >> 56);
 
7146
    *dst++ = bytebuff1;
 
7147
    buff2 = (buff2 << 8);
 
7148
    ready_bits -= 8;
 
7149
    }
 
7150
 
 
7151
  return (0);
 
7152
  } /* end rotateContigSamples32bits */
 
7153
 
 
7154
 
 
7155
/* Rotate an image by a multiple of 90 degrees clockwise */
 
7156
static int
 
7157
rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, 
 
7158
            uint32 *img_length, unsigned char **ibuff_ptr)
 
7159
  {
 
7160
  int      shift_width;
 
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;
 
7166
  unsigned char *src;
 
7167
  unsigned char *dst;
 
7168
  uint16   spp, bps;
 
7169
  float    res_temp;
 
7170
  unsigned char *rbuff = NULL;
 
7171
 
 
7172
  width  = *img_width;
 
7173
  length = *img_length;
 
7174
  spp = image->spp;
 
7175
  bps = image->bps;
 
7176
 
 
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;
 
7181
  else
 
7182
    buffsize = (rowsize + 1) * length;
 
7183
 
 
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;
 
7188
  else
 
7189
    shift_width = bytes_per_sample + 1;
 
7190
 
 
7191
  switch (rotation)
 
7192
    {
 
7193
    case 0:
 
7194
    case 360: return (0);
 
7195
    case 90:
 
7196
    case 180:
 
7197
    case 270: break;
 
7198
    default:  TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
 
7199
              return (-1);
 
7200
    }
 
7201
 
 
7202
  if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
 
7203
    {
 
7204
    TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
 
7205
    return (-1);
 
7206
    }
 
7207
  _TIFFmemset(rbuff, '\0', buffsize);
 
7208
 
 
7209
  ibuff = *ibuff_ptr;
 
7210
  switch (rotation)
 
7211
    {
 
7212
    case 180: if ((bps % 8) == 0) /* byte alligned data */
 
7213
                { 
 
7214
                src = ibuff;
 
7215
                pix_offset = (spp * bps) / 8;
 
7216
                for (row = 0; row < length; row++)
 
7217
                   {
 
7218
                   dst_offset = (length - row - 1) * rowsize;
 
7219
                   for (col = 0; col < width; col++)
 
7220
                     { 
 
7221
                     col_offset = (width - col - 1) * pix_offset;
 
7222
                     dst = rbuff + dst_offset + col_offset;
 
7223
 
 
7224
                     for (i = 0; i  < bytes_per_pixel; i++)
 
7225
                       *dst++ = *src++;
 
7226
                     }
 
7227
                   }
 
7228
                }
 
7229
              else
 
7230
                { /* non 8 bit per sample data */ 
 
7231
                for (row = 0; row < length; row++)
 
7232
                  {
 
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)
 
7238
                    {
 
7239
                    case 1: if (reverseSamples8bits(spp, bps, width, src, dst))
 
7240
                              {
 
7241
                              _TIFFfree(rbuff);
 
7242
                              return (-1);
 
7243
                              }
 
7244
                             break;
 
7245
                    case 2: if (reverseSamples16bits(spp, bps, width, src, dst))
 
7246
                              {
 
7247
                              _TIFFfree(rbuff);
 
7248
                              return (-1);
 
7249
                              }
 
7250
                             break;
 
7251
                    case 3: if (reverseSamples24bits(spp, bps, width, src, dst))
 
7252
                              {
 
7253
                              _TIFFfree(rbuff);
 
7254
                              return (-1);
 
7255
                              }
 
7256
                             break;
 
7257
                    case 4: 
 
7258
                    case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
 
7259
                              {
 
7260
                              _TIFFfree(rbuff);
 
7261
                              return (-1);
 
7262
                              }
 
7263
                             break;
 
7264
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
7265
                             _TIFFfree(rbuff);
 
7266
                             return (-1);      
 
7267
                    }
 
7268
                  }
 
7269
                }
 
7270
              _TIFFfree(ibuff);
 
7271
              *(ibuff_ptr) = rbuff;
 
7272
              break;
 
7273
 
 
7274
    case 90:  if ((bps % 8) == 0) /* byte aligned data */
 
7275
                {
 
7276
                for (col = 0; col < width; col++)
 
7277
                  {
 
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--)
 
7283
                    {
 
7284
                    for (i = 0; i < bytes_per_pixel; i++)
 
7285
                      *dst++ = *(src + i);
 
7286
                    src -= rowsize;
 
7287
                    }
 
7288
                  }
 
7289
                }
 
7290
              else
 
7291
                { /* non 8 bit per sample data */ 
 
7292
                for (col = 0; col < width; col++)
 
7293
                  {
 
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)
 
7299
                    {
 
7300
                    case 1: if (rotateContigSamples8bits(rotation, spp, bps, width, 
 
7301
                                                         length, col, src, dst))
 
7302
                              {
 
7303
                              _TIFFfree(rbuff);
 
7304
                              return (-1);
 
7305
                              }
 
7306
                            break;
 
7307
                    case 2: if (rotateContigSamples16bits(rotation, spp, bps, width, 
 
7308
                                                          length, col, src, dst))
 
7309
                              {
 
7310
                              _TIFFfree(rbuff);
 
7311
                              return (-1);
 
7312
                              }
 
7313
                             break;
 
7314
                    case 3: if (rotateContigSamples24bits(rotation, spp, bps, width, 
 
7315
                                                          length, col, src, dst))
 
7316
                              {
 
7317
                              _TIFFfree(rbuff);
 
7318
                              return (-1);
 
7319
                              }
 
7320
                             break;
 
7321
                    case 4: 
 
7322
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
 
7323
                                                          length, col, src, dst))
 
7324
                              {
 
7325
                              _TIFFfree(rbuff);
 
7326
                              return (-1);
 
7327
                              }
 
7328
                             break;
 
7329
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
7330
                             _TIFFfree(rbuff);
 
7331
                             return (-1);      
 
7332
                    }
 
7333
                  }
 
7334
                }
 
7335
              _TIFFfree(ibuff);
 
7336
              *(ibuff_ptr) = rbuff;
 
7337
 
 
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;
 
7345
              break;
 
7346
 
 
7347
    case 270: if ((bps % 8) == 0) /* byte aligned data */
 
7348
                {
 
7349
                for (col = 0; col < width; col++)
 
7350
                  {
 
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--)
 
7356
                    {
 
7357
                    for (i = 0; i < bytes_per_pixel; i++)
 
7358
                      *dst++ = *(src + i);
 
7359
                    src += rowsize;
 
7360
                    }
 
7361
                  }
 
7362
                }
 
7363
              else
 
7364
                { /* non 8 bit per sample data */ 
 
7365
                for (col = 0; col < width; col++)
 
7366
                  {
 
7367
                  src_offset = 0;
 
7368
                  dst_offset = (width - col - 1) * colsize;
 
7369
                  src = ibuff + src_offset;
 
7370
                  dst = rbuff + dst_offset;
 
7371
                  switch (shift_width)
 
7372
                    {
 
7373
                    case 1: if (rotateContigSamples8bits(rotation, spp, bps, width, 
 
7374
                                                         length, col, src, dst))
 
7375
                              {
 
7376
                              _TIFFfree(rbuff);
 
7377
                              return (-1);
 
7378
                              }
 
7379
                            break;
 
7380
                    case 2: if (rotateContigSamples16bits(rotation, spp, bps, width, 
 
7381
                                                          length, col, src, dst))
 
7382
                              {
 
7383
                              _TIFFfree(rbuff);
 
7384
                              return (-1);
 
7385
                              }
 
7386
                             break;
 
7387
                    case 3: if (rotateContigSamples24bits(rotation, spp, bps, width, 
 
7388
                                                          length, col, src, dst))
 
7389
                              {
 
7390
                              _TIFFfree(rbuff);
 
7391
                              return (-1);
 
7392
                              }
 
7393
                             break;
 
7394
                    case 4: 
 
7395
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
 
7396
                                                          length, col, src, dst))
 
7397
                              {
 
7398
                              _TIFFfree(rbuff);
 
7399
                              return (-1);
 
7400
                              }
 
7401
                             break;
 
7402
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
7403
                             _TIFFfree(rbuff);
 
7404
                             return (-1);      
 
7405
                    }
 
7406
                  }
 
7407
                }
 
7408
              _TIFFfree(ibuff);
 
7409
              *(ibuff_ptr) = rbuff;
 
7410
 
 
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;
 
7418
              break;
 
7419
    default:
 
7420
              break;
 
7421
    }
 
7422
 
 
7423
  return (0);
 
7424
  } /* end rotateImage */
 
7425
 
 
7426
static int
 
7427
reverseSamples8bits (uint16 spp, uint16 bps, uint32 width, 
 
7428
                     uint8 *ibuff, uint8 *obuff)
 
7429
  {
 
7430
  int      ready_bits = 0;
 
7431
  uint32   col;
 
7432
  uint32   src_byte, src_bit;
 
7433
  uint32   bit_offset = 0;
 
7434
  uint8    matchbits = 0, maskbits = 0;
 
7435
  uint8    buff1 = 0, buff2 = 0;
 
7436
  unsigned char *src;
 
7437
  unsigned char *dst;
 
7438
  tsample_t sample;
 
7439
 
 
7440
  if ((ibuff == NULL) || (obuff == NULL))
 
7441
    {
 
7442
    TIFFError("reverseSamples8bits","Invalid image or work buffer");
 
7443
    return (1);
 
7444
    }
 
7445
 
 
7446
  ready_bits = 0;
 
7447
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
7448
  dst = obuff;
 
7449
  for (col = width; col > 0; col--)
 
7450
    {
 
7451
    /* Compute src byte(s) and bits within byte(s) */
 
7452
    bit_offset = (col - 1) * bps * spp;
 
7453
    for (sample = 0; sample < spp; sample++)
 
7454
      {
 
7455
      if (sample == 0)
 
7456
        {
 
7457
        src_byte = bit_offset / 8;
 
7458
        src_bit  = bit_offset % 8;
 
7459
        }
 
7460
      else
 
7461
        {
 
7462
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7463
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7464
        }
 
7465
 
 
7466
      src = ibuff + src_byte;
 
7467
      matchbits = maskbits << (8 - src_bit - bps); 
 
7468
      buff1 = ((*src) & matchbits) << (src_bit);
 
7469
 
 
7470
      if (ready_bits < 8)
 
7471
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7472
      else  /* If we have a full buffer's worth, write it out */
 
7473
        {
 
7474
        *dst++ = buff2;
 
7475
        buff2 = buff1;
 
7476
        ready_bits -= 8;
 
7477
        }
 
7478
      ready_bits += bps;
 
7479
      }
 
7480
    }
 
7481
  if (ready_bits > 0)
 
7482
    {
 
7483
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
7484
    *dst++ = buff1;
 
7485
    }
 
7486
 
 
7487
  return (0);
 
7488
  } /* end reverseSamples8bits */
 
7489
 
 
7490
static int
 
7491
reverseSamples16bits (uint16 spp, uint16 bps, uint32 width, 
 
7492
                      uint8 *ibuff, uint8 *obuff)
 
7493
  {
 
7494
  int      ready_bits = 0;
 
7495
  uint32   col;
 
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;
 
7500
  uint8    bytebuff = 0;
 
7501
  unsigned char *src;
 
7502
  unsigned char *dst;
 
7503
  unsigned char  swapbuff[2];
 
7504
  tsample_t sample;
 
7505
 
 
7506
  if ((ibuff == NULL) || (obuff == NULL))
 
7507
    {
 
7508
    TIFFError("reverseSample16bits","Invalid image or work buffer");
 
7509
    return (1);
 
7510
    }
 
7511
 
 
7512
  ready_bits = 0;
 
7513
  maskbits =  (uint16)-1 >> (16 - bps);
 
7514
  dst = obuff;
 
7515
  for (col = width; col > 0; col--)
 
7516
    {
 
7517
    /* Compute src byte(s) and bits within byte(s) */
 
7518
    bit_offset = (col - 1) * bps * spp;
 
7519
    for (sample = 0; sample < spp; sample++)
 
7520
      {
 
7521
      if (sample == 0)
 
7522
        {
 
7523
        src_byte = bit_offset / 8;
 
7524
        src_bit  = bit_offset % 8;
 
7525
        }
 
7526
      else
 
7527
        {
 
7528
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7529
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7530
        }
 
7531
 
 
7532
      src = ibuff + src_byte;
 
7533
      matchbits = maskbits << (16 - src_bit - bps); 
 
7534
      if (little_endian)
 
7535
        {
 
7536
        swapbuff[1] = *src;
 
7537
        swapbuff[0] = *(src + 1);
 
7538
        }
 
7539
      else
 
7540
        {
 
7541
        swapbuff[0] = *src;
 
7542
        swapbuff[1] = *(src + 1);
 
7543
        }
 
7544
 
 
7545
      buff1 = *((uint16 *)swapbuff);
 
7546
      buff1 = (buff1 & matchbits) << (src_bit);
 
7547
      
 
7548
      if (ready_bits < 8)
 
7549
        { /* add another bps bits to the buffer */
 
7550
        bytebuff = 0;
 
7551
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7552
        }
 
7553
      else /* If we have a full buffer's worth, write it out */
 
7554
        {
 
7555
        bytebuff = (buff2 >> 8);
 
7556
        *dst++ = bytebuff;
 
7557
        ready_bits -= 8;
 
7558
        /* shift in new bits */
 
7559
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
7560
        }
 
7561
      ready_bits += bps;
 
7562
      }
 
7563
    }
 
7564
 
 
7565
  if (ready_bits > 0)
 
7566
    {
 
7567
    bytebuff = (buff2 >> 8);
 
7568
    *dst++ = bytebuff;
 
7569
    }
 
7570
 
 
7571
  return (0);
 
7572
  } /* end reverseSamples16bits */
 
7573
 
 
7574
static int
 
7575
reverseSamples24bits (uint16 spp, uint16 bps, uint32 width, 
 
7576
                      uint8 *ibuff, uint8 *obuff)
 
7577
  {
 
7578
  int      ready_bits = 0;
 
7579
  uint32   col;
 
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;
 
7585
  unsigned char *src;
 
7586
  unsigned char *dst;
 
7587
  unsigned char  swapbuff[4];
 
7588
  tsample_t sample;
 
7589
 
 
7590
  if ((ibuff == NULL) || (obuff == NULL))
 
7591
    {
 
7592
    TIFFError("reverseSamples24bits","Invalid image or work buffer");
 
7593
    return (1);
 
7594
    }
 
7595
 
 
7596
  ready_bits = 0;
 
7597
  maskbits =  (uint32)-1 >> (32 - bps);
 
7598
  dst = obuff;
 
7599
  for (col = width; col > 0; col--)
 
7600
    {
 
7601
    /* Compute src byte(s) and bits within byte(s) */
 
7602
    bit_offset = (col - 1) * bps * spp;
 
7603
    for (sample = 0; sample < spp; sample++)
 
7604
      {
 
7605
      if (sample == 0)
 
7606
        {
 
7607
        src_byte = bit_offset / 8;
 
7608
        src_bit  = bit_offset % 8;
 
7609
        }
 
7610
      else
 
7611
        {
 
7612
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7613
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7614
        }
 
7615
 
 
7616
      src = ibuff + src_byte;
 
7617
      matchbits = maskbits << (32 - src_bit - bps); 
 
7618
      if (little_endian)
 
7619
        {
 
7620
        swapbuff[3] = *src;
 
7621
        swapbuff[2] = *(src + 1);
 
7622
        swapbuff[1] = *(src + 2);
 
7623
        swapbuff[0] = *(src + 3);
 
7624
        }
 
7625
      else
 
7626
        {
 
7627
        swapbuff[0] = *src;
 
7628
        swapbuff[1] = *(src + 1);
 
7629
        swapbuff[2] = *(src + 2);
 
7630
        swapbuff[3] = *(src + 3);
 
7631
        }
 
7632
 
 
7633
      buff1 = *((uint32 *)swapbuff);
 
7634
      buff1 = (buff1 & matchbits) << (src_bit);
 
7635
 
 
7636
      if (ready_bits < 16)
 
7637
        { /* add another bps bits to the buffer */
 
7638
        bytebuff1 = bytebuff2 = 0;
 
7639
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7640
        }
 
7641
      else /* If we have a full buffer's worth, write it out */
 
7642
        {
 
7643
        bytebuff1 = (buff2 >> 24);
 
7644
        *dst++ = bytebuff1;
 
7645
        bytebuff2 = (buff2 >> 16);
 
7646
        *dst++ = bytebuff2;
 
7647
        ready_bits -= 16;
 
7648
 
 
7649
        /* shift in new bits */
 
7650
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
7651
        }
 
7652
      ready_bits += bps;
 
7653
      }
 
7654
    }
 
7655
 
 
7656
 /* catch any trailing bits at the end of the line */
 
7657
  while (ready_bits > 0)
 
7658
    {
 
7659
    bytebuff1 = (buff2 >> 24);
 
7660
    *dst++ = bytebuff1;
 
7661
 
 
7662
    buff2 = (buff2 << 8);
 
7663
    bytebuff2 = bytebuff1;
 
7664
    ready_bits -= 8;
 
7665
    }
 
7666
 
 
7667
  return (0);
 
7668
  } /* end reverseSamples24bits */
 
7669
 
 
7670
 
 
7671
static int
 
7672
reverseSamples32bits (uint16 spp, uint16 bps, uint32 width, 
 
7673
                      uint8 *ibuff, uint8 *obuff)
 
7674
  {
 
7675
  int    ready_bits = 0, shift_width = 0;
 
7676
  int    bytes_per_sample, bytes_per_pixel;
 
7677
  uint32 bit_offset;
 
7678
  uint32 src_byte = 0, src_bit = 0;
 
7679
  uint32 col;
 
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;
 
7684
  unsigned char *src;
 
7685
  unsigned char *dst;
 
7686
  unsigned char  swapbuff1[4];
 
7687
  unsigned char  swapbuff2[4];
 
7688
  tsample_t sample;
 
7689
 
 
7690
  if ((ibuff == NULL) || (obuff == NULL))
 
7691
    {
 
7692
    TIFFError("reverseSamples32bits","Invalid image or work buffer");
 
7693
    return (1);
 
7694
    }
 
7695
 
 
7696
  ready_bits = 0;
 
7697
  maskbits =  (uint64)-1 >> (64 - bps);
 
7698
  dst = obuff;
 
7699
 
 
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;
 
7704
  else
 
7705
    shift_width = bytes_per_sample + 1;
 
7706
 
 
7707
  for (col = width; col > 0; col--)
 
7708
    {
 
7709
    /* Compute src byte(s) and bits within byte(s) */
 
7710
    bit_offset = (col - 1) * bps * spp;
 
7711
    for (sample = 0; sample < spp; sample++)
 
7712
      {
 
7713
      if (sample == 0)
 
7714
        {
 
7715
        src_byte = bit_offset / 8;
 
7716
        src_bit  = bit_offset % 8;
 
7717
        }
 
7718
      else
 
7719
        {
 
7720
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7721
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7722
        }
 
7723
 
 
7724
      src = ibuff + src_byte;
 
7725
      matchbits = maskbits << (64 - src_bit - bps); 
 
7726
      if (little_endian)
 
7727
        {
 
7728
        swapbuff1[3] = *src;
 
7729
        swapbuff1[2] = *(src + 1);
 
7730
        swapbuff1[1] = *(src + 2);
 
7731
        swapbuff1[0] = *(src + 3);
 
7732
        }
 
7733
      else
 
7734
        {
 
7735
        swapbuff1[0] = *src;
 
7736
        swapbuff1[1] = *(src + 1);
 
7737
        swapbuff1[2] = *(src + 2);
 
7738
        swapbuff1[3] = *(src + 3);
 
7739
        }
 
7740
      longbuff1 = *((uint32 *)swapbuff1);                  
 
7741
 
 
7742
      memset (swapbuff2, '\0', sizeof(swapbuff2));
 
7743
      if (little_endian)
 
7744
        {
 
7745
        swapbuff2[3] = *src;
 
7746
        swapbuff2[2] = *(src + 1);
 
7747
        swapbuff2[1] = *(src + 2);
 
7748
        swapbuff2[0] = *(src + 3);
 
7749
        }
 
7750
      else
 
7751
        {
 
7752
        swapbuff2[0] = *src;
 
7753
        swapbuff2[1] = *(src + 1);
 
7754
        swapbuff2[2] = *(src + 2);
 
7755
        swapbuff2[3] = *(src + 3);
 
7756
        }
 
7757
 
 
7758
      longbuff2 = *((uint32 *)swapbuff2);
 
7759
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
7760
      buff1 = (buff3 & matchbits) << (src_bit);
 
7761
 
 
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));
 
7766
        }
 
7767
      else /* If we have a full buffer's worth, write it out */
 
7768
        {
 
7769
        bytebuff1 = (buff2 >> 56);
 
7770
        *dst++ = bytebuff1;
 
7771
        bytebuff2 = (buff2 >> 48);
 
7772
        *dst++ = bytebuff2;
 
7773
        bytebuff3 = (buff2 >> 40);
 
7774
        *dst++ = bytebuff3;
 
7775
        bytebuff4 = (buff2 >> 32);
 
7776
        *dst++ = bytebuff4;
 
7777
        ready_bits -= 32;
 
7778
                    
 
7779
        /* shift in new bits */
 
7780
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
7781
        }
 
7782
      ready_bits += bps;
 
7783
      }
 
7784
    }
 
7785
  while (ready_bits > 0)
 
7786
    {
 
7787
    bytebuff1 = (buff2 >> 56);
 
7788
    *dst++ = bytebuff1;
 
7789
    buff2 = (buff2 << 8);
 
7790
    ready_bits -= 8;
 
7791
    }
 
7792
 
 
7793
  return (0);
 
7794
  } /* end reverseSamples32bits */
 
7795
 
 
7796
static int
 
7797
reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width, 
 
7798
                     uint8 *src, uint8 *dst)
 
7799
  {
 
7800
  int i;
 
7801
  uint32  col, bytes_per_pixel, col_offset;
 
7802
  uint8   bytebuff1;
 
7803
  unsigned char swapbuff[32];
 
7804
 
 
7805
  if ((src == NULL) || (dst == NULL))
 
7806
    {
 
7807
    TIFFError("reverseSamplesBytes","Invalid input or output buffer");
 
7808
    return (1);
 
7809
    }
 
7810
 
 
7811
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
7812
  switch (bps / 8)
 
7813
     {
 
7814
     case 8:  /* Use memcpy for multiple bytes per sample data */
 
7815
     case 4:
 
7816
     case 3:
 
7817
     case 2: for (col = 0; col < (width / 2); col++)
 
7818
               {
 
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);
 
7823
               }
 
7824
             break;
 
7825
     case 1: /* Use byte copy only for single byte per sample data */
 
7826
             for (col = 0; col < (width / 2); col++)
 
7827
               { 
 
7828
               for (i = 0; i < spp; i++)
 
7829
                  {
 
7830
                  bytebuff1 = *src;
 
7831
                  *src++ = *(dst - spp + i);
 
7832
                  *(dst - spp + i) = bytebuff1;
 
7833
                  }
 
7834
                dst -= spp;
 
7835
                }
 
7836
             break;
 
7837
     default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
 
7838
       return (1);
 
7839
     }
 
7840
  return (0);
 
7841
  } /* end reverseSamplesBytes */
 
7842
 
 
7843
 
 
7844
/* Mirror an image horizontally or vertically */
 
7845
static int
 
7846
mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
 
7847
  {
 
7848
  int      shift_width;
 
7849
  uint32   bytes_per_pixel, bytes_per_sample;
 
7850
  uint32   row, rowsize, row_offset;
 
7851
  unsigned char *line_buff = NULL;
 
7852
  unsigned char *src;
 
7853
  unsigned char *dst;
 
7854
 
 
7855
  src = ibuff;
 
7856
  rowsize = ((width * bps * spp) + 7) / 8;
 
7857
  switch (mirror)
 
7858
    {
 
7859
    case MIRROR_BOTH:
 
7860
    case MIRROR_VERT: 
 
7861
             line_buff = (unsigned char *)_TIFFmalloc(rowsize);
 
7862
             if (line_buff == NULL)
 
7863
               {
 
7864
               TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
 
7865
               return (-1);
 
7866
               }
 
7867
 
 
7868
             dst = ibuff + (rowsize * (length - 1));
 
7869
             for (row = 0; row < length / 2; row++)
 
7870
               {
 
7871
              _TIFFmemcpy(line_buff, src, rowsize);
 
7872
              _TIFFmemcpy(src, dst,  rowsize);
 
7873
              _TIFFmemcpy(dst, line_buff, rowsize);
 
7874
               src += (rowsize);
 
7875
               dst -= (rowsize);                                 
 
7876
               }
 
7877
             if (line_buff)
 
7878
               _TIFFfree(line_buff);
 
7879
             if (mirror == MIRROR_VERT)
 
7880
               break;
 
7881
    case MIRROR_HORIZ :
 
7882
              if ((bps % 8) == 0) /* byte alligned data */
 
7883
                { 
 
7884
                for (row = 0; row < length; row++)
 
7885
                  {
 
7886
                  row_offset = row * rowsize;
 
7887
                  src = ibuff + row_offset;
 
7888
                  dst = ibuff + row_offset + rowsize;
 
7889
                  if (reverseSamplesBytes(spp, bps, width, src, dst))
 
7890
                    {
 
7891
                    return (-1);
 
7892
                    }
 
7893
                  }
 
7894
                }
 
7895
              else
 
7896
                { /* non 8 bit per sample  data */
 
7897
                if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
 
7898
                  {
 
7899
                  TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
 
7900
                  return (-1);
 
7901
                  }
 
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;
 
7906
                else
 
7907
                  shift_width = bytes_per_sample + 1;
 
7908
 
 
7909
                for (row = 0; row < length; row++)
 
7910
                  {
 
7911
                  row_offset = row * rowsize;
 
7912
                  src = ibuff + row_offset;
 
7913
                  _TIFFmemset (line_buff, '\0', rowsize);
 
7914
                  switch (shift_width)
 
7915
                    {
 
7916
                    case 1: if (reverseSamples8bits(spp, bps, width, src, line_buff))
 
7917
                              {
 
7918
                              _TIFFfree(line_buff);
 
7919
                              return (-1);
 
7920
                              }
 
7921
                             _TIFFmemcpy (src, line_buff, rowsize);
 
7922
                             break;
 
7923
                    case 2: if (reverseSamples16bits(spp, bps, width, src, line_buff))
 
7924
                              {
 
7925
                              _TIFFfree(line_buff);
 
7926
                              return (-1);
 
7927
                              }
 
7928
                             _TIFFmemcpy (src, line_buff, rowsize);
 
7929
                             break;
 
7930
                    case 3: if (reverseSamples24bits(spp, bps, width, src, line_buff))
 
7931
                              {
 
7932
                              _TIFFfree(line_buff);
 
7933
                              return (-1);
 
7934
                              }
 
7935
                             _TIFFmemcpy (src, line_buff, rowsize);
 
7936
                             break;
 
7937
                    case 4: 
 
7938
                    case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
 
7939
                              {
 
7940
                              _TIFFfree(line_buff);
 
7941
                              return (-1);
 
7942
                              }
 
7943
                             _TIFFmemcpy (src, line_buff, rowsize);
 
7944
                             break;
 
7945
                    default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
 
7946
                             _TIFFfree(line_buff);
 
7947
                             return (-1);      
 
7948
                    }
 
7949
                  }
 
7950
                if (line_buff)
 
7951
                  _TIFFfree(line_buff);
 
7952
                }
 
7953
             break;
 
7954
 
 
7955
    default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
 
7956
             return (-1);
 
7957
             break;
 
7958
    }
 
7959
 
 
7960
  return (0);
 
7961
  }
 
7962
 
 
7963
/* Invert the light and dark values for a bilevel or grayscale image */
 
7964
static int
 
7965
invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
 
7966
  {
 
7967
  uint32   row, col;
 
7968
  unsigned char  bytebuff1, bytebuff2, bytebuff3, bytebuff4;
 
7969
  unsigned char *src;
 
7970
  uint16        *src_uint16;
 
7971
  uint32        *src_uint32;
 
7972
 
 
7973
  if (spp != 1)
 
7974
    {
 
7975
    TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
 
7976
    return (-1);
 
7977
    }
 
7978
 
 
7979
  if (photometric !=  PHOTOMETRIC_MINISWHITE && photometric !=  PHOTOMETRIC_MINISBLACK)
 
7980
    {
 
7981
    TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
 
7982
    return (-1);
 
7983
    }
 
7984
 
 
7985
  src = work_buff;
 
7986
  if (src == NULL)
 
7987
    {
 
7988
    TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
 
7989
    return (-1);
 
7990
    }
 
7991
 
 
7992
  switch (bps)
 
7993
    {
 
7994
    case 32: src_uint32 = (uint32 *)src;
 
7995
             for (row = 0; row < length; row++)
 
7996
               for (col = 0; col < width; col++)
 
7997
                 {
 
7998
                 *src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
 
7999
                  src_uint32++;
 
8000
                 }
 
8001
            break;
 
8002
    case 16: src_uint16 = (uint16 *)src;
 
8003
             for (row = 0; row < length; row++)
 
8004
               for (col = 0; col < width; col++)
 
8005
                 {
 
8006
                 *src_uint16 = (uint16)0xFFFF - *src_uint16;
 
8007
                  src_uint16++;
 
8008
                 }
 
8009
            break;
 
8010
    case 8: for (row = 0; row < length; row++)
 
8011
              for (col = 0; col < width; col++)
 
8012
                {
 
8013
                *src = (uint8)255 - *src;
 
8014
                 src++;
 
8015
                }
 
8016
            break;
 
8017
    case 4: for (row = 0; row < length; row++)
 
8018
              for (col = 0; col < width; col++)
 
8019
                {
 
8020
                bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
 
8021
                bytebuff2 = 16 - (*src & 15);
 
8022
                *src = bytebuff1 << 4 & bytebuff2;
 
8023
                src++;
 
8024
                }
 
8025
            break;
 
8026
    case 2: for (row = 0; row < length; row++)
 
8027
              for (col = 0; col < width; col++)
 
8028
                {
 
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;
 
8034
                src++;
 
8035
                }
 
8036
            break;
 
8037
    case 1: for (row = 0; row < length; row++)
 
8038
              for (col = 0; col < width; col += 8 /(spp * bps))
 
8039
                {
 
8040
                *src = ~(*src);
 
8041
                src++;
 
8042
                }
 
8043
            break;
 
8044
    default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
 
8045
      return (-1);
 
8046
    }
 
8047
 
 
8048
  return (0);
 
8049
  }
 
8050
 
 
8051
/* vim: set ts=8 sts=8 sw=8 noet: */