~ubuntu-branches/ubuntu/precise/tiff/precise-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-81xx-1.patch/tools/tiffcrop.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-03-30 08:11:18 UTC
  • Revision ID: package-import@ubuntu.com-20150330081118-bvaoaii1act27voq
Tags: 3.9.5-2ubuntu1.7
* SECURITY UPDATE: Fix multiple security issues
  - debian/patches/CVE-2014-81xx-1.patch to CVE-2014-81xx-11.patch
  - debian/patches/CVE-2014-8128-5.patch
  - debian/patches/CVE-2014-9655-1.patch to CVE-2014-9655-3.patch
  - debian/patches/read_overrun.patch
  - debian/patches/CVE-2014-8130.patch
  - CVE-2014-8127 (partially)
  - CVE-2014-8128
  - CVE-2014-8129
  - CVE-2014-8130
  - CVE-2014-9330
  - CVE-2014-9655

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tiffcrop.c,v 1.3.2.15 2010-12-14 02:03:55 faxguy 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
 * Additions (c) Richard Nolde 2006-2010 
 
10
 *
 
11
 * Permission to use, copy, modify, distribute, and sell this software and 
 
12
 * its documentation for any purpose is hereby granted without fee, provided
 
13
 * that (i) the above copyright notices and this permission notice appear in
 
14
 * all copies of the software and related documentation, and (ii) the names of
 
15
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 
16
 * publicity relating to the software without the specific, prior written
 
17
 * permission of Sam Leffler and Silicon Graphics.
 
18
 * 
 
19
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 
20
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 
21
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 
22
 * 
 
23
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS OR ANY OTHER COPYRIGHT  
 
24
 * HOLDERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL 
 
25
 * DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
 
26
 * DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND 
 
27
 * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
 
28
 * OR PERFORMANCE OF THIS SOFTWARE.
 
29
 *
 
30
 * Some portions of the current code are derived from tiffcp, primarly in 
 
31
 * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though
 
32
 * some of the original functions have been extended to support arbitrary bit
 
33
 * depths. These functions are presented at the top of this file.
 
34
 *
 
35
 * Add support for the options below to extract sections of image(s) 
 
36
 * and to modify the whole image or selected portions of each image by
 
37
 * rotations, mirroring, and colorscale/colormap inversion of selected
 
38
 * types of TIFF images when appropriate. Some color model dependent 
 
39
 * functions are restricted to bilevel or 8 bit per sample data.
 
40
 * See the man page for the full explanations.
 
41
 *
 
42
 * New Options: 
 
43
 * -h             Display the syntax guide.
 
44
 * -v             Report the version and last build date for tiffcrop and libtiff.
 
45
 * -z x1,y1,x2,y2:x3,y3,x4,y4:..xN,yN,xN + 1, yN + 1 
 
46
 *                Specify a series of coordinates to define rectangular
 
47
 *                regions by the top left and lower right corners.
 
48
 * -e c|d|i|m|s   export mode for images and selections from input images
 
49
 *   combined     All images and selections are written to a single file (default)
 
50
 *                with multiple selections from one image combined into a single image
 
51
 *   divided      All images and selections are written to a single file
 
52
 *                with each selection from one image written to a new image
 
53
 *   image        Each input image is written to a new file (numeric filename sequence)
 
54
 *                with multiple selections from the image combined into one image
 
55
 *   multiple     Each input image is written to a new file (numeric filename sequence)
 
56
 *                with each selection from the image written to a new image
 
57
 *   separated    Individual selections from each image are written to separate files
 
58
 * -U units       [in, cm, px ] inches, centimeters or pixels
 
59
 * -H #           Set horizontal resolution of output images to #
 
60
 * -V #           Set vertical resolution of output images to #
 
61
 * -J #           Horizontal margin of output page to # expressed in current
 
62
 *                units when sectioning image into columns x rows 
 
63
 *                using the -S cols:rows option.
 
64
 * -K #           Vertical margin of output page to # expressed in current
 
65
 *                units when sectioning image into columns x rows
 
66
 *                using the -S cols:rows option.
 
67
 * -X #           Horizontal dimension of region to extract expressed in current
 
68
 *                units
 
69
 * -Y #           Vertical dimension of region to extract expressed in current
 
70
 *                units
 
71
 * -O orient      Orientation for output image, portrait, landscape, auto
 
72
 * -P page        Page size for output image segments, eg letter, legal, tabloid,
 
73
 *                etc.
 
74
 * -S cols:rows   Divide the image into equal sized segments using cols across
 
75
 *                and rows down
 
76
 * -E t|l|r|b     Edge to use as origin
 
77
 * -m #,#,#,#     Margins from edges for selection: top, left, bottom, right
 
78
 *                (commas separated)
 
79
 * -Z #:#,#:#     Zones of the image designated as zone X of Y, 
 
80
 *                eg 1:3 would be first of three equal portions measured
 
81
 *                from reference edge
 
82
 * -N odd|even|#,#-#,#|last 
 
83
 *                Select sequences and/or ranges of images within file
 
84
 *                to process. The words odd or even may be used to specify
 
85
 *                all odd or even numbered images the word last may be used
 
86
 *                in place of a number in the sequence to indicate the final
 
87
 *                image in the file without knowing how many images there are.
 
88
 * -R #           Rotate image or crop selection by 90,180,or 270 degrees
 
89
 *                clockwise  
 
90
 * -F h|v         Flip (mirror) image or crop selection horizontally
 
91
 *                or vertically 
 
92
 * -I [black|white|data|both]
 
93
 *                Invert color space, eg dark to light for bilevel and grayscale images
 
94
 *                If argument is white or black, set the PHOTOMETRIC_INTERPRETATION 
 
95
 *                tag to MinIsBlack or MinIsWhite without altering the image data
 
96
 *                If the argument is data or both, the image data are modified:
 
97
 *                both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,
 
98
 *                data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag
 
99
 * -D input:<filename1>,output:<filename2>,format:<raw|txt>,level:N,debug:N
 
100
 *                Dump raw data for input and/or output images to individual files
 
101
 *                in raw (binary) format or text (ASCII) representing binary data
 
102
 *                as strings of 1s and 0s. The filename arguments are used as stems
 
103
 *                from which individual files are created for each image. Text format
 
104
 *                includes annotations for image parameters and scanline info. Level
 
105
 *                selects which functions dump data, with higher numbers selecting
 
106
 *                lower level, scanline level routines. Debug reports a limited set
 
107
 *                of messages to monitor progess without enabling dump logs.
 
108
 */
 
109
 
 
110
static   char tiffcrop_version_id[] = "2.4";
 
111
static   char tiffcrop_rev_date[] = "12-13-2010";
 
112
 
 
113
#include "tif_config.h"
 
114
#include "tiffiop.h"
 
115
 
 
116
#include <stdio.h>
 
117
#include <stdlib.h>
 
118
#include <string.h>
 
119
#include <math.h>
 
120
#include <ctype.h>
 
121
#include <limits.h>
 
122
#include <sys/stat.h>
 
123
#include <assert.h>
 
124
 
 
125
#ifdef HAVE_UNISTD_H
 
126
# include <unistd.h>
 
127
#endif
 
128
 
 
129
#ifdef HAVE_STDINT_H
 
130
# include <stdint.h>
 
131
#endif
 
132
 
 
133
#ifndef HAVE_GETOPT
 
134
extern int getopt(int, char**, char*);
 
135
#endif
 
136
 
 
137
#ifdef NEED_LIBPORT
 
138
# include "libport.h"
 
139
#endif
 
140
 
 
141
#include "tiffio.h"
 
142
 
 
143
#if defined(VMS)
 
144
# define unlink delete
 
145
#endif
 
146
 
 
147
#ifndef PATH_MAX
 
148
#define PATH_MAX 1024
 
149
#endif
 
150
 
 
151
#ifndef streq
 
152
#define streq(a,b)      (strcmp((a),(b)) == 0)
 
153
#endif
 
154
#define strneq(a,b,n)   (strncmp((a),(b),(n)) == 0)
 
155
 
 
156
#define TRUE    1
 
157
#define FALSE   0
 
158
 
 
159
#ifndef TIFFhowmany
 
160
#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
 
161
#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
 
162
#endif
 
163
 
 
164
/*
 
165
 * Definitions and data structures required to support cropping and image
 
166
 * manipulations.
 
167
 */
 
168
 
 
169
#define EDGE_TOP      1
 
170
#define EDGE_LEFT     2
 
171
#define EDGE_BOTTOM   3
 
172
#define EDGE_RIGHT    4
 
173
#define EDGE_CENTER   5
 
174
 
 
175
#define MIRROR_HORIZ  1
 
176
#define MIRROR_VERT   2
 
177
#define MIRROR_BOTH   3
 
178
#define ROTATECW_90   8
 
179
#define ROTATECW_180 16
 
180
#define ROTATECW_270 32
 
181
#define ROTATE_ANY ROTATECW_90 || ROTATECW_180 || ROTATECW_270 
 
182
 
 
183
#define CROP_NONE     0
 
184
#define CROP_MARGINS  1
 
185
#define CROP_WIDTH    2
 
186
#define CROP_LENGTH   4
 
187
#define CROP_ZONES    8
 
188
#define CROP_REGIONS 16
 
189
#define CROP_ROTATE  32
 
190
#define CROP_MIRROR  64
 
191
#define CROP_INVERT 128
 
192
 
 
193
/* Modes for writing out images and selections */
 
194
#define ONE_FILE_COMPOSITE       0 /* One file, sections combined sections */
 
195
#define ONE_FILE_SEPARATED       1 /* One file, sections to new IFDs */
 
196
#define FILE_PER_IMAGE_COMPOSITE 2 /* One file per image, combined sections */
 
197
#define FILE_PER_IMAGE_SEPARATED 3 /* One file per input image */
 
198
#define FILE_PER_SELECTION       4 /* One file per selection */
 
199
 
 
200
#define COMPOSITE_IMAGES         0 /* Selections combined into one image */  
 
201
#define SEPARATED_IMAGES         1 /* Selections saved to separate images */
 
202
 
 
203
#define STRIP    1
 
204
#define TILE     2
 
205
 
 
206
#define MAX_REGIONS   8  /* number of regions to extract from a single page */
 
207
#define MAX_OUTBUFFS  8  /* must match larger of zones or regions */
 
208
#define MAX_SECTIONS 32  /* number of sections per page to write to output */
 
209
#define MAX_IMAGES 2048  /* number of images in descrete list, not in the file */
 
210
#define MAX_SAMPLES   8  /* maximum number of samples per pixel supported */
 
211
#define MAX_BITS_PER_SAMPLE 64 /* maximum bit depth supported */
 
212
#define MAX_EXPORT_PAGES 999999  /* maximum number of export pages per file */
 
213
 
 
214
#define DUMP_NONE   0
 
215
#define DUMP_TEXT   1
 
216
#define DUMP_RAW    2
 
217
 
 
218
/* Offsets into buffer for margins and fixed width and length segments */
 
219
struct offset {
 
220
  uint32  tmargin;
 
221
  uint32  lmargin;
 
222
  uint32  bmargin;
 
223
  uint32  rmargin;
 
224
  uint32  crop_width;
 
225
  uint32  crop_length;
 
226
  uint32  startx;
 
227
  uint32  endx;
 
228
  uint32  starty;
 
229
  uint32  endy;
 
230
};
 
231
 
 
232
/* Description of a zone within the image. Position 1 of 3 zones would be 
 
233
 * the first third of the image. These are computed after margins and 
 
234
 * width/length requests are applied so that you can extract multiple 
 
235
 * zones from within a larger region for OCR or barcode recognition.
 
236
 */
 
237
 
 
238
struct  buffinfo {
 
239
  uint32 size;           /* size of this buffer */
 
240
  unsigned char *buffer; /* address of the allocated buffer */
 
241
};
 
242
 
 
243
struct  zone {
 
244
  int   position;  /* ordinal of segment to be extracted */
 
245
  int   total;     /* total equal sized divisions of crop area */
 
246
  };
 
247
 
 
248
struct  pageseg {
 
249
  uint32 x1;        /* index of left edge */
 
250
  uint32 x2;        /* index of right edge */
 
251
  uint32 y1;        /* index of top edge */
 
252
  uint32 y2;        /* index of bottom edge */
 
253
  int    position;  /* ordinal of segment to be extracted */
 
254
  int    total;     /* total equal sized divisions of crop area */
 
255
  uint32 buffsize;  /* size of buffer needed to hold the cropped zone */
 
256
};
 
257
 
 
258
struct  coordpairs {
 
259
  double X1;        /* index of left edge in current units */
 
260
  double X2;        /* index of right edge in current units */
 
261
  double Y1;        /* index of top edge in current units */
 
262
  double Y2;        /* index of bottom edge in current units */
 
263
};
 
264
 
 
265
struct  region {
 
266
  uint32 x1;        /* pixel offset of left edge */
 
267
  uint32 x2;        /* pixel offset of right edge */
 
268
  uint32 y1;        /* pixel offset of top edge */
 
269
  uint32 y2;        /* picel offset of bottom edge */
 
270
  uint32 width;     /* width in pixels */
 
271
  uint32 length;    /* length in pixels */
 
272
  uint32 buffsize;  /* size of buffer needed to hold the cropped region */
 
273
  unsigned char *buffptr; /* address of start of the region */
 
274
};
 
275
 
 
276
/* Cropping parameters from command line and image data 
 
277
 * Note: This should be renamed to proc_opts and expanded to include all current globals
 
278
 * if possible, but each function that accesses global variables will have to be redone.
 
279
 */
 
280
struct crop_mask {
 
281
  double width;           /* Selection width for master crop region in requested units */
 
282
  double length;          /* Selection length for master crop region in requesed units */
 
283
  double margins[4];      /* Top, left, bottom, right margins */
 
284
  float  xres;            /* Horizontal resolution read from image*/
 
285
  float  yres;            /* Vertical resolution read from image */
 
286
  uint32 combined_width;  /* Width of combined cropped zones */
 
287
  uint32 combined_length; /* Length of combined cropped zones */
 
288
  uint32 bufftotal;       /* Size of buffer needed to hold all the cropped region */
 
289
  uint16 img_mode;        /* Composite or separate images created from zones or regions */
 
290
  uint16 exp_mode;        /* Export input images or selections to one or more files */
 
291
  uint16 crop_mode;       /* Crop options to be applied */
 
292
  uint16 res_unit;        /* Resolution unit for margins and selections */
 
293
  uint16 edge_ref;        /* Reference edge for sections extraction and combination */
 
294
  uint16 rotation;        /* Clockwise rotation of the extracted region or image */
 
295
  uint16 mirror;          /* Mirror extracted region or image horizontally or vertically */
 
296
  uint16 invert;          /* Invert the color map of image or region */
 
297
  uint16 photometric;     /* Status of photometric interpretation for inverted image */
 
298
  uint16 selections;      /* Number of regions or zones selected */
 
299
  uint16 regions;         /* Number of regions delimited by corner coordinates */
 
300
  struct region regionlist[MAX_REGIONS]; /* Regions within page or master crop region */
 
301
  uint16 zones;           /* Number of zones delimited by Ordinal:Total requested */
 
302
  struct zone zonelist[MAX_REGIONS]; /* Zones indices to define a region */
 
303
  struct coordpairs corners[MAX_REGIONS]; /* Coordinates of upper left and lower right corner */
 
304
};
 
305
 
 
306
#define MAX_PAPERNAMES 49
 
307
#define MAX_PAPERNAME_LENGTH 15
 
308
#define DEFAULT_RESUNIT      RESUNIT_INCH
 
309
#define DEFAULT_PAGE_HEIGHT   14.0
 
310
#define DEFAULT_PAGE_WIDTH     8.5
 
311
#define DEFAULT_RESOLUTION   300
 
312
#define DEFAULT_PAPER_SIZE  "legal"
 
313
 
 
314
#define ORIENTATION_NONE       0
 
315
#define ORIENTATION_PORTRAIT   1
 
316
#define ORIENTATION_LANDSCAPE  2
 
317
#define ORIENTATION_SEASCAPE   4
 
318
#define ORIENTATION_AUTO      16
 
319
 
 
320
#define PAGE_MODE_NONE         0
 
321
#define PAGE_MODE_RESOLUTION   1
 
322
#define PAGE_MODE_PAPERSIZE    2
 
323
#define PAGE_MODE_MARGINS      4
 
324
#define PAGE_MODE_ROWSCOLS     8
 
325
 
 
326
#define INVERT_DATA_ONLY      10
 
327
#define INVERT_DATA_AND_TAG   11
 
328
 
 
329
struct paperdef {
 
330
  char   name[MAX_PAPERNAME_LENGTH];
 
331
  double width;
 
332
  double length;
 
333
  double asratio;
 
334
  };
 
335
 
 
336
/* European page sizes corrected from update sent by 
 
337
 * thomas . jarosch @ intra2net . com on 5/7/2010
 
338
 * Paper Size       Width   Length  Aspect Ratio */
 
339
struct paperdef PaperTable[MAX_PAPERNAMES] = {
 
340
  {"default",         8.500,  14.000,  0.607},
 
341
  {"pa4",             8.264,  11.000,  0.751},
 
342
  {"letter",          8.500,  11.000,  0.773},
 
343
  {"legal",           8.500,  14.000,  0.607},
 
344
  {"half-letter",     8.500,   5.514,  1.542},
 
345
  {"executive",       7.264,  10.528,  0.690},
 
346
  {"tabloid",        11.000,  17.000,  0.647},
 
347
  {"11x17",          11.000,  17.000,  0.647},
 
348
  {"ledger",         17.000,  11.000,  1.545},
 
349
  {"archa",           9.000,  12.000,  0.750},
 
350
  {"archb",          12.000,  18.000,  0.667},
 
351
  {"archc",          18.000,  24.000,  0.750},
 
352
  {"archd",          24.000,  36.000,  0.667},
 
353
  {"arche",          36.000,  48.000,  0.750},
 
354
  {"csheet",         17.000,  22.000,  0.773},
 
355
  {"dsheet",         22.000,  34.000,  0.647},
 
356
  {"esheet",         34.000,  44.000,  0.773},
 
357
  {"superb",         11.708,  17.042,  0.687},
 
358
  {"commercial",      4.139,   9.528,  0.434},
 
359
  {"monarch",         3.889,   7.528,  0.517},
 
360
  {"envelope-dl",     4.333,   8.681,  0.499},
 
361
  {"envelope-c5",     6.389,   9.028,  0.708},
 
362
  {"europostcard",    4.139,   5.833,  0.710},
 
363
  {"a0",             33.110,  46.811,  0.707},
 
364
  {"a1",             23.386,  33.110,  0.706},
 
365
  {"a2",             16.535,  23.386,  0.707},
 
366
  {"a3",             11.693,  16.535,  0.707},
 
367
  {"a4",              8.268,  11.693,  0.707},
 
368
  {"a5",              5.827,   8.268,  0.705},
 
369
  {"a6",              4.134,   5.827,  0.709},
 
370
  {"a7",              2.913,   4.134,  0.705},
 
371
  {"a8",              2.047,   2.913,  0.703},
 
372
  {"a9",              1.457,   2.047,  0.712},
 
373
  {"a10",             1.024,   1.457,  0.703},
 
374
  {"b0",             39.370,  55.669,  0.707},
 
375
  {"b1",             27.835,  39.370,  0.707},
 
376
  {"b2",             19.685,  27.835,  0.707},
 
377
  {"b3",             13.898,  19.685,  0.706},
 
378
  {"b4",              9.843,  13.898,  0.708},
 
379
  {"b5",              6.929,   9.843,  0.704},
 
380
  {"b6",              4.921,   6.929,  0.710},
 
381
  {"c0",             36.102,  51.063,  0.707},
 
382
  {"c1",             25.512,  36.102,  0.707},
 
383
  {"c2",             18.031,  25.512,  0.707},
 
384
  {"c3",             12.756,  18.031,  0.707},
 
385
  {"c4",              9.016,  12.756,  0.707},
 
386
  {"c5",              6.378,   9.016,  0.707},
 
387
  {"c6",              4.488,   6.378,  0.704},
 
388
  {"",                0.000,   0.000,  1.000}
 
389
};
 
390
 
 
391
/* Structure to define input image parameters */
 
392
struct image_data {
 
393
  float  xres;
 
394
  float  yres;
 
395
  uint32 width;
 
396
  uint32 length;
 
397
  uint16 res_unit;
 
398
  uint16 bps;
 
399
  uint16 spp;
 
400
  uint16 planar;
 
401
  uint16 photometric;
 
402
  uint16 orientation;
 
403
  uint16 compression;
 
404
  uint16 adjustments;
 
405
};
 
406
 
 
407
/* Structure to define the output image modifiers */
 
408
struct pagedef {
 
409
  char          name[16];
 
410
  double        width;    /* width in pixels */
 
411
  double        length;   /* length in pixels */
 
412
  double        hmargin;  /* margins to subtract from width of sections */
 
413
  double        vmargin;  /* margins to subtract from height of sections */
 
414
  double        hres;     /* horizontal resolution for output */
 
415
  double        vres;     /* vertical resolution for output */
 
416
  uint32        mode;     /* bitmask of modifiers to page format */
 
417
  uint16        res_unit; /* resolution unit for output image */
 
418
  unsigned int  rows;     /* number of section rows */
 
419
  unsigned int  cols;     /* number of section cols */
 
420
  unsigned int  orient;   /* portrait, landscape, seascape, auto */
 
421
};
 
422
 
 
423
struct dump_opts {
 
424
  int  debug;
 
425
  int  format;
 
426
  int  level;
 
427
  char mode[4];
 
428
  char infilename[PATH_MAX + 1];
 
429
  char outfilename[PATH_MAX + 1];
 
430
  FILE *infile;
 
431
  FILE *outfile;
 
432
  };
 
433
 
 
434
/* globals */
 
435
static int    outtiled = -1;
 
436
static uint32 tilewidth = 0;
 
437
static uint32 tilelength = 0;
 
438
 
 
439
static uint16 config = 0;
 
440
static uint16 compression = 0;
 
441
static uint16 predictor = 0;
 
442
static uint16 fillorder = 0;
 
443
static uint32 rowsperstrip = 0;
 
444
static uint32 g3opts = 0;
 
445
static int    ignore = FALSE;           /* if true, ignore read errors */
 
446
static uint32 defg3opts = (uint32) -1;
 
447
static int    quality = 100;            /* JPEG quality */
 
448
/* static int    jpegcolormode = -1;        was JPEGCOLORMODE_RGB;  */
 
449
static int    jpegcolormode = JPEGCOLORMODE_RGB;
 
450
static uint16 defcompression = (uint16) -1;
 
451
static uint16 defpredictor = (uint16) -1;
 
452
static int    pageNum = 0;
 
453
static int    little_endian = 1;
 
454
 
 
455
/* Functions adapted from tiffcp with additions or significant modifications */
 
456
static int  readContigStripsIntoBuffer   (TIFF*, uint8*);
 
457
static int  readSeparateStripsIntoBuffer (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
 
458
static int  readContigTilesIntoBuffer    (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
 
459
static int  readSeparateTilesIntoBuffer  (TIFF*, uint8*, uint32, uint32, uint32, uint32, tsample_t, uint16);
 
460
static int  writeBufferToContigStrips    (TIFF*, uint8*, uint32);
 
461
static int  writeBufferToContigTiles     (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
 
462
static int  writeBufferToSeparateStrips  (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
 
463
static int  writeBufferToSeparateTiles   (TIFF*, uint8*, uint32, uint32, tsample_t, struct dump_opts *);
 
464
static int  extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, tsample_t, 
 
465
                                         uint16, uint16, struct dump_opts *);
 
466
static int processCompressOptions(char*);
 
467
static void usage(void);
 
468
 
 
469
/* All other functions by Richard Nolde,  not found in tiffcp */
 
470
static void initImageData (struct image_data *);
 
471
static void initCropMasks (struct crop_mask *);
 
472
static void initPageSetup (struct pagedef *, struct pageseg *, struct buffinfo []);
 
473
static void initDumpOptions(struct dump_opts *);
 
474
 
 
475
/* Command line and file naming functions */
 
476
void  process_command_opts (int, char *[], char *, char *, uint32 *,
 
477
                            uint16 *, uint16 *, uint32 *, uint32 *, uint32 *,
 
478
                            struct crop_mask *, struct pagedef *, 
 
479
                            struct dump_opts *, 
 
480
                            unsigned int *, unsigned int *);
 
481
static  int update_output_file (TIFF **, char *, int, char *, unsigned int *);
 
482
 
 
483
 
 
484
/*  * High level functions for whole image manipulation */
 
485
static int  get_page_geometry (char *, struct pagedef*);
 
486
static int  computeInputPixelOffsets(struct crop_mask *, struct image_data *, 
 
487
                                     struct offset *);
 
488
static int  computeOutputPixelOffsets (struct crop_mask *, struct image_data *,
 
489
                                       struct pagedef *, struct pageseg *,
 
490
                                       struct dump_opts *);
 
491
static int  loadImage(TIFF *, struct image_data *, struct dump_opts *, unsigned char **);
 
492
static int  correct_orientation(struct image_data *, unsigned char **);
 
493
static int  getCropOffsets(struct image_data *, struct crop_mask *, struct dump_opts *);
 
494
static int  processCropSelections(struct image_data *, struct crop_mask *, 
 
495
                                  unsigned char **, struct buffinfo []);
 
496
static int  writeSelections(TIFF *, TIFF **, struct crop_mask *, struct image_data *,
 
497
                            struct dump_opts *, struct buffinfo [],
 
498
                            char *, char *, unsigned int*, unsigned int);
 
499
 
 
500
/* Section functions */
 
501
static int  createImageSection(uint32, unsigned char **);
 
502
static int  extractImageSection(struct image_data *, struct pageseg *, 
 
503
                                unsigned char *, unsigned char *);
 
504
static int  writeSingleSection(TIFF *, TIFF *, struct image_data *,
 
505
                               struct dump_opts *, uint32, uint32,
 
506
                               double, double, unsigned char *);
 
507
static int  writeImageSections(TIFF *, TIFF *, struct image_data *,
 
508
                               struct pagedef *, struct pageseg *, 
 
509
                               struct dump_opts *, unsigned char *, 
 
510
                               unsigned char **);
 
511
/* Whole image functions */
 
512
static int  createCroppedImage(struct image_data *, struct crop_mask *, 
 
513
                               unsigned char **, unsigned char **);
 
514
static int  writeCroppedImage(TIFF *, TIFF *, struct image_data *image,
 
515
                              struct dump_opts * dump,
 
516
                              uint32, uint32, unsigned char *, int, int);
 
517
 
 
518
/* Image manipulation functions */
 
519
static int rotateContigSamples8bits(uint16, uint16, uint16, uint32, 
 
520
                                    uint32,   uint32, uint8 *, uint8 *);
 
521
static int rotateContigSamples16bits(uint16, uint16, uint16, uint32, 
 
522
                                     uint32,   uint32, uint8 *, uint8 *);
 
523
static int rotateContigSamples24bits(uint16, uint16, uint16, uint32, 
 
524
                                     uint32,   uint32, uint8 *, uint8 *);
 
525
static int rotateContigSamples32bits(uint16, uint16, uint16, uint32, 
 
526
                                     uint32,   uint32, uint8 *, uint8 *);
 
527
static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
 
528
                       unsigned char **);
 
529
static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
 
530
                       unsigned char *);
 
531
static int invertImage(uint16, uint16, uint16, uint32, uint32,
 
532
                       unsigned char *);
 
533
 
 
534
/* Functions to reverse the sequence of samples in a scanline */
 
535
static int reverseSamples8bits  (uint16, uint16, uint32, uint8 *, uint8 *);
 
536
static int reverseSamples16bits (uint16, uint16, uint32, uint8 *, uint8 *);
 
537
static int reverseSamples24bits (uint16, uint16, uint32, uint8 *, uint8 *);
 
538
static int reverseSamples32bits (uint16, uint16, uint32, uint8 *, uint8 *);
 
539
static int reverseSamplesBytes  (uint16, uint16, uint32, uint8 *, uint8 *);
 
540
 
 
541
/* Functions for manipulating individual samples in an image */
 
542
static int extractSeparateRegion(struct image_data *, struct crop_mask *,
 
543
                                 unsigned char *, unsigned char *, int);
 
544
static int extractCompositeRegions(struct image_data *,  struct crop_mask *,
 
545
                                   unsigned char *, unsigned char *);
 
546
static int extractContigSamples8bits (uint8 *, uint8 *, uint32,
 
547
                                     tsample_t, uint16, uint16, 
 
548
                                     tsample_t, uint32, uint32);
 
549
static int extractContigSamples16bits (uint8 *, uint8 *, uint32,
 
550
                                      tsample_t, uint16, uint16, 
 
551
                                      tsample_t, uint32, uint32);
 
552
static int extractContigSamples24bits (uint8 *, uint8 *, uint32,
 
553
                                      tsample_t, uint16, uint16, 
 
554
                                      tsample_t, uint32, uint32);
 
555
static int extractContigSamples32bits (uint8 *, uint8 *, uint32,
 
556
                                      tsample_t, uint16, uint16, 
 
557
                                      tsample_t, uint32, uint32);
 
558
static int extractContigSamplesBytes (uint8 *, uint8 *, uint32, 
 
559
                                      tsample_t, uint16, uint16, 
 
560
                                      tsample_t, uint32, uint32);
 
561
static int extractContigSamplesShifted8bits (uint8 *, uint8 *, uint32,
 
562
                                             tsample_t, uint16, uint16,
 
563
                                             tsample_t, uint32, uint32,
 
564
                                             int);
 
565
static int extractContigSamplesShifted16bits (uint8 *, uint8 *, uint32,
 
566
                                              tsample_t, uint16, uint16, 
 
567
                                              tsample_t, uint32, uint32,
 
568
                                              int);
 
569
static int extractContigSamplesShifted24bits (uint8 *, uint8 *, uint32,
 
570
                                              tsample_t, uint16, uint16, 
 
571
                                              tsample_t, uint32, uint32,
 
572
                                              int);
 
573
static int extractContigSamplesShifted32bits (uint8 *, uint8 *, uint32,
 
574
                                              tsample_t, uint16, uint16, 
 
575
                                              tsample_t, uint32, uint32,
 
576
                                              int);
 
577
static int extractContigSamplesToTileBuffer(uint8 *, uint8 *, uint32, uint32,
 
578
                                            uint32, uint32, tsample_t, uint16,
 
579
                                            uint16, uint16, struct dump_opts *);
 
580
 
 
581
/* Functions to combine separate planes into interleaved planes */
 
582
static int combineSeparateSamples8bits (uint8 *[], uint8 *, uint32, uint32,
 
583
                                        uint16, uint16, FILE *, int, int);
 
584
static int combineSeparateSamples16bits (uint8 *[], uint8 *, uint32, uint32,
 
585
                                         uint16, uint16, FILE *, int, int);
 
586
static int combineSeparateSamples24bits (uint8 *[], uint8 *, uint32, uint32,
 
587
                                         uint16, uint16, FILE *, int, int);
 
588
static int combineSeparateSamples32bits (uint8 *[], uint8 *, uint32, uint32,
 
589
                                         uint16, uint16, FILE *, int, int);
 
590
static int combineSeparateSamplesBytes (unsigned char *[], unsigned char *,
 
591
                                        uint32, uint32, tsample_t, uint16,
 
592
                                        FILE *, int, int);
 
593
 
 
594
static int combineSeparateTileSamples8bits (uint8 *[], uint8 *, uint32, uint32,
 
595
                                            uint32, uint32, uint16, uint16, 
 
596
                                            FILE *, int, int);
 
597
static int combineSeparateTileSamples16bits (uint8 *[], uint8 *, uint32, uint32,
 
598
                                             uint32, uint32, uint16, uint16,
 
599
                                             FILE *, int, int);
 
600
static int combineSeparateTileSamples24bits (uint8 *[], uint8 *, uint32, uint32,
 
601
                                             uint32, uint32, uint16, uint16,
 
602
                                             FILE *, int, int);
 
603
static int combineSeparateTileSamples32bits (uint8 *[], uint8 *, uint32, uint32,
 
604
                                             uint32, uint32, uint16, uint16,
 
605
                                             FILE *, int, int);
 
606
static int combineSeparateTileSamplesBytes (unsigned char *[], unsigned char *,
 
607
                                            uint32, uint32, uint32, uint32, 
 
608
                                            tsample_t, uint16, FILE *, int, int);
 
609
 
 
610
/* Dump functions for debugging */
 
611
static void dump_info  (FILE *, int, char *, char *, ...);
 
612
static int  dump_data  (FILE *, int, char *, unsigned char *, uint32);
 
613
static int  dump_byte  (FILE *, int, char *, unsigned char);
 
614
static int  dump_short (FILE *, int, char *, uint16);
 
615
static int  dump_long  (FILE *, int, char *, uint32);
 
616
static int  dump_wide  (FILE *, int, char *, uint64);
 
617
static int  dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *);
 
618
 
 
619
/* End function declarations */
 
620
/* Functions derived in whole or in part from tiffcp */
 
621
/* The following functions are taken largely intact from tiffcp */
 
622
 
 
623
static   char* usage_info[] = {
 
624
"usage: tiffcrop [options] source1 ... sourceN  destination",
 
625
"where options are:",
 
626
" -h            Print this syntax listing",
 
627
" -v            Print tiffcrop version identifier and last revision date",
 
628
" ",
 
629
" -a            Append to output instead of overwriting",
 
630
" -d offset     Set initial directory offset, counting first image as one, not zero",
 
631
" -p contig     Pack samples contiguously (e.g. RGBRGB...)",
 
632
" -p separate   Store samples separately (e.g. RRR...GGG...BBB...)",
 
633
" -s            Write output in strips",
 
634
" -t            Write output in tiles",
 
635
" -i            Ignore read errors",
 
636
" ",
 
637
" -r #          Make each strip have no more than # rows",
 
638
" -w #          Set output tile width (pixels)",
 
639
" -l #          Set output tile length (pixels)",
 
640
" ",
 
641
" -f lsb2msb    Force lsb-to-msb FillOrder for output",
 
642
" -f msb2lsb    Force msb-to-lsb FillOrder for output",
 
643
"",
 
644
" -c lzw[:opts]  Compress output with Lempel-Ziv & Welch encoding",
 
645
" -c zip[:opts]  Compress output with deflate encoding",
 
646
" -c jpeg[:opts] Compress output with JPEG encoding",
 
647
" -c packbits    Compress output with packbits encoding",
 
648
" -c g3[:opts]   Compress output with CCITT Group 3 encoding",
 
649
" -c g4          Compress output with CCITT Group 4 encoding",
 
650
" -c none        Use no compression algorithm on output",
 
651
" ",
 
652
"Group 3 options:",
 
653
" 1d            Use default CCITT Group 3 1D-encoding",
 
654
" 2d            Use optional CCITT Group 3 2D-encoding",
 
655
" fill          Byte-align EOL codes",
 
656
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
 
657
" ",
 
658
"JPEG options:",
 
659
" #             Set compression quality level (0-100, default 100)",
 
660
" raw           Output color image as raw YCbCr",
 
661
" rgb           Output color image as RGB",
 
662
"For example, -c jpeg:rgb:50 to get JPEG-encoded RGB data with 50% comp. quality",
 
663
" ",
 
664
"LZW and deflate options:",
 
665
" #             Set predictor value",
 
666
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
 
667
" ",
 
668
"Page and selection options:",
 
669
" -N odd|even|#,#-#,#|last         sequences and ranges of images within file to process",
 
670
"             The words odd or even may be used to specify all odd or even numbered images.",
 
671
"             The word last may be used in place of a number in the sequence to indicate.",
 
672
"             The final image in the file without knowing how many images there are.",
 
673
"             Numbers are counted from one even though TIFF IFDs are counted from zero.",
 
674
" ",
 
675
" -E t|l|r|b  edge to use as origin for width and length of crop region",
 
676
" -U units    [in, cm, px ] inches, centimeters or pixels",
 
677
" ",
 
678
" -m #,#,#,#  margins from edges for selection: top, left, bottom, right separated by commas",
 
679
" -X #        horizontal dimension of region to extract expressed in current units",
 
680
" -Y #        vertical dimension of region to extract expressed in current units",
 
681
" -Z #:#,#:#  zones of the image designated as position X of Y,",
 
682
"             eg 1:3 would be first of three equal portions measured from reference edge",
 
683
" -z x1,y1,x2,y2:...:xN,yN,xN+1,yN+1",
 
684
"             regions of the image designated by upper left and lower right coordinates",
 
685
"",
 
686
"Export grouping options:",
 
687
" -e c|d|i|m|s    export mode for images and selections from input images.",
 
688
"                 When exporting a composite image from multiple zones or regions",
 
689
"                 (combined and image modes), the selections must have equal sizes",
 
690
"                 for the axis perpendicular to the edge specified with -E.",
 
691
"    c|combined   All images and selections are written to a single file (default).",
 
692
"                 with multiple selections from one image combined into a single image.",
 
693
"    d|divided    All images and selections are written to a single file",
 
694
"                 with each selection from one image written to a new image.",
 
695
"    i|image      Each input image is written to a new file (numeric filename sequence)",
 
696
"                 with multiple selections from the image combined into one image.",
 
697
"    m|multiple   Each input image is written to a new file (numeric filename sequence)",
 
698
"                 with each selection from the image written to a new image.",
 
699
"    s|separated  Individual selections from each image are written to separate files.",
 
700
"",
 
701
"Output options:",
 
702
" -H #        Set horizontal resolution of output images to #",
 
703
" -V #        Set vertical resolution of output images to #",
 
704
" -J #        Set horizontal margin of output page to # expressed in current units",
 
705
"             when sectioning image into columns x rows using the -S cols:rows option",
 
706
" -K #        Set verticalal margin of output page to # expressed in current units",
 
707
"             when sectioning image into columns x rows using the -S cols:rows option",
 
708
" ",
 
709
" -O orient    orientation for output image, portrait, landscape, auto",
 
710
" -P page      page size for output image segments, eg letter, legal, tabloid, etc",
 
711
"              use #.#x#.# to specify a custom page size in the currently defined units",
 
712
"              where #.# represents the width and length",        
 
713
" -S cols:rows Divide the image into equal sized segments using cols across and rows down.",
 
714
" ",
 
715
" -F hor|vert|both",
 
716
"             flip (mirror) image or region horizontally, vertically, or both",
 
717
" -R #        [90,180,or 270] degrees clockwise rotation of image or extracted region",
 
718
" -I [black|white|data|both]",
 
719
"             invert color space, eg dark to light for bilevel and grayscale images",
 
720
"             If argument is white or black, set the PHOTOMETRIC_INTERPRETATION ",
 
721
"             tag to MinIsBlack or MinIsWhite without altering the image data",
 
722
"             If the argument is data or both, the image data are modified:",
 
723
"             both inverts the data and the PHOTOMETRIC_INTERPRETATION tag,",
 
724
"             data inverts the data but not the PHOTOMETRIC_INTERPRETATION tag",
 
725
" ",
 
726
"-D opt1:value1,opt2:value2,opt3:value3:opt4:value4",
 
727
"             Debug/dump program progress and/or data to non-TIFF files.",
 
728
"             Options include the following and must be joined as a comma",
 
729
"             separate list. The use of this option is generally limited to",
 
730
"             program debugging and development of future options.",
 
731
" ",
 
732
"   debug:N   Display limited program progress indicators where larger N",
 
733
"             increase the level of detail. Note: Tiffcrop may be compiled with",
 
734
"             -DDEVELMODE to enable additional very low level debug reporting.",
 
735
"",
 
736
"   Format:txt|raw  Format any logged data as ASCII text or raw binary ",
 
737
"             values. ASCII text dumps include strings of ones and zeroes",
 
738
"             representing the binary values in the image data plus identifying headers.",
 
739
" ",
 
740
"   level:N   Specify the level of detail presented in the dump files.",
 
741
"             This can vary from dumps of the entire input or output image data to dumps",
 
742
"             of data processed by specific functions. Current range of levels is 1 to 3.",
 
743
" ",
 
744
"   input:full-path-to-directory/input-dumpname",
 
745
" ",
 
746
"   output:full-path-to-directory/output-dumpnaem",
 
747
" ",
 
748
"             When dump files are being written, each image will be written to a separate",
 
749
"             file with the name built by adding a numeric sequence value to the dumpname",
 
750
"             and an extension of .txt for ASCII dumps or .bin for binary dumps.",
 
751
" ",
 
752
"             The four debug/dump options are independent, though it makes little sense to",
 
753
"             specify a dump file without specifying a detail level.",
 
754
" ",
 
755
NULL
 
756
};
 
757
 
 
758
/* This function could be modified to pass starting sample offset 
 
759
 * and number of samples as args to select fewer than spp
 
760
 * from input image. These would then be passed to individual 
 
761
 * extractContigSampleXX routines.
 
762
 */
 
763
static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, 
 
764
                                      uint32 imagelength, 
 
765
                                      uint32 imagewidth, 
 
766
                                      uint32 tw, uint32 tl,
 
767
                                      tsample_t spp, uint16 bps)
 
768
  {
 
769
  int status = 1;
 
770
  tsample_t sample = 0;
 
771
  tsample_t count = spp; 
 
772
  uint32 row, col, trow;
 
773
  uint32 nrow, ncol;
 
774
  uint32 dst_rowsize, shift_width;
 
775
  uint32 bytes_per_sample, bytes_per_pixel;
 
776
  uint32 trailing_bits, prev_trailing_bits;
 
777
  uint32 tile_rowsize  = TIFFTileRowSize(in);
 
778
  uint32 src_offset, dst_offset;
 
779
  uint32 row_offset, col_offset;
 
780
  uint8 *bufp = (uint8*) buf;
 
781
  unsigned char *src = NULL;
 
782
  unsigned char *dst = NULL;
 
783
  tsize_t tbytes = 0, tile_buffsize = 0;
 
784
  tsize_t tilesize = TIFFTileSize(in);
 
785
  unsigned char *tilebuf = NULL;
 
786
 
 
787
  bytes_per_sample = (bps + 7) / 8; 
 
788
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
789
 
 
790
  if ((bps % 8) == 0)
 
791
    shift_width = 0;
 
792
  else
 
793
    {
 
794
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
795
      shift_width = bytes_per_pixel;
 
796
    else
 
797
      shift_width = bytes_per_sample + 1;
 
798
    }
 
799
 
 
800
  tile_buffsize = tilesize;
 
801
 
 
802
  if (tilesize < (tsize_t)(tl * tile_rowsize))
 
803
    {
 
804
#ifdef DEBUG2
 
805
    TIFFError("readContigTilesIntoBuffer",
 
806
              "Tilesize %lu is too small, using alternate calculation %u",
 
807
              tilesize, tl * tile_rowsize);
 
808
#endif
 
809
    tile_buffsize = tl * tile_rowsize;
 
810
    } 
 
811
 
 
812
  tilebuf = _TIFFmalloc(tile_buffsize);
 
813
  if (tilebuf == 0)
 
814
    return 0;
 
815
 
 
816
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;  
 
817
  for (row = 0; row < imagelength; row += tl)
 
818
    {
 
819
    nrow = (row + tl > imagelength) ? imagelength - row : tl;
 
820
    for (col = 0; col < imagewidth; col += tw)
 
821
      {
 
822
      tbytes = TIFFReadTile(in, tilebuf, col, row, 0, 0);
 
823
      if (tbytes < tilesize  && !ignore)
 
824
        {
 
825
        TIFFError(TIFFFileName(in),
 
826
                  "Error, can't read tile at row %lu col %lu, Read %lu bytes of %lu",
 
827
                  (unsigned long) col, (unsigned long) row, (unsigned long)tbytes,
 
828
                  (unsigned long)tilesize);
 
829
                  status = 0;
 
830
                  _TIFFfree(tilebuf);
 
831
                  return status;
 
832
        }
 
833
      
 
834
      row_offset = row * dst_rowsize;
 
835
      col_offset = ((col * bps * spp) + 7)/ 8;
 
836
      bufp = buf + row_offset + col_offset;
 
837
 
 
838
      if (col + tw > imagewidth)
 
839
        ncol = imagewidth - col;
 
840
      else
 
841
        ncol = tw;
 
842
 
 
843
      /* Each tile scanline will start on a byte boundary but it
 
844
       * has to be merged into the scanline for the entire
 
845
       * image buffer and the previous segment may not have
 
846
       * ended on a byte boundary
 
847
       */
 
848
      /* Optimization for common bit depths, all samples */
 
849
      if (((bps % 8) == 0) && (count == spp))
 
850
        {
 
851
        for (trow = 0; trow < nrow; trow++)
 
852
          {
 
853
          src_offset = trow * tile_rowsize;
 
854
          _TIFFmemcpy (bufp, tilebuf + src_offset, (ncol * spp * bps) / 8);
 
855
          bufp += (imagewidth * bps * spp) / 8;
 
856
          }
 
857
        }
 
858
      else
 
859
        {
 
860
        /* Bit depths not a multiple of 8 and/or extract fewer than spp samples */
 
861
        prev_trailing_bits = trailing_bits = 0;
 
862
        trailing_bits = (ncol * bps * spp) % 8;
 
863
 
 
864
        /*      for (trow = 0; tl < nrow; trow++) */
 
865
        for (trow = 0; trow < nrow; trow++)
 
866
          {
 
867
          src_offset = trow * tile_rowsize;
 
868
          src = tilebuf + src_offset;
 
869
          dst_offset = (row + trow) * dst_rowsize;
 
870
          dst = buf + dst_offset + col_offset;
 
871
          switch (shift_width)
 
872
            {
 
873
            case 0: if (extractContigSamplesBytes (src, dst, ncol, sample,
 
874
                                                   spp, bps, count, 0, ncol))
 
875
                      {
 
876
                      TIFFError("readContigTilesIntoBuffer",
 
877
                                "Unable to extract row %d from tile %lu", 
 
878
                                row, (unsigned long)TIFFCurrentTile(in));
 
879
                      return 1;
 
880
                      }
 
881
                    break;
 
882
            case 1: if (bps == 1)
 
883
                      { 
 
884
                      if (extractContigSamplesShifted8bits (src, dst, ncol,
 
885
                                                            sample, spp,
 
886
                                                            bps, count,
 
887
                                                            0, ncol,
 
888
                                                            prev_trailing_bits))
 
889
                        {
 
890
                        TIFFError("readContigTilesIntoBuffer",
 
891
                                  "Unable to extract row %d from tile %lu", 
 
892
                                  row, (unsigned long)TIFFCurrentTile(in));
 
893
                        return 1;
 
894
                        }
 
895
                      break;
 
896
                      }
 
897
                    else
 
898
                      if (extractContigSamplesShifted16bits (src, dst, ncol,
 
899
                                                             sample, spp,
 
900
                                                             bps, count,
 
901
                                                             0, ncol,
 
902
                                                             prev_trailing_bits))
 
903
                        {
 
904
                        TIFFError("readContigTilesIntoBuffer",
 
905
                                  "Unable to extract row %d from tile %lu", 
 
906
                                  row, (unsigned long)TIFFCurrentTile(in));
 
907
                        return 1;
 
908
                        }
 
909
                    break;
 
910
            case 2: if (extractContigSamplesShifted24bits (src, dst, ncol,
 
911
                                                           sample, spp,
 
912
                                                           bps, count,
 
913
                                                           0, ncol,
 
914
                                                           prev_trailing_bits))
 
915
                      {
 
916
                      TIFFError("readContigTilesIntoBuffer",
 
917
                                "Unable to extract row %d from tile %lu", 
 
918
                                row, (unsigned long)TIFFCurrentTile(in));
 
919
                      return 1;
 
920
                      }
 
921
                    break;
 
922
            case 3:
 
923
            case 4:
 
924
            case 5: if (extractContigSamplesShifted32bits (src, dst, ncol,
 
925
                                                           sample, spp,
 
926
                                                           bps, count,
 
927
                                                           0, ncol,
 
928
                                                           prev_trailing_bits))
 
929
                      {
 
930
                      TIFFError("readContigTilesIntoBuffer",
 
931
                                "Unable to extract row %d from tile %lu", 
 
932
                                row, (unsigned long)TIFFCurrentTile(in));
 
933
                      return 1;
 
934
                      }
 
935
                    break;
 
936
            default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %d", bps);
 
937
                     return 1;
 
938
            }
 
939
          }
 
940
        prev_trailing_bits += trailing_bits;
 
941
        if (prev_trailing_bits > 7)
 
942
          prev_trailing_bits-= 8;
 
943
        }
 
944
      }
 
945
    }
 
946
 
 
947
  _TIFFfree(tilebuf);
 
948
  return status;
 
949
  }
 
950
 
 
951
static int  readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf, 
 
952
                                         uint32 imagelength, uint32 imagewidth, 
 
953
                                         uint32 tw, uint32 tl,
 
954
                                         uint16 spp, uint16 bps)
 
955
  {
 
956
  int     i, status = 1, sample;
 
957
  int     shift_width, bytes_per_pixel;
 
958
  uint16  bytes_per_sample;
 
959
  uint32  row, col;     /* Current row and col of image */
 
960
  uint32  nrow, ncol;   /* Number of rows and cols in current tile */
 
961
  uint32  row_offset, col_offset; /* Output buffer offsets */
 
962
  tsize_t tbytes = 0, tilesize = TIFFTileSize(in);
 
963
  tsample_t s;
 
964
  uint8*  bufp = (uint8*)obuf;
 
965
  unsigned char *srcbuffs[MAX_SAMPLES];
 
966
  unsigned char *tbuff = NULL;
 
967
 
 
968
  bytes_per_sample = (bps + 7) / 8;
 
969
 
 
970
  for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
 
971
    {
 
972
    srcbuffs[sample] = NULL;
 
973
    tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
 
974
    if (!tbuff)
 
975
      {
 
976
      TIFFError ("readSeparateTilesIntoBuffer", 
 
977
                 "Unable to allocate tile read buffer for sample %d", sample);
 
978
      for (i = 0; i < sample; i++)
 
979
        _TIFFfree (srcbuffs[i]);
 
980
      return 0;
 
981
      }
 
982
    srcbuffs[sample] = tbuff;
 
983
    } 
 
984
  /* Each tile contains only the data for a single plane
 
985
   * arranged in scanlines of tw * bytes_per_sample bytes.
 
986
   */
 
987
  for (row = 0; row < imagelength; row += tl)
 
988
    {
 
989
    nrow = (row + tl > imagelength) ? imagelength - row : tl;
 
990
    for (col = 0; col < imagewidth; col += tw)
 
991
      {
 
992
      for (s = 0; s < spp; s++)
 
993
        {  /* Read each plane of a tile set into srcbuffs[s] */
 
994
        tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
 
995
        if (tbytes < 0  && !ignore)
 
996
          {
 
997
          TIFFError(TIFFFileName(in),
 
998
                 "Error, can't read tile for row %lu col %lu, "
 
999
                 "sample %lu",
 
1000
                 (unsigned long) col, (unsigned long) row,
 
1001
                 (unsigned long) s);
 
1002
                 status = 0;
 
1003
          for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
 
1004
            {
 
1005
            tbuff = srcbuffs[sample];
 
1006
            if (tbuff != NULL)
 
1007
              _TIFFfree(tbuff);
 
1008
            }
 
1009
          return status;
 
1010
          }
 
1011
        }
 
1012
     /* Tiles on the right edge may be padded out to tw 
 
1013
      * which must be a multiple of 16.
 
1014
      * Ncol represents the visible (non padding) portion.  
 
1015
      */
 
1016
      if (col + tw > imagewidth)
 
1017
        ncol = imagewidth - col;
 
1018
      else
 
1019
        ncol = tw;
 
1020
 
 
1021
      row_offset = row * (((imagewidth * spp * bps) + 7) / 8);
 
1022
      col_offset = ((col * spp * bps) + 7) / 8;
 
1023
      bufp = obuf + row_offset + col_offset;
 
1024
 
 
1025
      if ((bps % 8) == 0)
 
1026
        {
 
1027
        if (combineSeparateTileSamplesBytes(srcbuffs, bufp, ncol, nrow, imagewidth,
 
1028
                                            tw, spp, bps, NULL, 0, 0))
 
1029
          {
 
1030
          status = 0;
 
1031
          break;
 
1032
          }
 
1033
        }
 
1034
      else
 
1035
        {
 
1036
        bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
1037
        if (bytes_per_pixel < (bytes_per_sample + 1))
 
1038
          shift_width = bytes_per_pixel;
 
1039
        else
 
1040
          shift_width = bytes_per_sample + 1;
 
1041
 
 
1042
        switch (shift_width)
 
1043
          {
 
1044
          case 1: if (combineSeparateTileSamples8bits (srcbuffs, bufp, ncol, nrow,
 
1045
                                                       imagewidth, tw, spp, bps, 
 
1046
                                                       NULL, 0, 0))
 
1047
                    {
 
1048
                    status = 0;
 
1049
                    break;
 
1050
                    }
 
1051
                  break;
 
1052
          case 2: if (combineSeparateTileSamples16bits (srcbuffs, bufp, ncol, nrow,
 
1053
                                                       imagewidth, tw, spp, bps, 
 
1054
                                                       NULL, 0, 0))
 
1055
                    {
 
1056
                    status = 0;
 
1057
                    break;
 
1058
                    }
 
1059
                  break;
 
1060
          case 3: if (combineSeparateTileSamples24bits (srcbuffs, bufp, ncol, nrow,
 
1061
                                                       imagewidth, tw, spp, bps, 
 
1062
                                                       NULL, 0, 0))
 
1063
                    {
 
1064
                    status = 0;
 
1065
                    break;
 
1066
                    }
 
1067
                  break;
 
1068
          case 4: 
 
1069
          case 5:
 
1070
          case 6:
 
1071
          case 7:
 
1072
          case 8: if (combineSeparateTileSamples32bits (srcbuffs, bufp, ncol, nrow,
 
1073
                                                       imagewidth, tw, spp, bps, 
 
1074
                                                       NULL, 0, 0))
 
1075
                    {
 
1076
                    status = 0;
 
1077
                    break;
 
1078
                    }
 
1079
                  break;
 
1080
          default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps);
 
1081
                  status = 0;
 
1082
                  break;
 
1083
          }
 
1084
        }
 
1085
      }
 
1086
    }
 
1087
 
 
1088
  for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
 
1089
    {
 
1090
    tbuff = srcbuffs[sample];
 
1091
    if (tbuff != NULL)
 
1092
      _TIFFfree(tbuff);
 
1093
    }
 
1094
 
 
1095
  return status;
 
1096
  }
 
1097
 
 
1098
static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength)
 
1099
  {
 
1100
  uint32 row, nrows, rowsperstrip;
 
1101
  tstrip_t strip = 0;
 
1102
  tsize_t stripsize;
 
1103
 
 
1104
  TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
 
1105
  for (row = 0; row < imagelength; row += rowsperstrip)
 
1106
    {
 
1107
    nrows = (row + rowsperstrip > imagelength) ?
 
1108
             imagelength - row : rowsperstrip;
 
1109
    stripsize = TIFFVStripSize(out, nrows);
 
1110
    if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
 
1111
      {
 
1112
      TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
 
1113
      return 1;
 
1114
      }
 
1115
    buf += stripsize;
 
1116
    }
 
1117
 
 
1118
  return 0;
 
1119
  }
 
1120
 
 
1121
/* Abandon plans to modify code so that plannar orientation separate images
 
1122
 * do not have all samples for each channel written before all samples
 
1123
 * for the next channel have been abandoned.
 
1124
 * Libtiff internals seem to depend on all data for a given sample
 
1125
 * being contiguous within a strip or tile when PLANAR_CONFIG is 
 
1126
 * separate. All strips or tiles of a given plane are written
 
1127
 * before any strips or tiles of a different plane are stored.
 
1128
 */
 
1129
static int 
 
1130
writeBufferToSeparateStrips (TIFF* out, uint8* buf, 
 
1131
                             uint32 length, uint32 width, uint16 spp,
 
1132
                             struct dump_opts *dump)
 
1133
  {
 
1134
  uint8   *src;
 
1135
  uint16   bps;
 
1136
  uint32   row, nrows, rowsize, rowsperstrip;
 
1137
  uint32   bytes_per_sample;
 
1138
  tsample_t s;
 
1139
  tstrip_t strip = 0;
 
1140
  tsize_t  stripsize = TIFFStripSize(out);
 
1141
  tsize_t  rowstripsize,  scanlinesize = TIFFScanlineSize(out);
 
1142
  tsize_t  total_bytes = 0;
 
1143
  tdata_t  obuf;
 
1144
 
 
1145
  (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
 
1146
  (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
 
1147
  bytes_per_sample = (bps + 7) / 8;
 
1148
  rowsize = ((bps * spp * width) + 7) / 8; /* source has interleaved samples */
 
1149
  rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); 
 
1150
 
 
1151
  obuf = _TIFFmalloc (rowstripsize);
 
1152
  if (obuf == NULL)
 
1153
    return 1;
 
1154
  
 
1155
  for (s = 0; s < spp; s++)
 
1156
    {
 
1157
    for (row = 0; row < length; row += rowsperstrip)
 
1158
      {
 
1159
      nrows = (row + rowsperstrip > length) ? length - row : rowsperstrip;
 
1160
 
 
1161
      stripsize = TIFFVStripSize(out, nrows);
 
1162
      src = buf + (row * rowsize);
 
1163
      total_bytes += stripsize;
 
1164
      memset (obuf, '\0', rowstripsize);
 
1165
      if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
 
1166
        {
 
1167
        _TIFFfree(obuf);
 
1168
        return 1;
 
1169
        }
 
1170
      if ((dump->outfile != NULL) && (dump->level == 1))
 
1171
        {
 
1172
        dump_info(dump->outfile, dump->format,"", 
 
1173
                  "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d", 
 
1174
                  s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
 
1175
        dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
 
1176
        }
 
1177
 
 
1178
      if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
 
1179
        {
 
1180
        TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
 
1181
        _TIFFfree(obuf);
 
1182
        return 1;
 
1183
        }
 
1184
      }
 
1185
    }      
 
1186
 
 
1187
  _TIFFfree(obuf);
 
1188
  return 0;
 
1189
}
 
1190
 
 
1191
/* Extract all planes from contiguous buffer into a single tile buffer 
 
1192
 * to be written out as a tile.
 
1193
 */
 
1194
static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
 
1195
                                       uint32 imagewidth, tsample_t spp, 
 
1196
                                       struct dump_opts* dump)
 
1197
  {
 
1198
  uint16 bps;
 
1199
  uint32 tl, tw;
 
1200
  uint32 row, col, nrow, ncol;
 
1201
  uint32 src_rowsize, col_offset;
 
1202
  uint32 tile_rowsize  = TIFFTileRowSize(out);
 
1203
  uint8* bufp = (uint8*) buf;
 
1204
  tsize_t tile_buffsize = 0;
 
1205
  tsize_t tilesize = TIFFTileSize(out);
 
1206
  unsigned char *tilebuf = NULL;
 
1207
 
 
1208
  TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
 
1209
  TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
 
1210
  TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
 
1211
 
 
1212
  tile_buffsize = tilesize;
 
1213
  if (tilesize < (tsize_t)(tl * tile_rowsize))
 
1214
    {
 
1215
#ifdef DEBUG2
 
1216
    TIFFError("writeBufferToContigTiles",
 
1217
              "Tilesize %lu is too small, using alternate calculation %u",
 
1218
              tilesize, tl * tile_rowsize);
 
1219
#endif
 
1220
    tile_buffsize = tl * tile_rowsize;
 
1221
    }
 
1222
 
 
1223
  tilebuf = _TIFFmalloc(tile_buffsize);
 
1224
  if (tilebuf == 0)
 
1225
    return 1;
 
1226
 
 
1227
  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
 
1228
  for (row = 0; row < imagelength; row += tl)
 
1229
    {
 
1230
    nrow = (row + tl > imagelength) ? imagelength - row : tl;
 
1231
    for (col = 0; col < imagewidth; col += tw)
 
1232
      {
 
1233
      /* Calculate visible portion of tile. */
 
1234
      if (col + tw > imagewidth)
 
1235
        ncol = imagewidth - col;
 
1236
      else
 
1237
        ncol = tw;
 
1238
 
 
1239
      col_offset = (((col * bps * spp) + 7) / 8);
 
1240
      bufp = buf + (row * src_rowsize) + col_offset;
 
1241
      if (extractContigSamplesToTileBuffer(tilebuf, bufp, nrow, ncol, imagewidth,
 
1242
                                           tw, 0, spp, spp, bps, dump) > 0)
 
1243
        {
 
1244
        TIFFError("writeBufferToContigTiles", 
 
1245
                  "Unable to extract data to tile for row %lu, col %lu",
 
1246
                  (unsigned long) row, (unsigned long)col);
 
1247
        _TIFFfree(tilebuf);
 
1248
        return 1;
 
1249
        }
 
1250
 
 
1251
      if (TIFFWriteTile(out, tilebuf, col, row, 0, 0) < 0)
 
1252
        {
 
1253
        TIFFError("writeBufferToContigTiles",
 
1254
                  "Cannot write tile at %lu %lu",
 
1255
                  (unsigned long) col, (unsigned long) row);
 
1256
         _TIFFfree(tilebuf);
 
1257
        return 1;
 
1258
        }
 
1259
      }
 
1260
    }
 
1261
  _TIFFfree(tilebuf);
 
1262
 
 
1263
  return 0;
 
1264
  } /* end writeBufferToContigTiles */
 
1265
 
 
1266
/* Extract each plane from contiguous buffer into a single tile buffer 
 
1267
 * to be written out as a tile.
 
1268
 */
 
1269
static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength,
 
1270
                                       uint32 imagewidth, tsample_t spp, 
 
1271
                                       struct dump_opts * dump)
 
1272
  {
 
1273
  tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
 
1274
  uint32 tl, tw;
 
1275
  uint32 row, col, nrow, ncol;
 
1276
  uint32 src_rowsize, col_offset;
 
1277
  uint16 bps;
 
1278
  tsample_t s;
 
1279
  uint8* bufp = (uint8*) buf;
 
1280
 
 
1281
  if (obuf == NULL)
 
1282
    return 1;
 
1283
 
 
1284
  TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
 
1285
  TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
 
1286
  TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
 
1287
  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
 
1288
         
 
1289
  for (row = 0; row < imagelength; row += tl)
 
1290
    {
 
1291
    nrow = (row + tl > imagelength) ? imagelength - row : tl;
 
1292
    for (col = 0; col < imagewidth; col += tw)
 
1293
      {
 
1294
      /* Calculate visible portion of tile. */
 
1295
      if (col + tw > imagewidth)
 
1296
        ncol = imagewidth - col;
 
1297
      else
 
1298
        ncol = tw;
 
1299
 
 
1300
      col_offset = (((col * bps * spp) + 7) / 8);
 
1301
      bufp = buf + (row * src_rowsize) + col_offset;
 
1302
 
 
1303
      for (s = 0; s < spp; s++)
 
1304
        {
 
1305
        if (extractContigSamplesToTileBuffer(obuf, bufp, nrow, ncol, imagewidth,
 
1306
                                             tw, s, 1, spp, bps, dump) > 0)
 
1307
          {
 
1308
          TIFFError("writeBufferToSeparateTiles", 
 
1309
                    "Unable to extract data to tile for row %lu, col %lu sample %d",
 
1310
                    (unsigned long) row, (unsigned long)col, (int)s);
 
1311
          _TIFFfree(obuf);
 
1312
          return 1;
 
1313
          }
 
1314
 
 
1315
        if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0)
 
1316
          {
 
1317
           TIFFError("writeBufferToseparateTiles",
 
1318
                     "Cannot write tile at %lu %lu sample %lu",
 
1319
                     (unsigned long) col, (unsigned long) row,
 
1320
                     (unsigned long) s);
 
1321
           _TIFFfree(obuf);
 
1322
           return 1;
 
1323
          }
 
1324
        }
 
1325
      }
 
1326
    }
 
1327
  _TIFFfree(obuf);
 
1328
 
 
1329
  return 0;
 
1330
  } /* end writeBufferToSeparateTiles */
 
1331
 
 
1332
static void
 
1333
processG3Options(char* cp)
 
1334
{
 
1335
        if( (cp = strchr(cp, ':')) ) {
 
1336
                if (defg3opts == (uint32) -1)
 
1337
                        defg3opts = 0;
 
1338
                do {
 
1339
                        cp++;
 
1340
                        if (strneq(cp, "1d", 2))
 
1341
                                defg3opts &= ~GROUP3OPT_2DENCODING;
 
1342
                        else if (strneq(cp, "2d", 2))
 
1343
                                defg3opts |= GROUP3OPT_2DENCODING;
 
1344
                        else if (strneq(cp, "fill", 4))
 
1345
                                defg3opts |= GROUP3OPT_FILLBITS;
 
1346
                        else
 
1347
                                usage();
 
1348
                } while( (cp = strchr(cp, ':')) );
 
1349
        }
 
1350
}
 
1351
 
 
1352
static int
 
1353
processCompressOptions(char* opt)
 
1354
  {
 
1355
  char* cp = NULL;
 
1356
 
 
1357
  if (strneq(opt, "none",4))
 
1358
    {
 
1359
    defcompression = COMPRESSION_NONE;
 
1360
    }
 
1361
  else if (streq(opt, "packbits"))
 
1362
    {
 
1363
    defcompression = COMPRESSION_PACKBITS;
 
1364
    }
 
1365
  else if (strneq(opt, "jpeg", 4))
 
1366
    {
 
1367
    cp = strchr(opt, ':');
 
1368
    defcompression = COMPRESSION_JPEG;
 
1369
 
 
1370
    while (cp)
 
1371
      {
 
1372
      if (isdigit((int)cp[1]))
 
1373
        quality = atoi(cp + 1);
 
1374
      else if (strneq(cp + 1, "raw", 3 ))
 
1375
        jpegcolormode = JPEGCOLORMODE_RAW;
 
1376
      else if (strneq(cp + 1, "rgb", 3 ))
 
1377
        jpegcolormode = JPEGCOLORMODE_RGB;
 
1378
      else
 
1379
        usage();
 
1380
      cp = strchr(cp + 1, ':');
 
1381
      }
 
1382
    }
 
1383
  else if (strneq(opt, "g3", 2))
 
1384
    {
 
1385
    processG3Options(opt);
 
1386
    defcompression = COMPRESSION_CCITTFAX3;
 
1387
    }
 
1388
  else if (streq(opt, "g4"))
 
1389
    {
 
1390
    defcompression = COMPRESSION_CCITTFAX4;
 
1391
    }
 
1392
  else if (strneq(opt, "lzw", 3))
 
1393
    {
 
1394
    cp = strchr(opt, ':');
 
1395
    if (cp)
 
1396
      defpredictor = atoi(cp+1);
 
1397
    defcompression = COMPRESSION_LZW;
 
1398
    }
 
1399
  else if (strneq(opt, "zip", 3))
 
1400
    {
 
1401
    cp = strchr(opt, ':');
 
1402
    if (cp)
 
1403
      defpredictor = atoi(cp+1);
 
1404
    defcompression = COMPRESSION_ADOBE_DEFLATE;
 
1405
   }
 
1406
  else
 
1407
    return (0);
 
1408
 
 
1409
  return (1);
 
1410
  }
 
1411
 
 
1412
static void
 
1413
usage(void)
 
1414
  {
 
1415
  int i;
 
1416
 
 
1417
  fprintf(stderr, "\n%s\n", TIFFGetVersion());
 
1418
  for (i = 0; usage_info[i] != NULL; i++)
 
1419
    fprintf(stderr, "%s\n", usage_info[i]);
 
1420
  exit(-1);
 
1421
  }
 
1422
 
 
1423
#define CopyField(tag, v) \
 
1424
    if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
 
1425
#define CopyField2(tag, v1, v2) \
 
1426
    if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
 
1427
#define CopyField3(tag, v1, v2, v3) \
 
1428
    if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
 
1429
#define CopyField4(tag, v1, v2, v3, v4) \
 
1430
    if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
 
1431
 
 
1432
static void
 
1433
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
 
1434
{
 
1435
        switch (type) {
 
1436
        case TIFF_SHORT:
 
1437
                if (count == 1) {
 
1438
                        uint16 shortv;
 
1439
                        CopyField(tag, shortv);
 
1440
                } else if (count == 2) {
 
1441
                        uint16 shortv1, shortv2;
 
1442
                        CopyField2(tag, shortv1, shortv2);
 
1443
                } else if (count == 4) {
 
1444
                        uint16 *tr, *tg, *tb, *ta;
 
1445
                        CopyField4(tag, tr, tg, tb, ta);
 
1446
                } else if (count == (uint16) -1) {
 
1447
                        uint16 shortv1;
 
1448
                        uint16* shortav;
 
1449
                        CopyField2(tag, shortv1, shortav);
 
1450
                }
 
1451
                break;
 
1452
        case TIFF_LONG:
 
1453
                { uint32 longv;
 
1454
                  CopyField(tag, longv);
 
1455
                }
 
1456
                break;
 
1457
        case TIFF_RATIONAL:
 
1458
                if (count == 1) {
 
1459
                        float floatv;
 
1460
                        CopyField(tag, floatv);
 
1461
                } else if (count == (uint16) -1) {
 
1462
                        float* floatav;
 
1463
                        CopyField(tag, floatav);
 
1464
                }
 
1465
                break;
 
1466
        case TIFF_ASCII:
 
1467
                { char* stringv;
 
1468
                  CopyField(tag, stringv);
 
1469
                }
 
1470
                break;
 
1471
        case TIFF_DOUBLE:
 
1472
                if (count == 1) {
 
1473
                        double doublev;
 
1474
                        CopyField(tag, doublev);
 
1475
                } else if (count == (uint16) -1) {
 
1476
                        double* doubleav;
 
1477
                        CopyField(tag, doubleav);
 
1478
                }
 
1479
                break;
 
1480
          default:
 
1481
                TIFFError(TIFFFileName(in),
 
1482
                          "Data type %d is not supported, tag %d skipped",
 
1483
                          tag, type);
 
1484
        }
 
1485
}
 
1486
 
 
1487
static struct cpTag {
 
1488
        uint16  tag;
 
1489
        uint16  count;
 
1490
        TIFFDataType type;
 
1491
} tags[] = {
 
1492
        { TIFFTAG_SUBFILETYPE,          1, TIFF_LONG },
 
1493
        { TIFFTAG_THRESHHOLDING,        1, TIFF_SHORT },
 
1494
        { TIFFTAG_DOCUMENTNAME,         1, TIFF_ASCII },
 
1495
        { TIFFTAG_IMAGEDESCRIPTION,     1, TIFF_ASCII },
 
1496
        { TIFFTAG_MAKE,                 1, TIFF_ASCII },
 
1497
        { TIFFTAG_MODEL,                1, TIFF_ASCII },
 
1498
        { TIFFTAG_MINSAMPLEVALUE,       1, TIFF_SHORT },
 
1499
        { TIFFTAG_MAXSAMPLEVALUE,       1, TIFF_SHORT },
 
1500
        { TIFFTAG_XRESOLUTION,          1, TIFF_RATIONAL },
 
1501
        { TIFFTAG_YRESOLUTION,          1, TIFF_RATIONAL },
 
1502
        { TIFFTAG_PAGENAME,             1, TIFF_ASCII },
 
1503
        { TIFFTAG_XPOSITION,            1, TIFF_RATIONAL },
 
1504
        { TIFFTAG_YPOSITION,            1, TIFF_RATIONAL },
 
1505
        { TIFFTAG_RESOLUTIONUNIT,       1, TIFF_SHORT },
 
1506
        { TIFFTAG_SOFTWARE,             1, TIFF_ASCII },
 
1507
        { TIFFTAG_DATETIME,             1, TIFF_ASCII },
 
1508
        { TIFFTAG_ARTIST,               1, TIFF_ASCII },
 
1509
        { TIFFTAG_HOSTCOMPUTER,         1, TIFF_ASCII },
 
1510
        { TIFFTAG_WHITEPOINT,           (uint16) -1, TIFF_RATIONAL },
 
1511
        { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
 
1512
        { TIFFTAG_HALFTONEHINTS,        2, TIFF_SHORT },
 
1513
        { TIFFTAG_INKSET,               1, TIFF_SHORT },
 
1514
        { TIFFTAG_DOTRANGE,             2, TIFF_SHORT },
 
1515
        { TIFFTAG_TARGETPRINTER,        1, TIFF_ASCII },
 
1516
        { TIFFTAG_SAMPLEFORMAT,         1, TIFF_SHORT },
 
1517
        { TIFFTAG_YCBCRCOEFFICIENTS,    (uint16) -1,TIFF_RATIONAL },
 
1518
        { TIFFTAG_YCBCRSUBSAMPLING,     2, TIFF_SHORT },
 
1519
        { TIFFTAG_YCBCRPOSITIONING,     1, TIFF_SHORT },
 
1520
        { TIFFTAG_REFERENCEBLACKWHITE,  (uint16) -1,TIFF_RATIONAL },
 
1521
        { TIFFTAG_EXTRASAMPLES,         (uint16) -1, TIFF_SHORT },
 
1522
        { TIFFTAG_SMINSAMPLEVALUE,      1, TIFF_DOUBLE },
 
1523
        { TIFFTAG_SMAXSAMPLEVALUE,      1, TIFF_DOUBLE },
 
1524
        { TIFFTAG_STONITS,              1, TIFF_DOUBLE },
 
1525
};
 
1526
#define NTAGS   (sizeof (tags) / sizeof (tags[0]))
 
1527
 
 
1528
#define CopyTag(tag, count, type)       cpTag(in, out, tag, count, type)
 
1529
 
 
1530
/* Functions written by Richard Nolde, with exceptions noted. */
 
1531
void  process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
 
1532
                            uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
 
1533
                            uint32 *deftilelength, uint32 *defrowsperstrip,
 
1534
                            struct crop_mask *crop_data, struct pagedef *page, 
 
1535
                            struct dump_opts *dump,
 
1536
                            unsigned int     *imagelist, unsigned int   *image_count )
 
1537
    {
 
1538
    int   c, good_args = 0;
 
1539
    char *opt_offset   = NULL;    /* Position in string of value sought */
 
1540
    char *opt_ptr      = NULL;    /* Pointer to next token in option set */
 
1541
    char *sep          = NULL;    /* Pointer to a token separator */
 
1542
    unsigned int  i, j, start, end;
 
1543
    extern int   optind;
 
1544
    extern char* optarg;
 
1545
 
 
1546
    *mp++ = 'w';
 
1547
    *mp = '\0';
 
1548
    while ((c = getopt(argc, argv,
 
1549
       "ac:d:e:f:hil:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1)
 
1550
      {
 
1551
    good_args++;
 
1552
    switch (c) {
 
1553
      case 'a': mode[0] = 'a';  /* append to output */
 
1554
                break;
 
1555
      case 'c': if (!processCompressOptions(optarg)) /* compression scheme */
 
1556
                  {
 
1557
                  TIFFError ("Unknown compression option", "%s", optarg);
 
1558
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1559
                  exit (-1);
 
1560
                  }
 
1561
                break;
 
1562
      case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */
 
1563
                if (start == 0)
 
1564
                  {
 
1565
                  TIFFError ("","Directory offset must be greater than zero");
 
1566
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1567
                  exit (-1);
 
1568
                  }
 
1569
                *dirnum = start - 1;
 
1570
                break;
 
1571
      case 'e': switch (tolower(optarg[0])) /* image export modes*/
 
1572
                  {
 
1573
                  case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
 
1574
                            crop_data->img_mode = COMPOSITE_IMAGES;
 
1575
                            break; /* Composite */
 
1576
                  case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
 
1577
                            crop_data->img_mode = SEPARATED_IMAGES;
 
1578
                            break; /* Divided */
 
1579
                  case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
 
1580
                            crop_data->img_mode = COMPOSITE_IMAGES;
 
1581
                            break; /* Image */
 
1582
                  case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
 
1583
                            crop_data->img_mode = SEPARATED_IMAGES;
 
1584
                            break; /* Multiple */
 
1585
                  case 's': crop_data->exp_mode = FILE_PER_SELECTION;
 
1586
                            crop_data->img_mode = SEPARATED_IMAGES;
 
1587
                            break; /* Sections */
 
1588
                  default:  TIFFError ("Unknown export mode","%s", optarg);
 
1589
                            TIFFError ("For valid options type", "tiffcrop -h");
 
1590
                            exit (-1);
 
1591
                  }
 
1592
                break;
 
1593
      case 'f': if (streq(optarg, "lsb2msb"))      /* fill order */
 
1594
                  *deffillorder = FILLORDER_LSB2MSB;
 
1595
                else if (streq(optarg, "msb2lsb"))
 
1596
                  *deffillorder = FILLORDER_MSB2LSB;
 
1597
                else
 
1598
                  {
 
1599
                  TIFFError ("Unknown fill order", "%s", optarg);
 
1600
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1601
                  exit (-1);
 
1602
                  }
 
1603
                break;
 
1604
      case 'h': usage();
 
1605
                break;
 
1606
      case 'i': ignore = TRUE;          /* ignore errors */
 
1607
                break;
 
1608
      case 'l': outtiled = TRUE;         /* tile length */
 
1609
                *deftilelength = atoi(optarg);
 
1610
                break;
 
1611
      case 'p': /* planar configuration */
 
1612
                if (streq(optarg, "separate"))
 
1613
                  *defconfig = PLANARCONFIG_SEPARATE;
 
1614
                else if (streq(optarg, "contig"))
 
1615
                  *defconfig = PLANARCONFIG_CONTIG;
 
1616
                else
 
1617
                  {
 
1618
                  TIFFError ("Unkown planar configuration", "%s", optarg);
 
1619
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1620
                  exit (-1);
 
1621
                  }
 
1622
                break;
 
1623
      case 'r': /* rows/strip */
 
1624
                *defrowsperstrip = atol(optarg);
 
1625
                break;
 
1626
      case 's': /* generate stripped output */
 
1627
                outtiled = FALSE;
 
1628
                break;
 
1629
      case 't': /* generate tiled output */
 
1630
                outtiled = TRUE;
 
1631
                break;
 
1632
      case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
 
1633
                TIFFError ("Tiffcrop version", "%s, last updated: %s", 
 
1634
                           tiffcrop_version_id, tiffcrop_rev_date);
 
1635
                TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
 
1636
                TIFFError ("           ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
 
1637
                TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
 
1638
                exit (0);
 
1639
                break;
 
1640
      case 'w': /* tile width */
 
1641
                outtiled = TRUE;
 
1642
                *deftilewidth = atoi(optarg);
 
1643
                break;
 
1644
      case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
 
1645
                crop_data->crop_mode |= CROP_REGIONS;
 
1646
                for (i = 0, opt_ptr = strtok (optarg, ":");
 
1647
                   ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
 
1648
                    (opt_ptr = strtok (NULL, ":")), i++)
 
1649
                    {
 
1650
                    crop_data->regions++;
 
1651
                    if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
 
1652
                               &crop_data->corners[i].X1, &crop_data->corners[i].Y1,
 
1653
                               &crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
 
1654
                      {
 
1655
                      TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
 
1656
                      TIFFError ("For valid options type", "tiffcrop -h");
 
1657
                      exit (-1);
 
1658
                      }
 
1659
                    }
 
1660
                /*  check for remaining elements over MAX_REGIONS */
 
1661
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
 
1662
                  {
 
1663
                  TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
 
1664
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1665
                  exit (-1);;
 
1666
                  }
 
1667
                break;
 
1668
      /* options for file open modes */
 
1669
      case 'B': *mp++ = 'b'; *mp = '\0';
 
1670
                break;
 
1671
      case 'L': *mp++ = 'l'; *mp = '\0';
 
1672
                break;
 
1673
      case 'M': *mp++ = 'm'; *mp = '\0';
 
1674
                break;
 
1675
      case 'C': *mp++ = 'c'; *mp = '\0';
 
1676
                break;
 
1677
      /* options for Debugging / data dump */
 
1678
      case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
 
1679
                    (opt_ptr != NULL);
 
1680
                    (opt_ptr = strtok (NULL, ",")), i++)
 
1681
                    {
 
1682
                    opt_offset = strpbrk(opt_ptr, ":=");
 
1683
                    if (opt_offset == NULL)
 
1684
                      {
 
1685
                      TIFFError("Invalid dump option", "%s", optarg);
 
1686
                      TIFFError ("For valid options type", "tiffcrop -h");
 
1687
                      exit (-1);
 
1688
                      }
 
1689
                      
 
1690
                    *opt_offset = '\0';
 
1691
                    /* convert option to lowercase */
 
1692
                    end = strlen (opt_ptr);
 
1693
                    for (i = 0; i < end; i++)
 
1694
                      *(opt_ptr + i) = tolower(*(opt_ptr + i));
 
1695
                    /* Look for dump format specification */
 
1696
                    if (strncmp(opt_ptr, "for", 3) == 0)
 
1697
                      {
 
1698
                      /* convert value to lowercase */
 
1699
                      end = strlen (opt_offset + 1);
 
1700
                      for (i = 1; i <= end; i++)
 
1701
                        *(opt_offset + i) = tolower(*(opt_offset + i));
 
1702
                      /* check dump format value */
 
1703
                      if (strncmp (opt_offset + 1, "txt", 3) == 0)
 
1704
                        {
 
1705
                        dump->format = DUMP_TEXT;
 
1706
                        strcpy (dump->mode, "w");
 
1707
                        }
 
1708
                      else
 
1709
                        {
 
1710
                        if (strncmp(opt_offset + 1, "raw", 3) == 0)
 
1711
                          {
 
1712
                          dump->format = DUMP_RAW;
 
1713
                          strcpy (dump->mode, "wb");
 
1714
                          }
 
1715
                        else
 
1716
                          {
 
1717
                          TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
 
1718
                          TIFFError ("For valid options type", "tiffcrop -h");
 
1719
                          exit (-1);
 
1720
                          }
 
1721
                        }
 
1722
                      }
 
1723
                    else
 
1724
                      { /* Look for dump level specification */
 
1725
                      if (strncmp (opt_ptr, "lev", 3) == 0)
 
1726
                        dump->level = atoi(opt_offset + 1);
 
1727
                        /* Look for input data dump file name */
 
1728
                      if (strncmp (opt_ptr, "in", 2) == 0)
 
1729
                        {
 
1730
                        strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
 
1731
                        dump->infilename[PATH_MAX - 20] = '\0';
 
1732
                        }
 
1733
                        /* Look for output data dump file name */
 
1734
                      if (strncmp (opt_ptr, "out", 3) == 0)
 
1735
                        {
 
1736
                        strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
 
1737
                        dump->outfilename[PATH_MAX - 20] = '\0';
 
1738
                        }
 
1739
                      if (strncmp (opt_ptr, "deb", 3) == 0)
 
1740
                        dump->debug = atoi(opt_offset + 1);
 
1741
                      }
 
1742
                    }
 
1743
                if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
 
1744
                  {
 
1745
                  if (dump->level == 1)
 
1746
                    TIFFError("","Defaulting to dump level 1, no data.");
 
1747
                  if (dump->format == DUMP_NONE)
 
1748
                    {
 
1749
                    TIFFError("", "You must specify a dump format for dump files");
 
1750
                    TIFFError ("For valid options type", "tiffcrop -h");
 
1751
                    exit (-1);
 
1752
                    }
 
1753
                  }
 
1754
                break;
 
1755
 
 
1756
      /* image manipulation routine options */
 
1757
      case 'm': /* margins to exclude from selection, uppercase M was already used */
 
1758
                /* order of values must be TOP, LEFT, BOTTOM, RIGHT */
 
1759
                crop_data->crop_mode |= CROP_MARGINS;
 
1760
                for (i = 0, opt_ptr = strtok (optarg, ",:");
 
1761
                    ((opt_ptr != NULL) &&  (i < 4));
 
1762
                     (opt_ptr = strtok (NULL, ",:")), i++)
 
1763
                    {
 
1764
                    crop_data->margins[i] = atof(opt_ptr);
 
1765
                    }
 
1766
                break;
 
1767
      case 'E': /* edge reference */
 
1768
                switch (tolower(optarg[0]))
 
1769
                  {
 
1770
                  case 't': crop_data->edge_ref = EDGE_TOP;
 
1771
                            break;
 
1772
                  case 'b': crop_data->edge_ref = EDGE_BOTTOM;
 
1773
                             break;
 
1774
                  case 'l': crop_data->edge_ref = EDGE_LEFT;
 
1775
                            break;
 
1776
                  case 'r': crop_data->edge_ref = EDGE_RIGHT;
 
1777
                            break;
 
1778
                  default:  TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
 
1779
                            TIFFError ("For valid options type", "tiffcrop -h");
 
1780
                            exit (-1);
 
1781
                  }
 
1782
                break;
 
1783
      case 'F': /* flip eg mirror image or cropped segment, M was already used */
 
1784
                crop_data->crop_mode |= CROP_MIRROR;
 
1785
                switch (tolower(optarg[0]))
 
1786
                  {
 
1787
                  case  'h': crop_data->mirror = MIRROR_HORIZ;
 
1788
                             break;
 
1789
                  case  'v': crop_data->mirror = MIRROR_VERT;
 
1790
                             break;
 
1791
                  case  'b': crop_data->mirror = MIRROR_BOTH;
 
1792
                             break;
 
1793
                  default:   TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
 
1794
                             TIFFError ("For valid options type", "tiffcrop -h");
 
1795
                             exit (-1);
 
1796
                  }
 
1797
                break;
 
1798
      case 'H': /* set horizontal resolution to new value */
 
1799
                page->hres = atof (optarg);
 
1800
                page->mode |= PAGE_MODE_RESOLUTION;
 
1801
                break;
 
1802
      case 'I': /* invert the color space, eg black to white */
 
1803
                crop_data->crop_mode |= CROP_INVERT;
 
1804
                /* The PHOTOMETIC_INTERPRETATION tag may be updated */
 
1805
                if (streq(optarg, "black"))
 
1806
                  {
 
1807
                  crop_data->photometric = PHOTOMETRIC_MINISBLACK;
 
1808
                  continue;
 
1809
                  }
 
1810
                if (streq(optarg, "white"))
 
1811
                  {
 
1812
                  crop_data->photometric = PHOTOMETRIC_MINISWHITE;
 
1813
                  continue;
 
1814
                  }
 
1815
                if (streq(optarg, "data")) 
 
1816
                  {
 
1817
                  crop_data->photometric = INVERT_DATA_ONLY;
 
1818
                  continue;
 
1819
                  }
 
1820
                if (streq(optarg, "both"))
 
1821
                  {
 
1822
                  crop_data->photometric = INVERT_DATA_AND_TAG;
 
1823
                  continue;
 
1824
                  }
 
1825
 
 
1826
                TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
 
1827
                TIFFError ("For valid options type", "tiffcrop -h");
 
1828
                exit (-1);
 
1829
                break;
 
1830
      case 'J': /* horizontal margin for sectioned ouput pages */ 
 
1831
                page->hmargin = atof(optarg);
 
1832
                page->mode |= PAGE_MODE_MARGINS;
 
1833
                break;
 
1834
      case 'K': /* vertical margin for sectioned ouput pages*/ 
 
1835
                page->vmargin = atof(optarg);
 
1836
                page->mode |= PAGE_MODE_MARGINS;
 
1837
                break;
 
1838
      case 'N': /* list of images to process */
 
1839
                for (i = 0, opt_ptr = strtok (optarg, ",");
 
1840
                    ((opt_ptr != NULL) &&  (i < MAX_IMAGES));
 
1841
                     (opt_ptr = strtok (NULL, ",")))
 
1842
                     { /* We do not know how many images are in file yet 
 
1843
                        * so we build a list to include the maximum allowed
 
1844
                        * and follow it until we hit the end of the file.
 
1845
                        * Image count is not accurate for odd, even, last
 
1846
                        * so page numbers won't be valid either.
 
1847
                        */
 
1848
                     if (streq(opt_ptr, "odd"))
 
1849
                       {
 
1850
                       for (j = 1; j <= MAX_IMAGES; j += 2)
 
1851
                         imagelist[i++] = j;
 
1852
                       *image_count = (MAX_IMAGES - 1) / 2;
 
1853
                       break;
 
1854
                       }
 
1855
                     else
 
1856
                       {
 
1857
                       if (streq(opt_ptr, "even"))
 
1858
                         {
 
1859
                         for (j = 2; j <= MAX_IMAGES; j += 2)
 
1860
                           imagelist[i++] = j;
 
1861
                         *image_count = MAX_IMAGES / 2;
 
1862
                         break;
 
1863
                         }
 
1864
                       else
 
1865
                         {
 
1866
                         if (streq(opt_ptr, "last"))
 
1867
                           imagelist[i++] = MAX_IMAGES;
 
1868
                         else  /* single value between commas */
 
1869
                           {
 
1870
                           sep = strpbrk(opt_ptr, ":-");
 
1871
                           if (!sep)
 
1872
                             imagelist[i++] = atoi(opt_ptr);
 
1873
                           else
 
1874
                             {
 
1875
                             *sep = '\0';
 
1876
                             start = atoi (opt_ptr);
 
1877
                             if (!strcmp((sep + 1), "last"))
 
1878
                               end = MAX_IMAGES;
 
1879
                             else
 
1880
                               end = atoi (sep + 1);
 
1881
                             for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
 
1882
                               imagelist[i++] = j;
 
1883
                             }
 
1884
                           }
 
1885
                         }
 
1886
                      }
 
1887
                    }
 
1888
                *image_count = i;
 
1889
                break;
 
1890
      case 'O': /* page orientation */ 
 
1891
                switch (tolower(optarg[0]))
 
1892
                  {
 
1893
                  case  'a': page->orient = ORIENTATION_AUTO;
 
1894
                             break;
 
1895
                  case  'p': page->orient = ORIENTATION_PORTRAIT;
 
1896
                             break;
 
1897
                  case  'l': page->orient = ORIENTATION_LANDSCAPE;
 
1898
                             break;
 
1899
                  default:  TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
 
1900
                            TIFFError ("For valid options type", "tiffcrop -h");
 
1901
                            exit (-1);
 
1902
                  }
 
1903
                break;
 
1904
      case 'P': /* page size selection */ 
 
1905
                if (sscanf(optarg, "%lfx%lf", &page->width, &page->length) == 2)
 
1906
                  {
 
1907
                  strcpy (page->name, "Custom"); 
 
1908
                  page->mode |= PAGE_MODE_PAPERSIZE;
 
1909
                  break;
 
1910
                  }
 
1911
                if (get_page_geometry (optarg, page))
 
1912
                  {
 
1913
                  if (!strcmp(optarg, "list"))
 
1914
                    {
 
1915
                    TIFFError("", "Name            Width   Length (in inches)");
 
1916
                    for (i = 0; i < MAX_PAPERNAMES - 1; i++)
 
1917
                      TIFFError ("", "%-15.15s %5.2f   %5.2f", 
 
1918
                               PaperTable[i].name, PaperTable[i].width, 
 
1919
                               PaperTable[i].length);
 
1920
                    exit (-1);                   
 
1921
                    }
 
1922
     
 
1923
                  TIFFError ("Invalid paper size", "%s", optarg);
 
1924
                  TIFFError ("", "Select one of:");
 
1925
                  TIFFError("", "Name            Width   Length (in inches)");
 
1926
                  for (i = 0; i < MAX_PAPERNAMES - 1; i++)
 
1927
                    TIFFError ("", "%-15.15s %5.2f   %5.2f", 
 
1928
                               PaperTable[i].name, PaperTable[i].width, 
 
1929
                               PaperTable[i].length);
 
1930
                  exit (-1);
 
1931
                  }
 
1932
                else
 
1933
                  {
 
1934
                  page->mode |= PAGE_MODE_PAPERSIZE;
 
1935
                  }
 
1936
                break;
 
1937
      case 'R': /* rotate image or cropped segment */
 
1938
                crop_data->crop_mode |= CROP_ROTATE;
 
1939
                switch (strtoul(optarg, NULL, 0))
 
1940
                  {
 
1941
                  case  90:  crop_data->rotation = (uint16)90;
 
1942
                             break;
 
1943
                  case  180: crop_data->rotation = (uint16)180;
 
1944
                             break;
 
1945
                  case  270: crop_data->rotation = (uint16)270;
 
1946
                             break;
 
1947
                  default:   TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
 
1948
                             TIFFError ("For valid options type", "tiffcrop -h");
 
1949
                             exit (-1);
 
1950
                  }
 
1951
                break;
 
1952
      case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
 
1953
                sep = strpbrk(optarg, ",:");
 
1954
                if (sep)
 
1955
                  {
 
1956
                  *sep = '\0';
 
1957
                  page->cols = atoi(optarg);
 
1958
                  page->rows = atoi(sep +1);
 
1959
                  }
 
1960
                else
 
1961
                  {
 
1962
                  page->cols = atoi(optarg);
 
1963
                  page->rows = atoi(optarg);
 
1964
                  }
 
1965
                if ((page->cols * page->rows) > MAX_SECTIONS)
 
1966
                  {
 
1967
                  TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
 
1968
                  exit (-1);
 
1969
                  }
 
1970
                page->mode |= PAGE_MODE_ROWSCOLS;
 
1971
                break;
 
1972
      case 'U': /* units for measurements and offsets */
 
1973
                if (streq(optarg, "in"))
 
1974
                  {
 
1975
                  crop_data->res_unit = RESUNIT_INCH;
 
1976
                  page->res_unit = RESUNIT_INCH;
 
1977
                  }
 
1978
                else if (streq(optarg, "cm"))
 
1979
                  {
 
1980
                  crop_data->res_unit = RESUNIT_CENTIMETER;
 
1981
                  page->res_unit = RESUNIT_CENTIMETER;
 
1982
                  }
 
1983
                else if (streq(optarg, "px"))
 
1984
                  {
 
1985
                  crop_data->res_unit = RESUNIT_NONE;
 
1986
                  page->res_unit = RESUNIT_NONE;
 
1987
                  }
 
1988
                else
 
1989
                  {
 
1990
                  TIFFError ("Illegal unit of measure","%s", optarg);
 
1991
                  TIFFError ("For valid options type", "tiffcrop -h");
 
1992
                  exit (-1);
 
1993
                  }
 
1994
                break;
 
1995
      case 'V': /* set vertical resolution to new value */
 
1996
                page->vres = atof (optarg);
 
1997
                page->mode |= PAGE_MODE_RESOLUTION;
 
1998
                break;
 
1999
      case 'X': /* selection width */
 
2000
                crop_data->crop_mode |= CROP_WIDTH;
 
2001
                crop_data->width = atof(optarg);
 
2002
                break;
 
2003
      case 'Y': /* selection length */
 
2004
                crop_data->crop_mode |= CROP_LENGTH;
 
2005
                crop_data->length = atof(optarg);
 
2006
                break;
 
2007
      case 'Z': /* zones of an image X:Y read as zone X of Y */
 
2008
                crop_data->crop_mode |= CROP_ZONES;
 
2009
                for (i = 0, opt_ptr = strtok (optarg, ",");
 
2010
                   ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
 
2011
                    (opt_ptr = strtok (NULL, ",")), i++)
 
2012
                    {
 
2013
                    crop_data->zones++;
 
2014
                    opt_offset = strchr(opt_ptr, ':');
 
2015
                    *opt_offset = '\0';
 
2016
                    crop_data->zonelist[i].position = atoi(opt_ptr);
 
2017
                    crop_data->zonelist[i].total    = atoi(opt_offset + 1);
 
2018
                    }
 
2019
                /*  check for remaining elements over MAX_REGIONS */
 
2020
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
 
2021
                  {
 
2022
                  TIFFError("Zone list exceeds region limit", "%d",  MAX_REGIONS);
 
2023
                  exit (-1);
 
2024
                  }
 
2025
                break;
 
2026
    case '?':   TIFFError ("For valid options type", "tiffcrop -h");
 
2027
                exit (-1);
 
2028
                /*NOTREACHED*/
 
2029
      }
 
2030
    }
 
2031
  }  /* end process_command_opts */
 
2032
 
 
2033
/* Start a new output file if one has not been previously opened or
 
2034
 * autoindex is set to non-zero. Update page and file counters
 
2035
 * so TIFFTAG PAGENUM will be correct in image.
 
2036
 */
 
2037
static int 
 
2038
update_output_file (TIFF **tiffout, char *mode, int autoindex,
 
2039
                    char *outname, unsigned int *page)
 
2040
  {
 
2041
  static int findex = 0;    /* file sequence indicator */
 
2042
  char  *sep;
 
2043
  char   filenum[16];
 
2044
  char   export_ext[16];
 
2045
  char   exportname[PATH_MAX];
 
2046
 
 
2047
  if (autoindex && (*tiffout != NULL))
 
2048
    {   
 
2049
    /* Close any export file that was previously opened */
 
2050
    TIFFClose (*tiffout);
 
2051
    *tiffout = NULL;
 
2052
    }
 
2053
 
 
2054
  strcpy (export_ext, ".tiff");
 
2055
  memset (exportname, '\0', PATH_MAX);
 
2056
 
 
2057
  /* Leave room for page number portion of the new filename */
 
2058
  strncpy (exportname, outname, PATH_MAX - 16);
 
2059
  if (*tiffout == NULL)   /* This is a new export file */
 
2060
    {
 
2061
    if (autoindex)
 
2062
      { /* create a new filename for each export */
 
2063
      findex++;
 
2064
      if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
 
2065
        {
 
2066
        strncpy (export_ext, sep, 5);
 
2067
        *sep = '\0';
 
2068
        }
 
2069
      else
 
2070
        strncpy (export_ext, ".tiff", 5);
 
2071
      export_ext[5] = '\0';
 
2072
 
 
2073
      /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
 
2074
      if (findex > MAX_EXPORT_PAGES)
 
2075
        {
 
2076
        TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES);
 
2077
        return 1;
 
2078
        }
 
2079
 
 
2080
      snprintf(filenum, sizeof(filenum), "-%03d%s", findex, export_ext);
 
2081
      filenum[14] = '\0';
 
2082
      strncat (exportname, filenum, 15);
 
2083
      }
 
2084
    exportname[PATH_MAX - 1] = '\0';
 
2085
 
 
2086
    *tiffout = TIFFOpen(exportname, mode);
 
2087
    if (*tiffout == NULL)
 
2088
      {
 
2089
      TIFFError("update_output_file", "Unable to open output file %s", exportname);
 
2090
      return 1;
 
2091
      }
 
2092
    *page = 0; 
 
2093
 
 
2094
    return 0;
 
2095
    }
 
2096
  else 
 
2097
    (*page)++;
 
2098
 
 
2099
  return 0;
 
2100
  } /* end update_output_file */
 
2101
 
 
2102
 
 
2103
int
 
2104
main(int argc, char* argv[])
 
2105
  {
 
2106
  extern int optind;
 
2107
  uint16 defconfig = (uint16) -1;
 
2108
  uint16 deffillorder = 0;
 
2109
  uint32 deftilewidth = (uint32) 0;
 
2110
  uint32 deftilelength = (uint32) 0;
 
2111
  uint32 defrowsperstrip = (uint32) 0;
 
2112
  uint32 dirnum = 0;
 
2113
 
 
2114
  TIFF *in = NULL;
 
2115
  TIFF *out = NULL;
 
2116
  char  mode[10];
 
2117
  char *mp = mode;
 
2118
 
 
2119
  /** RJN additions **/
 
2120
  struct image_data image;     /* Image parameters for one image */
 
2121
  struct crop_mask  crop;      /* Cropping parameters for all images */
 
2122
  struct pagedef    page;      /* Page definition for output pages */
 
2123
  struct pageseg    sections[MAX_SECTIONS];  /* Sections of one output page */
 
2124
  struct buffinfo   seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
 
2125
  struct dump_opts  dump;                  /* Data dump options */
 
2126
  unsigned char *read_buff    = NULL;      /* Input image data buffer */
 
2127
  unsigned char *crop_buff    = NULL;      /* Crop area buffer */
 
2128
  unsigned char *sect_buff    = NULL;      /* Image section buffer */
 
2129
  unsigned char *sect_src     = NULL;      /* Image section buffer pointer */
 
2130
  unsigned int  imagelist[MAX_IMAGES + 1]; /* individually specified images */
 
2131
  unsigned int  image_count  = 0;
 
2132
  unsigned int  dump_images  = 0;
 
2133
  unsigned int  next_image   = 0;
 
2134
  unsigned int  next_page    = 0;
 
2135
  unsigned int  total_pages  = 0;
 
2136
  unsigned int  total_images = 0;
 
2137
  unsigned int  end_of_input = FALSE;
 
2138
  int    seg, length;
 
2139
  char   temp_filename[PATH_MAX + 1];
 
2140
 
 
2141
  little_endian = *((unsigned char *)&little_endian) & '1';
 
2142
 
 
2143
  initImageData(&image);
 
2144
  initCropMasks(&crop);
 
2145
  initPageSetup(&page, sections, seg_buffs);
 
2146
  initDumpOptions(&dump);
 
2147
 
 
2148
  process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig, 
 
2149
                        &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
 
2150
                        &crop, &page, &dump, imagelist, &image_count);
 
2151
 
 
2152
  if (argc - optind < 2)
 
2153
    usage();
 
2154
 
 
2155
  if ((argc - optind) == 2)
 
2156
    pageNum = -1;
 
2157
  else
 
2158
    total_images = 0;
 
2159
  /* read multiple input files and write to output file(s) */
 
2160
  while (optind < argc - 1)
 
2161
    {
 
2162
    in = TIFFOpen (argv[optind], "r");
 
2163
    if (in == NULL)
 
2164
      return (-3);
 
2165
 
 
2166
    /* If only one input file is specified, we can use directory count */
 
2167
    total_images = TIFFNumberOfDirectories(in); 
 
2168
    if (image_count == 0)
 
2169
      {
 
2170
      dirnum = 0;
 
2171
      total_pages = total_images; /* Only valid with single input file */
 
2172
      }
 
2173
    else
 
2174
      {
 
2175
      dirnum = (tdir_t)(imagelist[next_image] - 1);
 
2176
      next_image++;
 
2177
 
 
2178
      /* Total pages only valid for enumerated list of pages not derived
 
2179
       * using odd, even, or last keywords.
 
2180
       */
 
2181
      if (image_count >  total_images)
 
2182
        image_count = total_images;
 
2183
      
 
2184
      total_pages = image_count;
 
2185
      }
 
2186
 
 
2187
    /* MAX_IMAGES is used for special case "last" in selection list */
 
2188
    if (dirnum == (MAX_IMAGES - 1))
 
2189
      dirnum = total_images - 1;
 
2190
 
 
2191
    if (dirnum > (total_images))
 
2192
      {
 
2193
      TIFFError (TIFFFileName(in), 
 
2194
      "Invalid image number %d, File contains only %d images", 
 
2195
                 (int)dirnum + 1, total_images);
 
2196
      if (out != NULL)
 
2197
        (void) TIFFClose(out);
 
2198
      return (1);
 
2199
      }
 
2200
 
 
2201
    if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
 
2202
      {
 
2203
      TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
 
2204
      if (out != NULL)
 
2205
        (void) TIFFClose(out);
 
2206
      return (1);
 
2207
      }
 
2208
 
 
2209
    end_of_input = FALSE;
 
2210
    while (end_of_input == FALSE)
 
2211
      {
 
2212
      config = defconfig;
 
2213
      compression = defcompression;
 
2214
      predictor = defpredictor;
 
2215
      fillorder = deffillorder;
 
2216
      rowsperstrip = defrowsperstrip;
 
2217
      tilewidth = deftilewidth;
 
2218
      tilelength = deftilelength;
 
2219
      g3opts = defg3opts;
 
2220
 
 
2221
      if (dump.format != DUMP_NONE)
 
2222
        {
 
2223
        /* manage input and/or output dump files here */
 
2224
        dump_images++;
 
2225
        length = strlen(dump.infilename);
 
2226
        if (length > 0)
 
2227
          {
 
2228
          if (dump.infile != NULL)
 
2229
            fclose (dump.infile);
 
2230
 
 
2231
          /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes 
 
2232
             fewer than PATH_MAX */ 
 
2233
          snprintf(temp_filename, sizeof(temp_filename), "%s-read-%03d.%s",
 
2234
                   dump.infilename, dump_images,
 
2235
                  (dump.format == DUMP_TEXT) ? "txt" : "raw");
 
2236
          if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
 
2237
            {
 
2238
            TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
 
2239
            exit (-1);
 
2240
            }
 
2241
          dump_info(dump.infile, dump.format, "Reading image","%d from %s", 
 
2242
                    dump_images, TIFFFileName(in));
 
2243
          } 
 
2244
        length = strlen(dump.outfilename);
 
2245
        if (length > 0)
 
2246
          {
 
2247
          if (dump.outfile != NULL)
 
2248
            fclose (dump.outfile);
 
2249
 
 
2250
          /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes 
 
2251
             fewer than PATH_MAX */ 
 
2252
          snprintf(temp_filename, sizeof(temp_filename), "%s-write-%03d.%s",
 
2253
                   dump.outfilename, dump_images,
 
2254
                  (dump.format == DUMP_TEXT) ? "txt" : "raw");
 
2255
          if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
 
2256
            {
 
2257
              TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
 
2258
            exit (-1);
 
2259
            }
 
2260
          dump_info(dump.outfile, dump.format, "Writing image","%d from %s", 
 
2261
                    dump_images, TIFFFileName(in));
 
2262
          } 
 
2263
        }
 
2264
 
 
2265
      if (dump.debug)
 
2266
         TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);
 
2267
 
 
2268
      if (loadImage(in, &image, &dump, &read_buff))
 
2269
        {
 
2270
        TIFFError("main", "Unable to load source image");
 
2271
        exit (-1);
 
2272
        }
 
2273
 
 
2274
      /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
 
2275
       */
 
2276
      if (image.adjustments != 0)
 
2277
        {
 
2278
        if (correct_orientation(&image, &read_buff))
 
2279
            TIFFError("main", "Unable to correct image orientation");
 
2280
        }
 
2281
 
 
2282
      if (getCropOffsets(&image, &crop, &dump))
 
2283
        {
 
2284
        TIFFError("main", "Unable to define crop regions");
 
2285
        exit (-1);
 
2286
        }
 
2287
 
 
2288
      if (crop.selections > 0)
 
2289
        {
 
2290
        if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
 
2291
          {
 
2292
          TIFFError("main", "Unable to process image selections");
 
2293
          exit (-1);
 
2294
          }
 
2295
        }
 
2296
      else  /* Single image segment without zones or regions */
 
2297
        {
 
2298
        if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
 
2299
          {
 
2300
          TIFFError("main", "Unable to create output image");
 
2301
          exit (-1);
 
2302
          }
 
2303
        }
 
2304
      if (page.mode == PAGE_MODE_NONE)
 
2305
        {  /* Whole image or sections not based on output page size */
 
2306
        if (crop.selections > 0)
 
2307
          {
 
2308
          writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
 
2309
                          mp, argv[argc - 1], &next_page, total_pages);
 
2310
          }
 
2311
        else  /* One file all images and sections */
 
2312
          {
 
2313
          if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
 
2314
                                  &next_page))
 
2315
             exit (1);
 
2316
          if (writeCroppedImage(in, out, &image, &dump,crop.combined_width, 
 
2317
                                crop.combined_length, crop_buff, next_page, total_pages))
 
2318
            {
 
2319
             TIFFError("main", "Unable to write new image");
 
2320
             exit (-1);
 
2321
            }
 
2322
          }
 
2323
        }
 
2324
      else
 
2325
        {
 
2326
        /* If we used a crop buffer, our data is there, otherwise it is
 
2327
         * in the read_buffer
 
2328
         */
 
2329
        if (crop_buff != NULL)  
 
2330
          sect_src = crop_buff;
 
2331
        else
 
2332
          sect_src = read_buff;
 
2333
        /* Break input image into pages or rows and columns */
 
2334
        if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
 
2335
          {
 
2336
          TIFFError("main", "Unable to compute output section data");
 
2337
          exit (-1);
 
2338
          }
 
2339
        /* If there are multiple files on the command line, the final one is assumed 
 
2340
         * to be the output filename into which the images are written.
 
2341
         */
 
2342
        if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
 
2343
          exit (1);
 
2344
 
 
2345
        if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, &sect_buff))
 
2346
          {
 
2347
          TIFFError("main", "Unable to write image sections");
 
2348
          exit (-1);
 
2349
          }
 
2350
        }
 
2351
 
 
2352
      /* No image list specified, just read the next image */
 
2353
      if (image_count == 0)
 
2354
        dirnum++;
 
2355
      else
 
2356
        {
 
2357
        dirnum = (tdir_t)(imagelist[next_image] - 1);
 
2358
        next_image++;
 
2359
        }
 
2360
 
 
2361
      if (dirnum == MAX_IMAGES - 1)
 
2362
        dirnum = TIFFNumberOfDirectories(in) - 1;
 
2363
 
 
2364
      if (!TIFFSetDirectory(in, (tdir_t)dirnum))
 
2365
        end_of_input = TRUE;
 
2366
      }
 
2367
    TIFFClose(in);
 
2368
    optind++;
 
2369
    }
 
2370
 
 
2371
  /* If we did not use the read buffer as the crop buffer */
 
2372
  if (read_buff)
 
2373
    _TIFFfree(read_buff);
 
2374
 
 
2375
  if (crop_buff)
 
2376
    _TIFFfree(crop_buff);
 
2377
 
 
2378
  if (sect_buff)
 
2379
    _TIFFfree(sect_buff);
 
2380
 
 
2381
   /* Clean up any segment buffers used for zones or regions */
 
2382
  for (seg = 0; seg < crop.selections; seg++)
 
2383
    _TIFFfree (seg_buffs[seg].buffer);
 
2384
 
 
2385
  if (dump.format != DUMP_NONE)
 
2386
    {
 
2387
    if (dump.infile != NULL)
 
2388
     fclose (dump.infile);
 
2389
 
 
2390
    if (dump.outfile != NULL)
 
2391
      {
 
2392
      dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
 
2393
      fclose (dump.outfile);
 
2394
      }
 
2395
    }
 
2396
 
 
2397
  TIFFClose(out);
 
2398
 
 
2399
  return (0);
 
2400
  } /* end main */
 
2401
 
 
2402
 
 
2403
/* Debugging functions */
 
2404
static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
 
2405
  {
 
2406
  int j, k;
 
2407
  uint32 i;
 
2408
  char  dump_array[10];
 
2409
  unsigned char bitset;
 
2410
 
 
2411
  if (dumpfile == NULL)
 
2412
    {
 
2413
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2414
    return (1);
 
2415
    }
 
2416
 
 
2417
  if (format == DUMP_TEXT)
 
2418
    {
 
2419
    fprintf (dumpfile," %s  ", dump_tag);
 
2420
    for (i = 0; i < count; i++)
 
2421
      {
 
2422
      for (j = 0, k = 7; j < 8; j++, k--)
 
2423
        {
 
2424
        bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
 
2425
        sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2426
        }
 
2427
      dump_array[8] = '\0';
 
2428
      fprintf (dumpfile," %s", dump_array);
 
2429
      }
 
2430
    fprintf (dumpfile,"\n");
 
2431
    }
 
2432
  else
 
2433
    {
 
2434
    if ((fwrite (data, 1, count, dumpfile)) != count)
 
2435
      {
 
2436
      TIFFError ("", "Unable to write binary data to dump file");
 
2437
      return (1);
 
2438
      }
 
2439
    }
 
2440
 
 
2441
  return (0);
 
2442
  }
 
2443
 
 
2444
static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
 
2445
  {
 
2446
  int j, k;
 
2447
  char  dump_array[10];
 
2448
  unsigned char bitset;
 
2449
 
 
2450
  if (dumpfile == NULL)
 
2451
    {
 
2452
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2453
    return (1);
 
2454
    }
 
2455
 
 
2456
  if (format == DUMP_TEXT)
 
2457
    {
 
2458
    fprintf (dumpfile," %s  ", dump_tag);
 
2459
    for (j = 0, k = 7; j < 8; j++, k--)
 
2460
      {
 
2461
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
 
2462
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2463
      }
 
2464
    dump_array[8] = '\0';
 
2465
    fprintf (dumpfile," %s\n", dump_array);
 
2466
    }
 
2467
  else
 
2468
    {
 
2469
    if ((fwrite (&data, 1, 1, dumpfile)) != 1)
 
2470
      {
 
2471
      TIFFError ("", "Unable to write binary data to dump file");
 
2472
      return (1);
 
2473
      }
 
2474
    }
 
2475
 
 
2476
  return (0);
 
2477
  }
 
2478
 
 
2479
static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
 
2480
  {
 
2481
  int j, k;
 
2482
  char  dump_array[20];
 
2483
  unsigned char bitset;
 
2484
 
 
2485
  if (dumpfile == NULL)
 
2486
    {
 
2487
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2488
    return (1);
 
2489
    }
 
2490
 
 
2491
  if (format == DUMP_TEXT)
 
2492
    {
 
2493
    fprintf (dumpfile," %s  ", dump_tag);
 
2494
    for (j = 0, k = 15; k >= 0; j++, k--)
 
2495
      {
 
2496
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
 
2497
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2498
      if ((k % 8) == 0)
 
2499
          sprintf(&dump_array[++j], " ");
 
2500
      }
 
2501
    dump_array[17] = '\0';
 
2502
    fprintf (dumpfile," %s\n", dump_array);
 
2503
    }
 
2504
  else
 
2505
    {
 
2506
    if ((fwrite (&data, 2, 1, dumpfile)) != 2)
 
2507
      {
 
2508
      TIFFError ("", "Unable to write binary data to dump file");
 
2509
      return (1);
 
2510
      }
 
2511
    }
 
2512
 
 
2513
  return (0);
 
2514
  }
 
2515
 
 
2516
static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
 
2517
  {
 
2518
  int j, k;
 
2519
  char  dump_array[40];
 
2520
  unsigned char bitset;
 
2521
 
 
2522
  if (dumpfile == NULL)
 
2523
    {
 
2524
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2525
    return (1);
 
2526
    }
 
2527
 
 
2528
  if (format == DUMP_TEXT)
 
2529
    {
 
2530
    fprintf (dumpfile," %s  ", dump_tag);
 
2531
    for (j = 0, k = 31; k >= 0; j++, k--)
 
2532
      {
 
2533
      bitset = data & (((uint32)1 << k)) ? 1 : 0;
 
2534
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2535
      if ((k % 8) == 0)
 
2536
          sprintf(&dump_array[++j], " ");
 
2537
      }
 
2538
    dump_array[35] = '\0';
 
2539
    fprintf (dumpfile," %s\n", dump_array);
 
2540
    }
 
2541
  else
 
2542
    {
 
2543
    if ((fwrite (&data, 4, 1, dumpfile)) != 4)
 
2544
      {
 
2545
      TIFFError ("", "Unable to write binary data to dump file");
 
2546
      return (1);
 
2547
      }
 
2548
    }
 
2549
  return (0);
 
2550
  }
 
2551
 
 
2552
static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
 
2553
  {
 
2554
  int j, k;
 
2555
  char  dump_array[80];
 
2556
  unsigned char bitset;
 
2557
 
 
2558
  if (dumpfile == NULL)
 
2559
    {
 
2560
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2561
    return (1);
 
2562
    }
 
2563
 
 
2564
  if (format == DUMP_TEXT)
 
2565
    {
 
2566
    fprintf (dumpfile," %s  ", dump_tag);
 
2567
    for (j = 0, k = 63; k >= 0; j++, k--)
 
2568
      {
 
2569
      bitset = data & (((uint64)1 << k)) ? 1 : 0;
 
2570
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
 
2571
      if ((k % 8) == 0)
 
2572
          sprintf(&dump_array[++j], " ");
 
2573
      }
 
2574
    dump_array[71] = '\0';
 
2575
    fprintf (dumpfile," %s\n", dump_array);
 
2576
    }
 
2577
  else
 
2578
    {
 
2579
    if ((fwrite (&data, 8, 1, dumpfile)) != 8)
 
2580
      {
 
2581
      TIFFError ("", "Unable to write binary data to dump file");
 
2582
      return (1);
 
2583
      }
 
2584
    }
 
2585
 
 
2586
  return (0);
 
2587
  }
 
2588
 
 
2589
static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
 
2590
  {
 
2591
  if (format == DUMP_TEXT)
 
2592
    {
 
2593
    va_list ap;
 
2594
    va_start(ap, msg);
 
2595
    fprintf(dumpfile, "%s ", prefix);
 
2596
    vfprintf(dumpfile, msg, ap);
 
2597
    fprintf(dumpfile, "\n");
 
2598
    }
 
2599
  }
 
2600
 
 
2601
static int dump_buffer (FILE* dumpfile, int format, uint32 rows, uint32 width, 
 
2602
                 uint32 row, unsigned char *buff)
 
2603
  {
 
2604
  int j, k;
 
2605
  uint32 i;
 
2606
  unsigned char * dump_ptr;
 
2607
 
 
2608
  if (dumpfile == NULL)
 
2609
    {
 
2610
    TIFFError ("", "Invalid FILE pointer for dump file");
 
2611
    return (1);
 
2612
    }
 
2613
 
 
2614
  for (i = 0; i < rows; i++)
 
2615
    {
 
2616
    dump_ptr = buff + (i * width);
 
2617
    if (format == DUMP_TEXT)
 
2618
      dump_info (dumpfile, format, "", 
 
2619
                 "Row %4d, %d bytes at offset %d",
 
2620
                 row + i + 1, width, row * width);
 
2621
     
 
2622
    for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
 
2623
      dump_data (dumpfile, format, "", dump_ptr, 10);
 
2624
    if (k > 0)
 
2625
      dump_data (dumpfile, format, "", dump_ptr, k);
 
2626
    }
 
2627
  return (0);
 
2628
  }
 
2629
 
 
2630
/* Extract one or more samples from an interleaved buffer. If count == 1,
 
2631
 * only the sample plane indicated by sample will be extracted.  If count > 1, 
 
2632
 * count samples beginning at sample will be extracted. Portions of a 
 
2633
 * scanline can be extracted by specifying a start and end value.
 
2634
 */
 
2635
 
 
2636
static int 
 
2637
extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols, 
 
2638
                           tsample_t sample, uint16 spp, uint16 bps, 
 
2639
                           tsample_t count, uint32 start, uint32 end)
 
2640
  {
 
2641
  int i, bytes_per_sample, sindex;
 
2642
  uint32 col, dst_rowsize, bit_offset;
 
2643
  uint32 src_byte, src_bit;
 
2644
  uint8 *src = in;
 
2645
  uint8 *dst = out;
 
2646
 
 
2647
  if ((src == NULL) || (dst == NULL))
 
2648
    {
 
2649
    TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
 
2650
    return (1);
 
2651
    }
 
2652
 
 
2653
  if ((start > end) || (start > cols))
 
2654
    {
 
2655
    TIFFError ("extractContigSamplesBytes", 
 
2656
               "Invalid start column value %d ignored", start);
 
2657
    start = 0;
 
2658
    }
 
2659
  if ((end == 0) || (end > cols))
 
2660
    {
 
2661
    TIFFError ("extractContigSamplesBytes", 
 
2662
               "Invalid end column value %d ignored", end);
 
2663
    end = cols;
 
2664
    }
 
2665
 
 
2666
  dst_rowsize = (bps * (end - start) * count) / 8;
 
2667
 
 
2668
  bytes_per_sample = (bps + 7) / 8; 
 
2669
  /* Optimize case for copying all samples */
 
2670
  if (count == spp)
 
2671
    {
 
2672
    src = in + (start * spp * bytes_per_sample);
 
2673
    _TIFFmemcpy (dst, src, dst_rowsize);
 
2674
    }
 
2675
  else
 
2676
    {
 
2677
    for (col = start; col < end; col++)
 
2678
      {
 
2679
      for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
2680
        {
 
2681
        bit_offset = col * bps * spp;
 
2682
        if (sindex == 0)
 
2683
          {
 
2684
          src_byte = bit_offset / 8;
 
2685
          src_bit  = bit_offset % 8;
 
2686
          }
 
2687
        else
 
2688
          {
 
2689
          src_byte = (bit_offset + (sindex * bps)) / 8;
 
2690
          src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2691
          }
 
2692
        src = in + src_byte;
 
2693
        for (i = 0; i < bytes_per_sample; i++)
 
2694
            *dst++ = *src++;
 
2695
        }
 
2696
      }
 
2697
    }
 
2698
 
 
2699
  return (0);
 
2700
  } /* end extractContigSamplesBytes */
 
2701
 
 
2702
static int
 
2703
extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
 
2704
                           tsample_t sample, uint16 spp, uint16 bps, 
 
2705
                           tsample_t count, uint32 start, uint32 end)
 
2706
  {
 
2707
  int    ready_bits = 0, sindex = 0;
 
2708
  uint32 col, src_byte, src_bit, bit_offset;
 
2709
  uint8  maskbits = 0, matchbits = 0;
 
2710
  uint8  buff1 = 0, buff2 = 0;
 
2711
  uint8 *src = in;
 
2712
  uint8 *dst = out;
 
2713
 
 
2714
  if ((src == NULL) || (dst == NULL))
 
2715
    {
 
2716
    TIFFError("extractContigSamples8bits","Invalid input or output buffer");
 
2717
    return (1);
 
2718
    }
 
2719
 
 
2720
  if ((start > end) || (start > cols))
 
2721
    {
 
2722
    TIFFError ("extractContigSamples8bits", 
 
2723
               "Invalid start column value %d ignored", start);
 
2724
    start = 0;
 
2725
    }
 
2726
  if ((end == 0) || (end > cols))
 
2727
    {
 
2728
    TIFFError ("extractContigSamples8bits", 
 
2729
               "Invalid end column value %d ignored", end);
 
2730
    end = cols;
 
2731
    }
 
2732
  
 
2733
  ready_bits = 0;
 
2734
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
2735
  buff1 = buff2 = 0;
 
2736
  for (col = start; col < end; col++)
 
2737
    {    /* Compute src byte(s) and bits within byte(s) */
 
2738
    bit_offset = col * bps * spp;
 
2739
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
2740
      {
 
2741
      if (sindex == 0)
 
2742
        {
 
2743
        src_byte = bit_offset / 8;
 
2744
        src_bit  = bit_offset % 8;
 
2745
        }
 
2746
      else
 
2747
        {
 
2748
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2749
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2750
        }
 
2751
 
 
2752
      src = in + src_byte;
 
2753
      matchbits = maskbits << (8 - src_bit - bps); 
 
2754
      buff1 = ((*src) & matchbits) << (src_bit);
 
2755
 
 
2756
      /* If we have a full buffer's worth, write it out */
 
2757
      if (ready_bits >= 8)
 
2758
        {
 
2759
        *dst++ = buff2;
 
2760
        buff2 = buff1;
 
2761
        ready_bits -= 8;
 
2762
        }
 
2763
      else
 
2764
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2765
      ready_bits += bps;
 
2766
      }
 
2767
    }
 
2768
 
 
2769
  while (ready_bits > 0)
 
2770
    {
 
2771
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
2772
    *dst++ = buff1;
 
2773
    ready_bits -= 8;
 
2774
    }
 
2775
 
 
2776
  return (0);
 
2777
  } /* end extractContigSamples8bits */
 
2778
 
 
2779
static int
 
2780
extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols, 
 
2781
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2782
                            tsample_t count, uint32 start, uint32 end)
 
2783
  {
 
2784
  int    ready_bits = 0, sindex = 0;
 
2785
  uint32 col, src_byte, src_bit, bit_offset;
 
2786
  uint16 maskbits = 0, matchbits = 0;
 
2787
  uint16 buff1 = 0, buff2 = 0;
 
2788
  uint8  bytebuff = 0;
 
2789
  uint8 *src = in;
 
2790
  uint8 *dst = out;
 
2791
 
 
2792
  if ((src == NULL) || (dst == NULL))
 
2793
    {
 
2794
    TIFFError("extractContigSamples16bits","Invalid input or output buffer");
 
2795
    return (1);
 
2796
    }
 
2797
 
 
2798
  if ((start > end) || (start > cols))
 
2799
    {
 
2800
    TIFFError ("extractContigSamples16bits", 
 
2801
               "Invalid start column value %d ignored", start);
 
2802
    start = 0;
 
2803
    }
 
2804
  if ((end == 0) || (end > cols))
 
2805
    {
 
2806
    TIFFError ("extractContigSamples16bits", 
 
2807
               "Invalid end column value %d ignored", end);
 
2808
    end = cols;
 
2809
    }
 
2810
 
 
2811
  ready_bits = 0;
 
2812
  maskbits = (uint16)-1 >> (16 - bps);
 
2813
 
 
2814
  for (col = start; col < end; col++)
 
2815
    {    /* Compute src byte(s) and bits within byte(s) */
 
2816
    bit_offset = col * bps * spp;
 
2817
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
2818
      {
 
2819
      if (sindex == 0)
 
2820
        {
 
2821
        src_byte = bit_offset / 8;
 
2822
        src_bit  = bit_offset % 8;
 
2823
        }
 
2824
      else
 
2825
        {
 
2826
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2827
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2828
        }
 
2829
 
 
2830
      src = in + src_byte;
 
2831
      matchbits = maskbits << (16 - src_bit - bps); 
 
2832
 
 
2833
      if (little_endian)
 
2834
        buff1 = (src[0] << 8) | src[1];
 
2835
      else
 
2836
        buff1 = (src[1] << 8) | src[0];
 
2837
 
 
2838
      buff1 = (buff1 & matchbits) << (src_bit);
 
2839
      if (ready_bits < 8) /* add another bps bits to the buffer */
 
2840
        { 
 
2841
        bytebuff = 0;
 
2842
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2843
        }
 
2844
      else /* If we have a full buffer's worth, write it out */
 
2845
        {
 
2846
        bytebuff = (buff2 >> 8);
 
2847
        *dst++ = bytebuff;
 
2848
        ready_bits -= 8;
 
2849
        /* shift in new bits */
 
2850
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
2851
        }
 
2852
      ready_bits += bps;
 
2853
      }
 
2854
    }
 
2855
 
 
2856
  /* catch any trailing bits at the end of the line */
 
2857
  while (ready_bits > 0)
 
2858
    {
 
2859
    bytebuff = (buff2 >> 8);
 
2860
    *dst++ = bytebuff;
 
2861
    ready_bits -= 8;
 
2862
    }
 
2863
  
 
2864
  return (0);
 
2865
  } /* end extractContigSamples16bits */
 
2866
 
 
2867
 
 
2868
static int
 
2869
extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
 
2870
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2871
                            tsample_t count, uint32 start, uint32 end)
 
2872
  {
 
2873
  int    ready_bits = 0, sindex = 0;
 
2874
  uint32 col, src_byte, src_bit, bit_offset;
 
2875
  uint32 maskbits = 0, matchbits = 0;
 
2876
  uint32 buff1 = 0, buff2 = 0;
 
2877
  uint8  bytebuff1 = 0, bytebuff2 = 0;
 
2878
  uint8 *src = in;
 
2879
  uint8 *dst = out;
 
2880
 
 
2881
  if ((in == NULL) || (out == NULL))
 
2882
    {
 
2883
    TIFFError("extractContigSamples24bits","Invalid input or output buffer");
 
2884
    return (1);
 
2885
    }
 
2886
 
 
2887
  if ((start > end) || (start > cols))
 
2888
    {
 
2889
    TIFFError ("extractContigSamples24bits", 
 
2890
               "Invalid start column value %d ignored", start);
 
2891
    start = 0;
 
2892
    }
 
2893
  if ((end == 0) || (end > cols))
 
2894
    {
 
2895
    TIFFError ("extractContigSamples24bits", 
 
2896
               "Invalid end column value %d ignored", end);
 
2897
    end = cols;
 
2898
    }
 
2899
 
 
2900
  ready_bits = 0;
 
2901
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
2902
  for (col = start; col < end; col++)
 
2903
    {
 
2904
    /* Compute src byte(s) and bits within byte(s) */
 
2905
    bit_offset = col * bps * spp;
 
2906
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
2907
      {
 
2908
      if (sindex == 0)
 
2909
        {
 
2910
        src_byte = bit_offset / 8;
 
2911
        src_bit  = bit_offset % 8;
 
2912
        }
 
2913
      else
 
2914
        {
 
2915
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
2916
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
2917
        }
 
2918
 
 
2919
      src = in + src_byte;
 
2920
      matchbits = maskbits << (32 - src_bit - bps); 
 
2921
      if (little_endian)
 
2922
        buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
2923
      else
 
2924
        buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
2925
      buff1 = (buff1 & matchbits) << (src_bit);
 
2926
 
 
2927
      if (ready_bits < 16) /* add another bps bits to the buffer */
 
2928
        {
 
2929
        bytebuff1 = bytebuff2 = 0;
 
2930
        buff2 = (buff2 | (buff1 >> ready_bits));
 
2931
        }
 
2932
      else /* If we have a full buffer's worth, write it out */
 
2933
        {
 
2934
        bytebuff1 = (buff2 >> 24);
 
2935
        *dst++ = bytebuff1;
 
2936
        bytebuff2 = (buff2 >> 16);
 
2937
        *dst++ = bytebuff2;
 
2938
        ready_bits -= 16;
 
2939
 
 
2940
        /* shift in new bits */
 
2941
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
2942
        }
 
2943
      ready_bits += bps;
 
2944
      }
 
2945
    }
 
2946
 
 
2947
  /* catch any trailing bits at the end of the line */
 
2948
  while (ready_bits > 0)
 
2949
    {
 
2950
    bytebuff1 = (buff2 >> 24);
 
2951
    *dst++ = bytebuff1;
 
2952
 
 
2953
    buff2 = (buff2 << 8);
 
2954
    bytebuff2 = bytebuff1;
 
2955
    ready_bits -= 8;
 
2956
    } 
 
2957
  
 
2958
  return (0);
 
2959
  } /* end extractContigSamples24bits */
 
2960
 
 
2961
static int
 
2962
extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
 
2963
                            tsample_t sample, uint16 spp, uint16 bps, 
 
2964
                            tsample_t count, uint32 start, uint32 end)
 
2965
  {
 
2966
  int    ready_bits = 0, sindex = 0, shift_width = 0;
 
2967
  uint32 col, src_byte, src_bit, bit_offset;
 
2968
  uint32 longbuff1 = 0, longbuff2 = 0;
 
2969
  uint64 maskbits = 0, matchbits = 0;
 
2970
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
2971
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
2972
  uint8 *src = in;
 
2973
  uint8 *dst = out;
 
2974
 
 
2975
  if ((in == NULL) || (out == NULL))
 
2976
    {
 
2977
    TIFFError("extractContigSamples32bits","Invalid input or output buffer");
 
2978
    return (1);
 
2979
    }
 
2980
 
 
2981
 
 
2982
  if ((start > end) || (start > cols))
 
2983
    {
 
2984
    TIFFError ("extractContigSamples32bits", 
 
2985
               "Invalid start column value %d ignored", start);
 
2986
    start = 0;
 
2987
    }
 
2988
  if ((end == 0) || (end > cols))
 
2989
    {
 
2990
    TIFFError ("extractContigSamples32bits", 
 
2991
               "Invalid end column value %d ignored", end);
 
2992
    end = cols;
 
2993
    }
 
2994
 
 
2995
  shift_width = ((bps + 7) / 8) + 1; 
 
2996
  ready_bits = 0;
 
2997
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
2998
  for (col = start; col < end; col++)
 
2999
    {
 
3000
    /* Compute src byte(s) and bits within byte(s) */
 
3001
    bit_offset = col * bps * spp;
 
3002
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
3003
      {
 
3004
      if (sindex == 0)
 
3005
        {
 
3006
        src_byte = bit_offset / 8;
 
3007
        src_bit  = bit_offset % 8;
 
3008
        }
 
3009
      else
 
3010
        {
 
3011
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3012
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3013
        }
 
3014
 
 
3015
      src = in + src_byte;
 
3016
      matchbits = maskbits << (64 - src_bit - bps); 
 
3017
      if (little_endian)
 
3018
        {
 
3019
        longbuff1 = (src[0] << 24) | (src[1] << 16)  | (src[2] << 8) | src[3];
 
3020
        longbuff2 = longbuff1;
 
3021
        }
 
3022
      else
 
3023
        {
 
3024
        longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
3025
        longbuff2 = longbuff1;
 
3026
        }
 
3027
 
 
3028
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
3029
      buff1 = (buff3 & matchbits) << (src_bit);
 
3030
 
 
3031
      /* If we have a full buffer's worth, write it out */
 
3032
      if (ready_bits >= 32)
 
3033
        {
 
3034
        bytebuff1 = (buff2 >> 56);
 
3035
        *dst++ = bytebuff1;
 
3036
        bytebuff2 = (buff2 >> 48);
 
3037
        *dst++ = bytebuff2;
 
3038
        bytebuff3 = (buff2 >> 40);
 
3039
        *dst++ = bytebuff3;
 
3040
        bytebuff4 = (buff2 >> 32);
 
3041
        *dst++ = bytebuff4;
 
3042
        ready_bits -= 32;
 
3043
                    
 
3044
        /* shift in new bits */
 
3045
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
3046
        }
 
3047
      else
 
3048
        { /* add another bps bits to the buffer */
 
3049
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
3050
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3051
        }
 
3052
      ready_bits += bps;
 
3053
      }
 
3054
    }
 
3055
  while (ready_bits > 0)
 
3056
    {
 
3057
    bytebuff1 = (buff2 >> 56);
 
3058
    *dst++ = bytebuff1;
 
3059
    buff2 = (buff2 << 8);
 
3060
    ready_bits -= 8;
 
3061
    }
 
3062
  
 
3063
  return (0);
 
3064
  } /* end extractContigSamples32bits */
 
3065
 
 
3066
static int
 
3067
extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
 
3068
                                  tsample_t sample, uint16 spp, uint16 bps, 
 
3069
                                  tsample_t count, uint32 start, uint32 end,
 
3070
                                  int shift)
 
3071
  {
 
3072
  int    ready_bits = 0, sindex = 0;
 
3073
  uint32 col, src_byte, src_bit, bit_offset;
 
3074
  uint8  maskbits = 0, matchbits = 0;
 
3075
  uint8  buff1 = 0, buff2 = 0;
 
3076
  uint8 *src = in;
 
3077
  uint8 *dst = out;
 
3078
 
 
3079
  if ((src == NULL) || (dst == NULL))
 
3080
    {
 
3081
    TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
 
3082
    return (1);
 
3083
    }
 
3084
 
 
3085
  if ((start > end) || (start > cols))
 
3086
    {
 
3087
    TIFFError ("extractContigSamplesShifted8bits", 
 
3088
               "Invalid start column value %d ignored", start);
 
3089
    start = 0;
 
3090
    }
 
3091
  if ((end == 0) || (end > cols))
 
3092
    {
 
3093
    TIFFError ("extractContigSamplesShifted8bits", 
 
3094
               "Invalid end column value %d ignored", end);
 
3095
    end = cols;
 
3096
    }
 
3097
 
 
3098
  ready_bits = shift;
 
3099
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
3100
  buff1 = buff2 = 0;
 
3101
  for (col = start; col < end; col++)
 
3102
    {    /* Compute src byte(s) and bits within byte(s) */
 
3103
    bit_offset = col * bps * spp;
 
3104
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
3105
      {
 
3106
      if (sindex == 0)
 
3107
        {
 
3108
        src_byte = bit_offset / 8;
 
3109
        src_bit  = bit_offset % 8;
 
3110
        }
 
3111
      else
 
3112
        {
 
3113
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3114
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3115
        }
 
3116
 
 
3117
      src = in + src_byte;
 
3118
      matchbits = maskbits << (8 - src_bit - bps); 
 
3119
      buff1 = ((*src) & matchbits) << (src_bit);
 
3120
      if ((col == start) && (sindex == sample))
 
3121
        buff2 = *src & ((uint8)-1) << (shift);
 
3122
 
 
3123
      /* If we have a full buffer's worth, write it out */
 
3124
      if (ready_bits >= 8)
 
3125
        {
 
3126
        *dst++ |= buff2;
 
3127
        buff2 = buff1;
 
3128
        ready_bits -= 8;
 
3129
        }
 
3130
      else
 
3131
        buff2 = buff2 | (buff1 >> ready_bits);
 
3132
      ready_bits += bps;
 
3133
      }
 
3134
    }
 
3135
 
 
3136
  while (ready_bits > 0)
 
3137
    {
 
3138
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
3139
    *dst++ = buff1;
 
3140
    ready_bits -= 8;
 
3141
    }
 
3142
 
 
3143
  return (0);
 
3144
  } /* end extractContigSamplesShifted8bits */
 
3145
 
 
3146
static int
 
3147
extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols, 
 
3148
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
3149
                                   tsample_t count, uint32 start, uint32 end,
 
3150
                                   int shift)
 
3151
  {
 
3152
  int    ready_bits = 0, sindex = 0;
 
3153
  uint32 col, src_byte, src_bit, bit_offset;
 
3154
  uint16 maskbits = 0, matchbits = 0;
 
3155
  uint16 buff1 = 0, buff2 = 0;
 
3156
  uint8  bytebuff = 0;
 
3157
  uint8 *src = in;
 
3158
  uint8 *dst = out;
 
3159
  
 
3160
  if ((src == NULL) || (dst == NULL))
 
3161
    {
 
3162
    TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
 
3163
    return (1);
 
3164
    }
 
3165
 
 
3166
  if ((start > end) || (start > cols))
 
3167
    {
 
3168
    TIFFError ("extractContigSamplesShifted16bits", 
 
3169
               "Invalid start column value %d ignored", start);
 
3170
    start = 0;
 
3171
    }
 
3172
  if ((end == 0) || (end > cols))
 
3173
    {
 
3174
    TIFFError ("extractContigSamplesShifted16bits", 
 
3175
               "Invalid end column value %d ignored", end);
 
3176
    end = cols;
 
3177
    }
 
3178
 
 
3179
  ready_bits = shift;
 
3180
  maskbits = (uint16)-1 >> (16 - bps);
 
3181
  for (col = start; col < end; col++)
 
3182
    {    /* Compute src byte(s) and bits within byte(s) */
 
3183
    bit_offset = col * bps * spp;
 
3184
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
3185
      {
 
3186
      if (sindex == 0)
 
3187
        {
 
3188
        src_byte = bit_offset / 8;
 
3189
        src_bit  = bit_offset % 8;
 
3190
        }
 
3191
      else
 
3192
        {
 
3193
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3194
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3195
        }
 
3196
 
 
3197
      src = in + src_byte;
 
3198
      matchbits = maskbits << (16 - src_bit - bps); 
 
3199
      if (little_endian)
 
3200
        buff1 = (src[0] << 8) | src[1];
 
3201
      else
 
3202
        buff1 = (src[1] << 8) | src[0];
 
3203
 
 
3204
      if ((col == start) && (sindex == sample))
 
3205
        buff2 = buff1 & ((uint16)-1) << (8 - shift);
 
3206
 
 
3207
      buff1 = (buff1 & matchbits) << (src_bit);
 
3208
 
 
3209
      if (ready_bits < 8) /* add another bps bits to the buffer */
 
3210
        buff2 = buff2 | (buff1 >> ready_bits);
 
3211
      else  /* If we have a full buffer's worth, write it out */
 
3212
        {
 
3213
        bytebuff = (buff2 >> 8);
 
3214
        *dst++ = bytebuff;
 
3215
        ready_bits -= 8;
 
3216
        /* shift in new bits */
 
3217
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
3218
        }
 
3219
 
 
3220
      ready_bits += bps;
 
3221
      }
 
3222
    }
 
3223
 
 
3224
  /* catch any trailing bits at the end of the line */
 
3225
  while (ready_bits > 0)
 
3226
    {
 
3227
    bytebuff = (buff2 >> 8);
 
3228
    *dst++ = bytebuff;
 
3229
    ready_bits -= 8;
 
3230
    }
 
3231
  
 
3232
  return (0);
 
3233
  } /* end extractContigSamplesShifted16bits */
 
3234
 
 
3235
 
 
3236
static int
 
3237
extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
 
3238
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
3239
                                   tsample_t count, uint32 start, uint32 end,
 
3240
                                   int shift)
 
3241
  {
 
3242
  int    ready_bits = 0, sindex = 0;
 
3243
  uint32 col, src_byte, src_bit, bit_offset;
 
3244
  uint32 maskbits = 0, matchbits = 0;
 
3245
  uint32 buff1 = 0, buff2 = 0;
 
3246
  uint8  bytebuff1 = 0, bytebuff2 = 0;
 
3247
  uint8 *src = in;
 
3248
  uint8 *dst = out;
 
3249
 
 
3250
  if ((in == NULL) || (out == NULL))
 
3251
    {
 
3252
    TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
 
3253
    return (1);
 
3254
    }
 
3255
 
 
3256
  if ((start > end) || (start > cols))
 
3257
    {
 
3258
    TIFFError ("extractContigSamplesShifted24bits", 
 
3259
               "Invalid start column value %d ignored", start);
 
3260
    start = 0;
 
3261
    }
 
3262
  if ((end == 0) || (end > cols))
 
3263
    {
 
3264
    TIFFError ("extractContigSamplesShifted24bits", 
 
3265
               "Invalid end column value %d ignored", end);
 
3266
    end = cols;
 
3267
    }
 
3268
 
 
3269
  ready_bits = shift;
 
3270
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
3271
  for (col = start; col < end; col++)
 
3272
    {
 
3273
    /* Compute src byte(s) and bits within byte(s) */
 
3274
    bit_offset = col * bps * spp;
 
3275
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
3276
      {
 
3277
      if (sindex == 0)
 
3278
        {
 
3279
        src_byte = bit_offset / 8;
 
3280
        src_bit  = bit_offset % 8;
 
3281
        }
 
3282
      else
 
3283
        {
 
3284
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3285
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3286
        }
 
3287
 
 
3288
      src = in + src_byte;
 
3289
      matchbits = maskbits << (32 - src_bit - bps); 
 
3290
      if (little_endian)
 
3291
        buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
3292
      else
 
3293
        buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
3294
 
 
3295
      if ((col == start) && (sindex == sample))
 
3296
        buff2 = buff1 & ((uint32)-1) << (16 - shift);
 
3297
 
 
3298
      buff1 = (buff1 & matchbits) << (src_bit);
 
3299
 
 
3300
      if (ready_bits < 16)  /* add another bps bits to the buffer */
 
3301
        {
 
3302
        bytebuff1 = bytebuff2 = 0;
 
3303
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3304
        }
 
3305
      else /* If we have a full buffer's worth, write it out */
 
3306
        {
 
3307
        bytebuff1 = (buff2 >> 24);
 
3308
        *dst++ = bytebuff1;
 
3309
        bytebuff2 = (buff2 >> 16);
 
3310
        *dst++ = bytebuff2;
 
3311
        ready_bits -= 16;
 
3312
 
 
3313
        /* shift in new bits */
 
3314
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
3315
        }
 
3316
      ready_bits += bps;
 
3317
      }
 
3318
    }
 
3319
 
 
3320
  /* catch any trailing bits at the end of the line */
 
3321
  while (ready_bits > 0)
 
3322
    {
 
3323
    bytebuff1 = (buff2 >> 24);
 
3324
    *dst++ = bytebuff1;
 
3325
 
 
3326
    buff2 = (buff2 << 8);
 
3327
    bytebuff2 = bytebuff1;
 
3328
    ready_bits -= 8;
 
3329
    }
 
3330
   
 
3331
  return (0);
 
3332
  } /* end extractContigSamplesShifted24bits */
 
3333
 
 
3334
static int
 
3335
extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
 
3336
                                   tsample_t sample, uint16 spp, uint16 bps, 
 
3337
                                   tsample_t count, uint32 start, uint32 end,
 
3338
                                   int shift)
 
3339
  {
 
3340
  int    ready_bits = 0, sindex = 0, shift_width = 0;
 
3341
  uint32 col, src_byte, src_bit, bit_offset;
 
3342
  uint32 longbuff1 = 0, longbuff2 = 0;
 
3343
  uint64 maskbits = 0, matchbits = 0;
 
3344
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
3345
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
3346
  uint8 *src = in;
 
3347
  uint8 *dst = out;
 
3348
 
 
3349
  if ((in == NULL) || (out == NULL))
 
3350
    {
 
3351
    TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
 
3352
    return (1);
 
3353
    }
 
3354
 
 
3355
 
 
3356
  if ((start > end) || (start > cols))
 
3357
    {
 
3358
    TIFFError ("extractContigSamplesShifted32bits", 
 
3359
               "Invalid start column value %d ignored", start);
 
3360
    start = 0;
 
3361
    }
 
3362
  if ((end == 0) || (end > cols))
 
3363
    {
 
3364
    TIFFError ("extractContigSamplesShifted32bits", 
 
3365
               "Invalid end column value %d ignored", end);
 
3366
    end = cols;
 
3367
    }
 
3368
 
 
3369
  shift_width = ((bps + 7) / 8) + 1; 
 
3370
  ready_bits = shift;
 
3371
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
3372
  for (col = start; col < end; col++)
 
3373
    {
 
3374
    /* Compute src byte(s) and bits within byte(s) */
 
3375
    bit_offset = col * bps * spp;
 
3376
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
 
3377
      {
 
3378
      if (sindex == 0)
 
3379
        {
 
3380
        src_byte = bit_offset / 8;
 
3381
        src_bit  = bit_offset % 8;
 
3382
        }
 
3383
      else
 
3384
        {
 
3385
        src_byte = (bit_offset + (sindex * bps)) / 8;
 
3386
        src_bit  = (bit_offset + (sindex * bps)) % 8;
 
3387
        }
 
3388
 
 
3389
      src = in + src_byte;
 
3390
      matchbits = maskbits << (64 - src_bit - bps); 
 
3391
      if (little_endian)
 
3392
        {
 
3393
        longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
3394
        longbuff2 = longbuff1;
 
3395
        }
 
3396
      else
 
3397
        {
 
3398
        longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
3399
        longbuff2 = longbuff1;
 
3400
        }
 
3401
 
 
3402
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
3403
      if ((col == start) && (sindex == sample))
 
3404
        buff2 = buff3 & ((uint64)-1) << (32 - shift);
 
3405
 
 
3406
      buff1 = (buff3 & matchbits) << (src_bit);
 
3407
 
 
3408
      if (ready_bits < 32)
 
3409
        { /* add another bps bits to the buffer */
 
3410
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
3411
        buff2 = (buff2 | (buff1 >> ready_bits));
 
3412
        }
 
3413
      else  /* If we have a full buffer's worth, write it out */
 
3414
        {
 
3415
        bytebuff1 = (buff2 >> 56);
 
3416
        *dst++ = bytebuff1;
 
3417
        bytebuff2 = (buff2 >> 48);
 
3418
        *dst++ = bytebuff2;
 
3419
        bytebuff3 = (buff2 >> 40);
 
3420
        *dst++ = bytebuff3;
 
3421
        bytebuff4 = (buff2 >> 32);
 
3422
        *dst++ = bytebuff4;
 
3423
        ready_bits -= 32;
 
3424
                    
 
3425
        /* shift in new bits */
 
3426
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
3427
        }
 
3428
      ready_bits += bps;
 
3429
      }
 
3430
    }
 
3431
  while (ready_bits > 0)
 
3432
    {
 
3433
    bytebuff1 = (buff2 >> 56);
 
3434
    *dst++ = bytebuff1;
 
3435
    buff2 = (buff2 << 8);
 
3436
    ready_bits -= 8;
 
3437
    }
 
3438
  
 
3439
  return (0);
 
3440
  } /* end extractContigSamplesShifted32bits */
 
3441
 
 
3442
static int
 
3443
extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
 
3444
                             tsample_t sample, uint16 spp, uint16 bps, 
 
3445
                             struct dump_opts *dump)
 
3446
  {
 
3447
  int    shift_width, bytes_per_sample, bytes_per_pixel;
 
3448
  uint32 src_rowsize, src_offset, row, first_col = 0;
 
3449
  uint32 dst_rowsize, dst_offset;
 
3450
  tsample_t count = 1;
 
3451
  uint8 *src, *dst;
 
3452
 
 
3453
  bytes_per_sample = (bps + 7) / 8; 
 
3454
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
3455
  if ((bps % 8) == 0)
 
3456
    shift_width = 0;
 
3457
  else
 
3458
    {
 
3459
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
3460
      shift_width = bytes_per_pixel;
 
3461
    else
 
3462
      shift_width = bytes_per_sample + 1;
 
3463
    }
 
3464
  src_rowsize = ((bps * spp * cols) + 7) / 8;
 
3465
  dst_rowsize = ((bps * cols) + 7) / 8;
 
3466
 
 
3467
  if ((dump->outfile != NULL) && (dump->level == 4))
 
3468
    {
 
3469
    dump_info  (dump->outfile, dump->format, "extractContigSamplesToBuffer", 
 
3470
                "Sample %d, %d rows", sample + 1, rows + 1);
 
3471
    }
 
3472
  for (row = 0; row < rows; row++)
 
3473
    {
 
3474
    src_offset = row * src_rowsize;
 
3475
    dst_offset = row * dst_rowsize;
 
3476
    src = in + src_offset;
 
3477
    dst = out + dst_offset;
 
3478
 
 
3479
    /* pack the data into the scanline */
 
3480
    switch (shift_width)
 
3481
      {  
 
3482
      case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
 
3483
                                             spp, bps,  count, first_col, cols))  
 
3484
                return (1);
 
3485
              break;
 
3486
      case 1: if (bps == 1)
 
3487
                {
 
3488
                if (extractContigSamples8bits (src, dst, cols, sample,
 
3489
                                               spp, bps, count, first_col, cols))
 
3490
                  return (1);
 
3491
                break;
 
3492
                }
 
3493
              else
 
3494
                 if (extractContigSamples16bits (src, dst, cols, sample,
 
3495
                                                 spp, bps, count, first_col, cols))
 
3496
                 return (1);
 
3497
              break;
 
3498
      case 2: if (extractContigSamples24bits (src, dst, cols, sample,
 
3499
                                              spp, bps,  count, first_col, cols))
 
3500
                 return (1);
 
3501
              break;
 
3502
      case 3:
 
3503
      case 4: 
 
3504
      case 5: if (extractContigSamples32bits (src, dst, cols, sample,
 
3505
                                              spp, bps,  count, first_col, cols))
 
3506
                 return (1);
 
3507
              break;
 
3508
      default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
 
3509
               return (1);
 
3510
      }
 
3511
    if ((dump->outfile != NULL) && (dump->level == 4))
 
3512
      dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
 
3513
    }
 
3514
 
 
3515
  return (0);
 
3516
  } /* end extractContigSamplesToBuffer */
 
3517
 
 
3518
static int
 
3519
extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
 
3520
                                 uint32 imagewidth, uint32 tilewidth, tsample_t sample,
 
3521
                                 uint16 count, uint16 spp, uint16 bps, struct dump_opts *dump)
 
3522
  {
 
3523
  int    shift_width, bytes_per_sample, bytes_per_pixel;
 
3524
  uint32 src_rowsize, src_offset, row;
 
3525
  uint32 dst_rowsize, dst_offset;
 
3526
  uint8 *src, *dst;
 
3527
 
 
3528
  bytes_per_sample = (bps + 7) / 8; 
 
3529
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
3530
  if ((bps % 8) == 0)
 
3531
    shift_width = 0;
 
3532
  else
 
3533
    {
 
3534
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
3535
      shift_width = bytes_per_pixel;
 
3536
    else
 
3537
      shift_width = bytes_per_sample + 1;
 
3538
    }
 
3539
 
 
3540
  if ((dump->outfile != NULL) && (dump->level == 4))
 
3541
    {
 
3542
    dump_info  (dump->outfile, dump->format, "extractContigSamplesToTileBuffer", 
 
3543
                "Sample %d, %d rows", sample + 1, rows + 1);
 
3544
    }
 
3545
 
 
3546
  src_rowsize = ((bps * spp * imagewidth) + 7) / 8;
 
3547
  dst_rowsize = ((bps * tilewidth * count) + 7) / 8;
 
3548
 
 
3549
  for (row = 0; row < rows; row++)
 
3550
    {
 
3551
    src_offset = row * src_rowsize;
 
3552
    dst_offset = row * dst_rowsize;
 
3553
    src = in + src_offset;
 
3554
    dst = out + dst_offset;
 
3555
 
 
3556
    /* pack the data into the scanline */
 
3557
    switch (shift_width)
 
3558
      {  
 
3559
      case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
 
3560
                                             spp, bps,  count, 0, cols))  
 
3561
                return (1);
 
3562
              break;
 
3563
      case 1: if (bps == 1)
 
3564
                {
 
3565
                if (extractContigSamples8bits (src, dst, cols, sample,
 
3566
                                               spp, bps, count, 0, cols))
 
3567
                  return (1);
 
3568
                break;
 
3569
                }
 
3570
              else
 
3571
                 if (extractContigSamples16bits (src, dst, cols, sample,
 
3572
                                                 spp, bps, count, 0, cols))
 
3573
                 return (1);
 
3574
              break;
 
3575
      case 2: if (extractContigSamples24bits (src, dst, cols, sample,
 
3576
                                              spp, bps,  count, 0, cols))
 
3577
                 return (1);
 
3578
              break;
 
3579
      case 3:
 
3580
      case 4: 
 
3581
      case 5: if (extractContigSamples32bits (src, dst, cols, sample,
 
3582
                                              spp, bps,  count, 0, cols))
 
3583
                 return (1);
 
3584
              break;
 
3585
      default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps);
 
3586
               return (1);
 
3587
      }
 
3588
    if ((dump->outfile != NULL) && (dump->level == 4))
 
3589
      dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
 
3590
    }
 
3591
 
 
3592
  return (0);
 
3593
  } /* end extractContigSamplesToTileBuffer */
 
3594
 
 
3595
static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
 
3596
  {
 
3597
  uint8* bufp = buf;
 
3598
  int32  bytes_read = 0;
 
3599
  uint16 strip, nstrips   = TIFFNumberOfStrips(in);
 
3600
  uint32 stripsize = TIFFStripSize(in);
 
3601
  uint32 rows = 0;
 
3602
  uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
 
3603
  tsize_t scanline_size = TIFFScanlineSize(in);
 
3604
 
 
3605
  for (strip = 0; strip < nstrips; strip++)
 
3606
    {
 
3607
    bytes_read = TIFFReadEncodedStrip (in, strip, bufp, -1);
 
3608
    rows = bytes_read / scanline_size;
 
3609
    if ((strip < (nstrips - 1)) && (bytes_read != (int32)stripsize))
 
3610
      TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
 
3611
                (int)strip + 1, (unsigned long) bytes_read, (unsigned long)stripsize);
 
3612
 
 
3613
    if (bytes_read < 0 && !ignore)
 
3614
      {
 
3615
      TIFFError("", "Error reading strip %lu after %lu rows",
 
3616
                (unsigned long) strip, (unsigned long)rows);
 
3617
      return 0;
 
3618
      }
 
3619
    bufp += bytes_read;
 
3620
    }
 
3621
 
 
3622
 return 1;
 
3623
  } /* end readContigStripsIntoBuffer */
 
3624
 
 
3625
static int 
 
3626
combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
 
3627
                             uint32 cols, uint32 rows, uint16 spp, uint16 bps,
 
3628
                             FILE *dumpfile, int format, int level)
 
3629
  {
 
3630
  int i, bytes_per_sample;
 
3631
  uint32 row, col, col_offset, src_rowsize, dst_rowsize, row_offset;
 
3632
  unsigned char *src;
 
3633
  unsigned char *dst;
 
3634
  tsample_t s;
 
3635
 
 
3636
  src = srcbuffs[0];
 
3637
  dst = out;
 
3638
  if ((src == NULL) || (dst == NULL))
 
3639
    {
 
3640
    TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
 
3641
    return (1);
 
3642
    }
 
3643
 
 
3644
  bytes_per_sample = (bps + 7) / 8; 
 
3645
 
 
3646
  src_rowsize = ((bps * cols) + 7) / 8;
 
3647
  dst_rowsize = ((bps * spp * cols) + 7) / 8;
 
3648
  for (row = 0; row < rows; row++)
 
3649
    {
 
3650
    if ((dumpfile != NULL) && (level == 2))
 
3651
      {
 
3652
      for (s = 0; s < spp; s++)
 
3653
        {
 
3654
        dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
 
3655
        dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
 
3656
        }
 
3657
      }
 
3658
    dst = out + (row * dst_rowsize);
 
3659
    row_offset = row * src_rowsize;
 
3660
    for (col = 0; col < cols; col++)
 
3661
      {
 
3662
      col_offset = row_offset + (col * (bps / 8)); 
 
3663
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
3664
        {
 
3665
        src = srcbuffs[s] + col_offset; 
 
3666
        for (i = 0; i < bytes_per_sample; i++)
 
3667
          *(dst + i) = *(src + i);
 
3668
        src += bytes_per_sample;
 
3669
        dst += bytes_per_sample;
 
3670
        }   
 
3671
      }
 
3672
 
 
3673
    if ((dumpfile != NULL) && (level == 2))
 
3674
      {
 
3675
      dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
 
3676
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
3677
      }
 
3678
    }
 
3679
 
 
3680
  return (0);
 
3681
  } /* end combineSeparateSamplesBytes */
 
3682
 
 
3683
static int
 
3684
combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
 
3685
                            uint32 rows, uint16 spp, uint16 bps, 
 
3686
                            FILE *dumpfile, int format, int level)
 
3687
  {
 
3688
  int    ready_bits = 0;
 
3689
  int    bytes_per_sample = 0;
 
3690
  uint32 src_rowsize, dst_rowsize, src_offset; 
 
3691
  uint32 bit_offset;
 
3692
  uint32 row, col, src_byte = 0, src_bit = 0;
 
3693
  uint8  maskbits = 0, matchbits = 0;
 
3694
  uint8  buff1 = 0, buff2 = 0;
 
3695
  tsample_t s;
 
3696
  unsigned char *src = in[0];
 
3697
  unsigned char *dst = out;
 
3698
  char           action[32];
 
3699
 
 
3700
  if ((src == NULL) || (dst == NULL))
 
3701
    {
 
3702
    TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
 
3703
    return (1);
 
3704
    }
 
3705
 
 
3706
  bytes_per_sample = (bps + 7) / 8; 
 
3707
  src_rowsize = ((bps * cols) + 7) / 8;
 
3708
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
3709
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
3710
 
 
3711
  for (row = 0; row < rows; row++)
 
3712
    {
 
3713
    ready_bits = 0;
 
3714
    buff1 = buff2 = 0;
 
3715
    dst = out + (row * dst_rowsize);
 
3716
    src_offset = row * src_rowsize;
 
3717
    for (col = 0; col < cols; col++)
 
3718
      {
 
3719
      /* Compute src byte(s) and bits within byte(s) */
 
3720
      bit_offset = col * bps;
 
3721
      src_byte = bit_offset / 8;
 
3722
      src_bit  = bit_offset % 8;
 
3723
 
 
3724
      matchbits = maskbits << (8 - src_bit - bps); 
 
3725
      /* load up next sample from each plane */
 
3726
      for (s = 0; s < spp; s++)
 
3727
        {
 
3728
        src = in[s] + src_offset + src_byte;
 
3729
        buff1 = ((*src) & matchbits) << (src_bit);
 
3730
 
 
3731
        /* If we have a full buffer's worth, write it out */
 
3732
        if (ready_bits >= 8)
 
3733
          {
 
3734
          *dst++ = buff2;
 
3735
          buff2 = buff1;
 
3736
          ready_bits -= 8;
 
3737
          strcpy (action, "Flush");
 
3738
          }
 
3739
        else
 
3740
          {
 
3741
          buff2 = (buff2 | (buff1 >> ready_bits));
 
3742
          strcpy (action, "Update");
 
3743
          }
 
3744
        ready_bits += bps;
 
3745
 
 
3746
        if ((dumpfile != NULL) && (level == 3))
 
3747
          {
 
3748
          dump_info (dumpfile, format, "",
 
3749
                   "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3750
                   row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
3751
          dump_byte (dumpfile, format, "Match bits", matchbits);
 
3752
          dump_byte (dumpfile, format, "Src   bits", *src);
 
3753
          dump_byte (dumpfile, format, "Buff1 bits", buff1);
 
3754
          dump_byte (dumpfile, format, "Buff2 bits", buff2);
 
3755
          dump_info (dumpfile, format, "","%s", action); 
 
3756
          }
 
3757
        }
 
3758
      }
 
3759
 
 
3760
    if (ready_bits > 0)
 
3761
      {
 
3762
      buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
3763
      *dst++ = buff1;
 
3764
      if ((dumpfile != NULL) && (level == 3))
 
3765
        {
 
3766
        dump_info (dumpfile, format, "",
 
3767
                 "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3768
                 row + 1, col + 1, src_byte, src_bit, dst - out);
 
3769
                 dump_byte (dumpfile, format, "Final bits", buff1);
 
3770
        }
 
3771
      }
 
3772
 
 
3773
    if ((dumpfile != NULL) && (level >= 2))
 
3774
      {
 
3775
      dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
 
3776
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
3777
      }
 
3778
    }
 
3779
 
 
3780
  return (0);
 
3781
  } /* end combineSeparateSamples8bits */
 
3782
 
 
3783
static int
 
3784
combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
 
3785
                              uint32 rows, uint16 spp, uint16 bps, 
 
3786
                              FILE *dumpfile, int format, int level)
 
3787
  {
 
3788
  int    ready_bits = 0, bytes_per_sample = 0;
 
3789
  uint32 src_rowsize, dst_rowsize; 
 
3790
  uint32 bit_offset, src_offset;
 
3791
  uint32 row, col, src_byte = 0, src_bit = 0;
 
3792
  uint16 maskbits = 0, matchbits = 0;
 
3793
  uint16 buff1 = 0, buff2 = 0;
 
3794
  uint8  bytebuff = 0;
 
3795
  tsample_t s;
 
3796
  unsigned char *src = in[0];
 
3797
  unsigned char *dst = out;
 
3798
  char           action[8];
 
3799
 
 
3800
  if ((src == NULL) || (dst == NULL))
 
3801
    {
 
3802
    TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
 
3803
    return (1);
 
3804
    }
 
3805
 
 
3806
  bytes_per_sample = (bps + 7) / 8; 
 
3807
  src_rowsize = ((bps * cols) + 7) / 8;
 
3808
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
3809
  maskbits = (uint16)-1 >> (16 - bps);
 
3810
 
 
3811
  for (row = 0; row < rows; row++)
 
3812
    {
 
3813
    ready_bits = 0;
 
3814
    buff1 = buff2 = 0;
 
3815
    dst = out + (row * dst_rowsize);
 
3816
    src_offset = row * src_rowsize;
 
3817
    for (col = 0; col < cols; col++)
 
3818
      {
 
3819
      /* Compute src byte(s) and bits within byte(s) */
 
3820
      bit_offset = col * bps;
 
3821
      src_byte = bit_offset / 8;
 
3822
      src_bit  = bit_offset % 8;
 
3823
 
 
3824
      matchbits = maskbits << (16 - src_bit - bps); 
 
3825
      for (s = 0; s < spp; s++)
 
3826
        {
 
3827
        src = in[s] + src_offset + src_byte;
 
3828
        if (little_endian)
 
3829
          buff1 = (src[0] << 8) | src[1];
 
3830
        else
 
3831
          buff1 = (src[1] << 8) | src[0];
 
3832
 
 
3833
        buff1 = (buff1 & matchbits) << (src_bit);
 
3834
 
 
3835
        /* If we have a full buffer's worth, write it out */
 
3836
        if (ready_bits >= 8)
 
3837
          {
 
3838
            bytebuff = (buff2 >> 8);
 
3839
            *dst++ = bytebuff;
 
3840
            ready_bits -= 8;
 
3841
            /* shift in new bits */
 
3842
            buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
3843
            strcpy (action, "Flush");
 
3844
          }
 
3845
        else
 
3846
          { /* add another bps bits to the buffer */
 
3847
            bytebuff = 0;
 
3848
            buff2 = (buff2 | (buff1 >> ready_bits));
 
3849
            strcpy (action, "Update");
 
3850
          }
 
3851
        ready_bits += bps;
 
3852
 
 
3853
        if ((dumpfile != NULL) && (level == 3))
 
3854
          {
 
3855
          dump_info (dumpfile, format, "",
 
3856
                       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3857
                       row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
3858
 
 
3859
          dump_short (dumpfile, format, "Match bits", matchbits);
 
3860
          dump_data  (dumpfile, format, "Src   bits", src, 2);
 
3861
          dump_short (dumpfile, format, "Buff1 bits", buff1);
 
3862
          dump_short (dumpfile, format, "Buff2 bits", buff2);
 
3863
          dump_byte  (dumpfile, format, "Write byte", bytebuff);
 
3864
          dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
 
3865
          }
 
3866
        }
 
3867
      }
 
3868
 
 
3869
    /* catch any trailing bits at the end of the line */
 
3870
    if (ready_bits > 0)
 
3871
      {
 
3872
      bytebuff = (buff2 >> 8);
 
3873
      *dst++ = bytebuff;
 
3874
      if ((dumpfile != NULL) && (level == 3))
 
3875
        {
 
3876
        dump_info (dumpfile, format, "",
 
3877
                       "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3878
                       row + 1, col + 1, src_byte, src_bit, dst - out);
 
3879
        dump_byte (dumpfile, format, "Final bits", bytebuff);
 
3880
        }
 
3881
      }
 
3882
 
 
3883
    if ((dumpfile != NULL) && (level == 2))
 
3884
      {
 
3885
      dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
 
3886
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
3887
      }
 
3888
    }
 
3889
 
 
3890
  return (0);
 
3891
  } /* end combineSeparateSamples16bits */
 
3892
 
 
3893
static int
 
3894
combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
 
3895
                              uint32 rows, uint16 spp, uint16 bps, 
 
3896
                              FILE *dumpfile, int format, int level)
 
3897
  {
 
3898
  int    ready_bits = 0, bytes_per_sample = 0;
 
3899
  uint32 src_rowsize, dst_rowsize; 
 
3900
  uint32 bit_offset, src_offset;
 
3901
  uint32 row, col, src_byte = 0, src_bit = 0;
 
3902
  uint32 maskbits = 0, matchbits = 0;
 
3903
  uint32 buff1 = 0, buff2 = 0;
 
3904
  uint8  bytebuff1 = 0, bytebuff2 = 0;
 
3905
  tsample_t s;
 
3906
  unsigned char *src = in[0];
 
3907
  unsigned char *dst = out;
 
3908
  char           action[8];
 
3909
 
 
3910
  if ((src == NULL) || (dst == NULL))
 
3911
    {
 
3912
    TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
 
3913
    return (1);
 
3914
    }
 
3915
 
 
3916
  bytes_per_sample = (bps + 7) / 8; 
 
3917
  src_rowsize = ((bps * cols) + 7) / 8;
 
3918
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
3919
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
3920
 
 
3921
  for (row = 0; row < rows; row++)
 
3922
    {
 
3923
    ready_bits = 0;
 
3924
    buff1 = buff2 = 0;
 
3925
    dst = out + (row * dst_rowsize);
 
3926
    src_offset = row * src_rowsize;
 
3927
    for (col = 0; col < cols; col++)
 
3928
      {
 
3929
      /* Compute src byte(s) and bits within byte(s) */
 
3930
      bit_offset = col * bps;
 
3931
      src_byte = bit_offset / 8;
 
3932
      src_bit  = bit_offset % 8;
 
3933
 
 
3934
      matchbits = maskbits << (32 - src_bit - bps); 
 
3935
      for (s = 0; s < spp; s++)
 
3936
        {
 
3937
        src = in[s] + src_offset + src_byte;
 
3938
        if (little_endian)
 
3939
          buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
3940
        else
 
3941
          buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
3942
        buff1 = (buff1 & matchbits) << (src_bit);
 
3943
 
 
3944
        /* If we have a full buffer's worth, write it out */
 
3945
        if (ready_bits >= 16)
 
3946
          {
 
3947
            bytebuff1 = (buff2 >> 24);
 
3948
            *dst++ = bytebuff1;
 
3949
            bytebuff2 = (buff2 >> 16);
 
3950
            *dst++ = bytebuff2;
 
3951
            ready_bits -= 16;
 
3952
 
 
3953
            /* shift in new bits */
 
3954
            buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
3955
            strcpy (action, "Flush");
 
3956
          }
 
3957
        else
 
3958
          { /* add another bps bits to the buffer */
 
3959
            bytebuff1 = bytebuff2 = 0;
 
3960
            buff2 = (buff2 | (buff1 >> ready_bits));
 
3961
            strcpy (action, "Update");
 
3962
          }
 
3963
        ready_bits += bps;
 
3964
 
 
3965
        if ((dumpfile != NULL) && (level == 3))
 
3966
          {
 
3967
          dump_info (dumpfile, format, "",
 
3968
                       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3969
                       row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
3970
          dump_long (dumpfile, format, "Match bits ", matchbits);
 
3971
          dump_data (dumpfile, format, "Src   bits ", src, 4);
 
3972
          dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
3973
          dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
3974
          dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
3975
          dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
3976
          dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
 
3977
          }
 
3978
        }
 
3979
      }
 
3980
 
 
3981
    /* catch any trailing bits at the end of the line */
 
3982
    while (ready_bits > 0)
 
3983
      {
 
3984
        bytebuff1 = (buff2 >> 24);
 
3985
        *dst++ = bytebuff1;
 
3986
 
 
3987
        buff2 = (buff2 << 8);
 
3988
        bytebuff2 = bytebuff1;
 
3989
        ready_bits -= 8;
 
3990
      }
 
3991
 
 
3992
    if ((dumpfile != NULL) && (level == 3))
 
3993
      {
 
3994
      dump_info (dumpfile, format, "",
 
3995
                   "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
3996
                   row + 1, col + 1, src_byte, src_bit, dst - out);
 
3997
 
 
3998
      dump_long (dumpfile, format, "Match bits ", matchbits);
 
3999
      dump_data (dumpfile, format, "Src   bits ", src, 4);
 
4000
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
4001
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
4002
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
4003
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
4004
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
 
4005
      }
 
4006
 
 
4007
    if ((dumpfile != NULL) && (level == 2))
 
4008
      {
 
4009
      dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
 
4010
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
4011
      }
 
4012
    }
 
4013
  
 
4014
  return (0);
 
4015
  } /* end combineSeparateSamples24bits */
 
4016
 
 
4017
static int
 
4018
combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
 
4019
                              uint32 rows, uint16 spp, uint16 bps, 
 
4020
                              FILE *dumpfile, int format, int level)
 
4021
  {
 
4022
  int    ready_bits = 0, bytes_per_sample = 0, shift_width = 0;
 
4023
  uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
 
4024
  uint32 src_byte = 0, src_bit = 0;
 
4025
  uint32 row, col;
 
4026
  uint32 longbuff1 = 0, longbuff2 = 0;
 
4027
  uint64 maskbits = 0, matchbits = 0;
 
4028
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
4029
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
4030
  tsample_t s;
 
4031
  unsigned char *src = in[0];
 
4032
  unsigned char *dst = out;
 
4033
  char           action[8];
 
4034
 
 
4035
  if ((src == NULL) || (dst == NULL))
 
4036
    {
 
4037
    TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
 
4038
    return (1);
 
4039
    }
 
4040
 
 
4041
  bytes_per_sample = (bps + 7) / 8; 
 
4042
  src_rowsize = ((bps * cols) + 7) / 8;
 
4043
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
 
4044
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
4045
  shift_width = ((bps + 7) / 8) + 1; 
 
4046
 
 
4047
  for (row = 0; row < rows; row++)
 
4048
    {
 
4049
    ready_bits = 0;
 
4050
    buff1 = buff2 = 0;
 
4051
    dst = out + (row * dst_rowsize);
 
4052
    src_offset = row * src_rowsize;
 
4053
    for (col = 0; col < cols; col++)
 
4054
      {
 
4055
      /* Compute src byte(s) and bits within byte(s) */
 
4056
      bit_offset = col * bps;
 
4057
      src_byte = bit_offset / 8;
 
4058
      src_bit  = bit_offset % 8;
 
4059
 
 
4060
      matchbits = maskbits << (64 - src_bit - bps); 
 
4061
      for (s = 0; s < spp; s++)
 
4062
        {
 
4063
        src = in[s] + src_offset + src_byte;
 
4064
        if (little_endian)
 
4065
          {
 
4066
          longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
4067
          longbuff2 = longbuff1;
 
4068
          }
 
4069
        else
 
4070
          {
 
4071
          longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
4072
          longbuff2 = longbuff1;
 
4073
          }
 
4074
        buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
4075
        buff1 = (buff3 & matchbits) << (src_bit);
 
4076
 
 
4077
        /* If we have a full buffer's worth, write it out */
 
4078
        if (ready_bits >= 32)
 
4079
          {
 
4080
          bytebuff1 = (buff2 >> 56);
 
4081
          *dst++ = bytebuff1;
 
4082
          bytebuff2 = (buff2 >> 48);
 
4083
          *dst++ = bytebuff2;
 
4084
          bytebuff3 = (buff2 >> 40);
 
4085
          *dst++ = bytebuff3;
 
4086
          bytebuff4 = (buff2 >> 32);
 
4087
          *dst++ = bytebuff4;
 
4088
          ready_bits -= 32;
 
4089
                    
 
4090
          /* shift in new bits */
 
4091
          buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
4092
          strcpy (action, "Flush");
 
4093
          }
 
4094
        else
 
4095
          { /* add another bps bits to the buffer */
 
4096
          bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
4097
          buff2 = (buff2 | (buff1 >> ready_bits));
 
4098
          strcpy (action, "Update");
 
4099
          }
 
4100
        ready_bits += bps;
 
4101
 
 
4102
        if ((dumpfile != NULL) && (level == 3))
 
4103
          { 
 
4104
          dump_info (dumpfile, format, "",
 
4105
                     "Row %3d, Col %3d, Sample %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4106
                     row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
4107
          dump_wide (dumpfile, format, "Match bits ", matchbits);
 
4108
          dump_data (dumpfile, format, "Src   bits ", src, 8);
 
4109
          dump_wide (dumpfile, format, "Buff1 bits ", buff1);
 
4110
          dump_wide (dumpfile, format, "Buff2 bits ", buff2);
 
4111
          dump_info (dumpfile, format, "", "Ready bits:   %d, %s", ready_bits, action); 
 
4112
          }
 
4113
        }
 
4114
      }
 
4115
    while (ready_bits > 0)
 
4116
      {
 
4117
      bytebuff1 = (buff2 >> 56);
 
4118
      *dst++ = bytebuff1;
 
4119
      buff2 = (buff2 << 8);
 
4120
      ready_bits -= 8;
 
4121
      }
 
4122
 
 
4123
    if ((dumpfile != NULL) && (level == 3))
 
4124
      {
 
4125
      dump_info (dumpfile, format, "",
 
4126
                 "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4127
                 row + 1, col + 1, src_byte, src_bit, dst - out);
 
4128
 
 
4129
      dump_long (dumpfile, format, "Match bits ", matchbits);
 
4130
      dump_data (dumpfile, format, "Src   bits ", src, 4);
 
4131
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
4132
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
4133
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
4134
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
4135
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
 
4136
      }
 
4137
 
 
4138
    if ((dumpfile != NULL) && (level == 2))
 
4139
      {
 
4140
      dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
 
4141
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
4142
      }
 
4143
    }
 
4144
  
 
4145
  return (0);
 
4146
  } /* end combineSeparateSamples32bits */
 
4147
 
 
4148
static int 
 
4149
combineSeparateTileSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
 
4150
                                 uint32 cols, uint32 rows, uint32 imagewidth,
 
4151
                                 uint32 tw, uint16 spp, uint16 bps,
 
4152
                                 FILE *dumpfile, int format, int level)
 
4153
  {
 
4154
  int i, bytes_per_sample;
 
4155
  uint32 row, col, col_offset, src_rowsize, dst_rowsize, src_offset;
 
4156
  unsigned char *src;
 
4157
  unsigned char *dst;
 
4158
  tsample_t s;
 
4159
 
 
4160
  src = srcbuffs[0];
 
4161
  dst = out;
 
4162
  if ((src == NULL) || (dst == NULL))
 
4163
    {
 
4164
    TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
 
4165
    return (1);
 
4166
    }
 
4167
 
 
4168
  bytes_per_sample = (bps + 7) / 8; 
 
4169
  src_rowsize = ((bps * tw) + 7) / 8;
 
4170
  dst_rowsize = imagewidth * bytes_per_sample * spp;
 
4171
  for (row = 0; row < rows; row++)
 
4172
    {
 
4173
    if ((dumpfile != NULL) && (level == 2))
 
4174
      {
 
4175
      for (s = 0; s < spp; s++)
 
4176
        {
 
4177
        dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Input data, Sample %d", s);
 
4178
        dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
 
4179
        }
 
4180
      }
 
4181
    dst = out + (row * dst_rowsize);
 
4182
    src_offset = row * src_rowsize;
 
4183
#ifdef DEVELMODE
 
4184
    TIFFError("","Tile row %4d, Src offset %6d   Dst offset %6d", 
 
4185
              row, src_offset, dst - out);
 
4186
#endif
 
4187
    for (col = 0; col < cols; col++)
 
4188
      {
 
4189
      col_offset = src_offset + (col * (bps / 8)); 
 
4190
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
4191
        {
 
4192
        src = srcbuffs[s] + col_offset; 
 
4193
        for (i = 0; i < bytes_per_sample; i++)
 
4194
          *(dst + i) = *(src + i);
 
4195
        dst += bytes_per_sample;
 
4196
        }   
 
4197
      }
 
4198
 
 
4199
    if ((dumpfile != NULL) && (level == 2))
 
4200
      {
 
4201
      dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Output data, combined samples");
 
4202
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
4203
      }
 
4204
    }
 
4205
 
 
4206
  return (0);
 
4207
  } /* end combineSeparateTileSamplesBytes */
 
4208
 
 
4209
static int
 
4210
combineSeparateTileSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
 
4211
                                 uint32 rows, uint32 imagewidth, 
 
4212
                                 uint32 tw, uint16 spp, uint16 bps, 
 
4213
                                 FILE *dumpfile, int format, int level)
 
4214
  {
 
4215
  int    ready_bits = 0;
 
4216
  uint32 src_rowsize, dst_rowsize, src_offset; 
 
4217
  uint32 bit_offset;
 
4218
  uint32 row, col, src_byte = 0, src_bit = 0;
 
4219
  uint8  maskbits = 0, matchbits = 0;
 
4220
  uint8  buff1 = 0, buff2 = 0;
 
4221
  tsample_t s;
 
4222
  unsigned char *src = in[0];
 
4223
  unsigned char *dst = out;
 
4224
  char           action[32];
 
4225
 
 
4226
  if ((src == NULL) || (dst == NULL))
 
4227
    {
 
4228
    TIFFError("combineSeparateTileSamples8bits","Invalid input or output buffer");
 
4229
    return (1);
 
4230
    }
 
4231
 
 
4232
  src_rowsize = ((bps * tw) + 7) / 8;
 
4233
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
 
4234
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
4235
 
 
4236
  for (row = 0; row < rows; row++)
 
4237
    {
 
4238
    ready_bits = 0;
 
4239
    buff1 = buff2 = 0;
 
4240
    dst = out + (row * dst_rowsize);
 
4241
    src_offset = row * src_rowsize;
 
4242
    for (col = 0; col < cols; col++)
 
4243
      {
 
4244
      /* Compute src byte(s) and bits within byte(s) */
 
4245
      bit_offset = col * bps;
 
4246
      src_byte = bit_offset / 8;
 
4247
      src_bit  = bit_offset % 8;
 
4248
 
 
4249
      matchbits = maskbits << (8 - src_bit - bps); 
 
4250
      /* load up next sample from each plane */
 
4251
      for (s = 0; s < spp; s++)
 
4252
        {
 
4253
        src = in[s] + src_offset + src_byte;
 
4254
        buff1 = ((*src) & matchbits) << (src_bit);
 
4255
 
 
4256
        /* If we have a full buffer's worth, write it out */
 
4257
        if (ready_bits >= 8)
 
4258
          {
 
4259
          *dst++ = buff2;
 
4260
          buff2 = buff1;
 
4261
          ready_bits -= 8;
 
4262
          strcpy (action, "Flush");
 
4263
          }
 
4264
        else
 
4265
          {
 
4266
          buff2 = (buff2 | (buff1 >> ready_bits));
 
4267
          strcpy (action, "Update");
 
4268
          }
 
4269
        ready_bits += bps;
 
4270
 
 
4271
        if ((dumpfile != NULL) && (level == 3))
 
4272
          {
 
4273
          dump_info (dumpfile, format, "",
 
4274
                   "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4275
                   row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
4276
          dump_byte (dumpfile, format, "Match bits", matchbits);
 
4277
          dump_byte (dumpfile, format, "Src   bits", *src);
 
4278
          dump_byte (dumpfile, format, "Buff1 bits", buff1);
 
4279
          dump_byte (dumpfile, format, "Buff2 bits", buff2);
 
4280
          dump_info (dumpfile, format, "","%s", action); 
 
4281
          }
 
4282
        }
 
4283
      }
 
4284
 
 
4285
    if (ready_bits > 0)
 
4286
      {
 
4287
      buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
4288
      *dst++ = buff1;
 
4289
      if ((dumpfile != NULL) && (level == 3))
 
4290
        {
 
4291
        dump_info (dumpfile, format, "",
 
4292
                 "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4293
                 row + 1, col + 1, src_byte, src_bit, dst - out);
 
4294
                 dump_byte (dumpfile, format, "Final bits", buff1);
 
4295
        }
 
4296
      }
 
4297
 
 
4298
    if ((dumpfile != NULL) && (level >= 2))
 
4299
      {
 
4300
      dump_info (dumpfile, format, "combineSeparateTileSamples8bits","Output data");
 
4301
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
4302
      }
 
4303
    }
 
4304
 
 
4305
  return (0);
 
4306
  } /* end combineSeparateTileSamples8bits */
 
4307
 
 
4308
static int
 
4309
combineSeparateTileSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
 
4310
                                  uint32 rows, uint32 imagewidth, 
 
4311
                                  uint32 tw, uint16 spp, uint16 bps, 
 
4312
                                  FILE *dumpfile, int format, int level)
 
4313
  {
 
4314
  int    ready_bits = 0;
 
4315
  uint32 src_rowsize, dst_rowsize; 
 
4316
  uint32 bit_offset, src_offset;
 
4317
  uint32 row, col, src_byte = 0, src_bit = 0;
 
4318
  uint16 maskbits = 0, matchbits = 0;
 
4319
  uint16 buff1 = 0, buff2 = 0;
 
4320
  uint8  bytebuff = 0;
 
4321
  tsample_t s;
 
4322
  unsigned char *src = in[0];
 
4323
  unsigned char *dst = out;
 
4324
  char           action[8];
 
4325
 
 
4326
  if ((src == NULL) || (dst == NULL))
 
4327
    {
 
4328
    TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
 
4329
    return (1);
 
4330
    }
 
4331
 
 
4332
  src_rowsize = ((bps * tw) + 7) / 8;
 
4333
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
 
4334
  maskbits = (uint16)-1 >> (16 - bps);
 
4335
 
 
4336
  for (row = 0; row < rows; row++)
 
4337
    {
 
4338
    ready_bits = 0;
 
4339
    buff1 = buff2 = 0;
 
4340
    dst = out + (row * dst_rowsize);
 
4341
    src_offset = row * src_rowsize;
 
4342
    for (col = 0; col < cols; col++)
 
4343
      {
 
4344
      /* Compute src byte(s) and bits within byte(s) */
 
4345
      bit_offset = col * bps;
 
4346
      src_byte = bit_offset / 8;
 
4347
      src_bit  = bit_offset % 8;
 
4348
 
 
4349
      matchbits = maskbits << (16 - src_bit - bps); 
 
4350
      for (s = 0; s < spp; s++)
 
4351
        {
 
4352
        src = in[s] + src_offset + src_byte;
 
4353
        if (little_endian)
 
4354
          buff1 = (src[0] << 8) | src[1];
 
4355
        else
 
4356
          buff1 = (src[1] << 8) | src[0];
 
4357
        buff1 = (buff1 & matchbits) << (src_bit);
 
4358
 
 
4359
        /* If we have a full buffer's worth, write it out */
 
4360
        if (ready_bits >= 8)
 
4361
          {
 
4362
            bytebuff = (buff2 >> 8);
 
4363
            *dst++ = bytebuff;
 
4364
            ready_bits -= 8;
 
4365
            /* shift in new bits */
 
4366
            buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
4367
            strcpy (action, "Flush");
 
4368
          }
 
4369
        else
 
4370
          { /* add another bps bits to the buffer */
 
4371
            bytebuff = 0;
 
4372
            buff2 = (buff2 | (buff1 >> ready_bits));
 
4373
            strcpy (action, "Update");
 
4374
          }
 
4375
        ready_bits += bps;
 
4376
 
 
4377
        if ((dumpfile != NULL) && (level == 3))
 
4378
          {
 
4379
          dump_info (dumpfile, format, "",
 
4380
                       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4381
                       row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
4382
 
 
4383
          dump_short (dumpfile, format, "Match bits", matchbits);
 
4384
          dump_data  (dumpfile, format, "Src   bits", src, 2);
 
4385
          dump_short (dumpfile, format, "Buff1 bits", buff1);
 
4386
          dump_short (dumpfile, format, "Buff2 bits", buff2);
 
4387
          dump_byte  (dumpfile, format, "Write byte", bytebuff);
 
4388
          dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
 
4389
          }
 
4390
        }
 
4391
      }
 
4392
 
 
4393
    /* catch any trailing bits at the end of the line */
 
4394
    if (ready_bits > 0)
 
4395
      {
 
4396
      bytebuff = (buff2 >> 8);
 
4397
      *dst++ = bytebuff;
 
4398
      if ((dumpfile != NULL) && (level == 3))
 
4399
        {
 
4400
        dump_info (dumpfile, format, "",
 
4401
                       "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4402
                       row + 1, col + 1, src_byte, src_bit, dst - out);
 
4403
        dump_byte (dumpfile, format, "Final bits", bytebuff);
 
4404
        }
 
4405
      }
 
4406
 
 
4407
    if ((dumpfile != NULL) && (level == 2))
 
4408
      {
 
4409
      dump_info (dumpfile, format, "combineSeparateTileSamples16bits","Output data");
 
4410
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
4411
      }
 
4412
    }
 
4413
 
 
4414
  return (0);
 
4415
  } /* end combineSeparateTileSamples16bits */
 
4416
 
 
4417
static int
 
4418
combineSeparateTileSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
 
4419
                                  uint32 rows, uint32 imagewidth, 
 
4420
                                  uint32 tw, uint16 spp, uint16 bps, 
 
4421
                                  FILE *dumpfile, int format, int level)
 
4422
  {
 
4423
  int    ready_bits = 0;
 
4424
  uint32 src_rowsize, dst_rowsize; 
 
4425
  uint32 bit_offset, src_offset;
 
4426
  uint32 row, col, src_byte = 0, src_bit = 0;
 
4427
  uint32 maskbits = 0, matchbits = 0;
 
4428
  uint32 buff1 = 0, buff2 = 0;
 
4429
  uint8  bytebuff1 = 0, bytebuff2 = 0;
 
4430
  tsample_t s;
 
4431
  unsigned char *src = in[0];
 
4432
  unsigned char *dst = out;
 
4433
  char           action[8];
 
4434
 
 
4435
  if ((src == NULL) || (dst == NULL))
 
4436
    {
 
4437
    TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
 
4438
    return (1);
 
4439
    }
 
4440
 
 
4441
  src_rowsize = ((bps * tw) + 7) / 8;
 
4442
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
 
4443
  maskbits =  (uint32)-1 >> ( 32 - bps);
 
4444
 
 
4445
  for (row = 0; row < rows; row++)
 
4446
    {
 
4447
    ready_bits = 0;
 
4448
    buff1 = buff2 = 0;
 
4449
    dst = out + (row * dst_rowsize);
 
4450
    src_offset = row * src_rowsize;
 
4451
    for (col = 0; col < cols; col++)
 
4452
      {
 
4453
      /* Compute src byte(s) and bits within byte(s) */
 
4454
      bit_offset = col * bps;
 
4455
      src_byte = bit_offset / 8;
 
4456
      src_bit  = bit_offset % 8;
 
4457
 
 
4458
      matchbits = maskbits << (32 - src_bit - bps); 
 
4459
      for (s = 0; s < spp; s++)
 
4460
        {
 
4461
        src = in[s] + src_offset + src_byte;
 
4462
        if (little_endian)
 
4463
          buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
4464
        else
 
4465
          buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
4466
        buff1 = (buff1 & matchbits) << (src_bit);
 
4467
 
 
4468
        /* If we have a full buffer's worth, write it out */
 
4469
        if (ready_bits >= 16)
 
4470
          {
 
4471
            bytebuff1 = (buff2 >> 24);
 
4472
            *dst++ = bytebuff1;
 
4473
            bytebuff2 = (buff2 >> 16);
 
4474
            *dst++ = bytebuff2;
 
4475
            ready_bits -= 16;
 
4476
 
 
4477
            /* shift in new bits */
 
4478
            buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
4479
            strcpy (action, "Flush");
 
4480
          }
 
4481
        else
 
4482
          { /* add another bps bits to the buffer */
 
4483
            bytebuff1 = bytebuff2 = 0;
 
4484
            buff2 = (buff2 | (buff1 >> ready_bits));
 
4485
            strcpy (action, "Update");
 
4486
          }
 
4487
        ready_bits += bps;
 
4488
 
 
4489
        if ((dumpfile != NULL) && (level == 3))
 
4490
          {
 
4491
          dump_info (dumpfile, format, "",
 
4492
                       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4493
                       row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
4494
          dump_long (dumpfile, format, "Match bits ", matchbits);
 
4495
          dump_data (dumpfile, format, "Src   bits ", src, 4);
 
4496
          dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
4497
          dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
4498
          dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
4499
          dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
4500
          dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
 
4501
          }
 
4502
        }
 
4503
      }
 
4504
 
 
4505
    /* catch any trailing bits at the end of the line */
 
4506
    while (ready_bits > 0)
 
4507
      {
 
4508
        bytebuff1 = (buff2 >> 24);
 
4509
        *dst++ = bytebuff1;
 
4510
 
 
4511
        buff2 = (buff2 << 8);
 
4512
        bytebuff2 = bytebuff1;
 
4513
        ready_bits -= 8;
 
4514
      }
 
4515
 
 
4516
    if ((dumpfile != NULL) && (level == 3))
 
4517
      {
 
4518
      dump_info (dumpfile, format, "",
 
4519
                   "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4520
                   row + 1, col + 1, src_byte, src_bit, dst - out);
 
4521
 
 
4522
      dump_long (dumpfile, format, "Match bits ", matchbits);
 
4523
      dump_data (dumpfile, format, "Src   bits ", src, 4);
 
4524
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
4525
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
4526
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
4527
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
4528
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
 
4529
      }
 
4530
 
 
4531
    if ((dumpfile != NULL) && (level == 2))
 
4532
      {
 
4533
      dump_info (dumpfile, format, "combineSeparateTileSamples24bits","Output data");
 
4534
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
 
4535
      }
 
4536
    }
 
4537
  
 
4538
  return (0);
 
4539
  } /* end combineSeparateTileSamples24bits */
 
4540
 
 
4541
static int
 
4542
combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
 
4543
                                  uint32 rows, uint32 imagewidth, 
 
4544
                                  uint32 tw, uint16 spp, uint16 bps, 
 
4545
                                  FILE *dumpfile, int format, int level)
 
4546
  {
 
4547
  int    ready_bits = 0, shift_width = 0;
 
4548
  uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
 
4549
  uint32 src_byte = 0, src_bit = 0;
 
4550
  uint32 row, col;
 
4551
  uint32 longbuff1 = 0, longbuff2 = 0;
 
4552
  uint64 maskbits = 0, matchbits = 0;
 
4553
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
4554
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
4555
  tsample_t s;
 
4556
  unsigned char *src = in[0];
 
4557
  unsigned char *dst = out;
 
4558
  char           action[8];
 
4559
 
 
4560
  if ((src == NULL) || (dst == NULL))
 
4561
    {
 
4562
    TIFFError("combineSeparateTileSamples32bits","Invalid input or output buffer");
 
4563
    return (1);
 
4564
    }
 
4565
 
 
4566
  src_rowsize = ((bps * tw) + 7) / 8;
 
4567
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
 
4568
  maskbits =  (uint64)-1 >> ( 64 - bps);
 
4569
  shift_width = ((bps + 7) / 8) + 1; 
 
4570
 
 
4571
  for (row = 0; row < rows; row++)
 
4572
    {
 
4573
    ready_bits = 0;
 
4574
    buff1 = buff2 = 0;
 
4575
    dst = out + (row * dst_rowsize);
 
4576
    src_offset = row * src_rowsize;
 
4577
    for (col = 0; col < cols; col++)
 
4578
      {
 
4579
      /* Compute src byte(s) and bits within byte(s) */
 
4580
      bit_offset = col * bps;
 
4581
      src_byte = bit_offset / 8;
 
4582
      src_bit  = bit_offset % 8;
 
4583
 
 
4584
      matchbits = maskbits << (64 - src_bit - bps); 
 
4585
      for (s = 0; s < spp; s++)
 
4586
        {
 
4587
        src = in[s] + src_offset + src_byte;
 
4588
        if (little_endian)
 
4589
          {
 
4590
          longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
4591
          longbuff2 = longbuff1;
 
4592
          }
 
4593
        else
 
4594
          {
 
4595
          longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
4596
          longbuff2 = longbuff1;
 
4597
          }
 
4598
 
 
4599
        buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
4600
        buff1 = (buff3 & matchbits) << (src_bit);
 
4601
 
 
4602
        /* If we have a full buffer's worth, write it out */
 
4603
        if (ready_bits >= 32)
 
4604
          {
 
4605
          bytebuff1 = (buff2 >> 56);
 
4606
          *dst++ = bytebuff1;
 
4607
          bytebuff2 = (buff2 >> 48);
 
4608
          *dst++ = bytebuff2;
 
4609
          bytebuff3 = (buff2 >> 40);
 
4610
          *dst++ = bytebuff3;
 
4611
          bytebuff4 = (buff2 >> 32);
 
4612
          *dst++ = bytebuff4;
 
4613
          ready_bits -= 32;
 
4614
                    
 
4615
          /* shift in new bits */
 
4616
          buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
4617
          strcpy (action, "Flush");
 
4618
          }
 
4619
        else
 
4620
          { /* add another bps bits to the buffer */
 
4621
          bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
4622
          buff2 = (buff2 | (buff1 >> ready_bits));
 
4623
          strcpy (action, "Update");
 
4624
          }
 
4625
        ready_bits += bps;
 
4626
 
 
4627
        if ((dumpfile != NULL) && (level == 3))
 
4628
          { 
 
4629
          dump_info (dumpfile, format, "",
 
4630
                     "Row %3d, Col %3d, Sample %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4631
                     row + 1, col + 1, s, src_byte, src_bit, dst - out);
 
4632
          dump_wide (dumpfile, format, "Match bits ", matchbits);
 
4633
          dump_data (dumpfile, format, "Src   bits ", src, 8);
 
4634
          dump_wide (dumpfile, format, "Buff1 bits ", buff1);
 
4635
          dump_wide (dumpfile, format, "Buff2 bits ", buff2);
 
4636
          dump_info (dumpfile, format, "", "Ready bits:   %d, %s", ready_bits, action); 
 
4637
          }
 
4638
        }
 
4639
      }
 
4640
    while (ready_bits > 0)
 
4641
      {
 
4642
      bytebuff1 = (buff2 >> 56);
 
4643
      *dst++ = bytebuff1;
 
4644
      buff2 = (buff2 << 8);
 
4645
      ready_bits -= 8;
 
4646
      }
 
4647
 
 
4648
    if ((dumpfile != NULL) && (level == 3))
 
4649
      {
 
4650
      dump_info (dumpfile, format, "",
 
4651
                 "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
 
4652
                 row + 1, col + 1, src_byte, src_bit, dst - out);
 
4653
 
 
4654
      dump_long (dumpfile, format, "Match bits ", matchbits);
 
4655
      dump_data (dumpfile, format, "Src   bits ", src, 4);
 
4656
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
 
4657
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
 
4658
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
 
4659
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
 
4660
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
 
4661
      }
 
4662
 
 
4663
    if ((dumpfile != NULL) && (level == 2))
 
4664
      {
 
4665
      dump_info (dumpfile, format, "combineSeparateTileSamples32bits","Output data");
 
4666
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
 
4667
      }
 
4668
    }
 
4669
  
 
4670
  return (0);
 
4671
  } /* end combineSeparateTileSamples32bits */
 
4672
 
 
4673
 
 
4674
static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, 
 
4675
                                         uint32 width, uint16 spp,
 
4676
                                         struct dump_opts *dump)
 
4677
  {
 
4678
  int i, j, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
 
4679
  int32  bytes_read = 0;
 
4680
  uint16 bps, nstrips, planar, strips_per_sample;
 
4681
  uint32 src_rowsize, dst_rowsize, rows_processed, rps;
 
4682
  uint32 rows_this_strip = 0;
 
4683
  tsample_t s;
 
4684
  tstrip_t  strip;
 
4685
  tsize_t scanlinesize = TIFFScanlineSize(in);
 
4686
  tsize_t stripsize    = TIFFStripSize(in);
 
4687
  unsigned char *srcbuffs[MAX_SAMPLES];
 
4688
  unsigned char *buff = NULL;
 
4689
  unsigned char *dst = NULL;
 
4690
 
 
4691
  if (obuf == NULL)
 
4692
    {
 
4693
    TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
 
4694
    return (0);
 
4695
    }
 
4696
 
 
4697
  memset (srcbuffs, '\0', sizeof(srcbuffs));
 
4698
  TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
 
4699
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
 
4700
  TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
 
4701
  if (rps > length)
 
4702
    rps = length;
 
4703
 
 
4704
  bytes_per_sample = (bps + 7) / 8; 
 
4705
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
4706
  if (bytes_per_pixel < (bytes_per_sample + 1))
 
4707
    shift_width = bytes_per_pixel;
 
4708
  else
 
4709
    shift_width = bytes_per_sample + 1;
 
4710
 
 
4711
  src_rowsize = ((bps * width) + 7) / 8;
 
4712
  dst_rowsize = ((bps * width * spp) + 7) / 8;
 
4713
  dst = obuf;
 
4714
 
 
4715
  if ((dump->infile != NULL) && (dump->level == 3))
 
4716
    {
 
4717
    dump_info  (dump->infile, dump->format, "", 
 
4718
                "Image width %d, length %d, Scanline size, %4d bytes",
 
4719
                width, length,  scanlinesize);
 
4720
    dump_info  (dump->infile, dump->format, "", 
 
4721
                "Bits per sample %d, Samples per pixel %d, Shift width %d",
 
4722
                bps, spp, shift_width);
 
4723
    }
 
4724
 
 
4725
  /* Libtiff seems to assume/require that data for separate planes are 
 
4726
   * written one complete plane after another and not interleaved in any way.
 
4727
   * Multiple scanlines and possibly strips of the same plane must be 
 
4728
   * written before data for any other plane.
 
4729
   */
 
4730
  nstrips = TIFFNumberOfStrips(in);
 
4731
  strips_per_sample = nstrips /spp;
 
4732
 
 
4733
  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
4734
    {
 
4735
    srcbuffs[s] = NULL;
 
4736
    buff = _TIFFmalloc(stripsize);
 
4737
    if (!buff)
 
4738
      {
 
4739
      TIFFError ("readSeparateStripsIntoBuffer", 
 
4740
                 "Unable to allocate strip read buffer for sample %d", s);
 
4741
      for (i = 0; i < s; i++)
 
4742
        _TIFFfree (srcbuffs[i]);
 
4743
      return 0;
 
4744
      }
 
4745
    srcbuffs[s] = buff;
 
4746
    }
 
4747
 
 
4748
  rows_processed = 0;
 
4749
  for (j = 0; (j < strips_per_sample) && (result == 1); j++)
 
4750
    {
 
4751
    for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
4752
      {
 
4753
      buff = srcbuffs[s];
 
4754
      strip = (s * strips_per_sample) + j; 
 
4755
      bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
 
4756
      rows_this_strip = bytes_read / src_rowsize;
 
4757
      if (bytes_read < 0 && !ignore)
 
4758
        {
 
4759
        TIFFError(TIFFFileName(in),
 
4760
                  "Error, can't read strip %lu for sample %d",
 
4761
                   (unsigned long) strip, s + 1);
 
4762
        result = 0;
 
4763
        break;
 
4764
        }
 
4765
#ifdef DEVELMODE
 
4766
      TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d", 
 
4767
                strip, bytes_read, rows_this_strip, shift_width);
 
4768
#endif
 
4769
      }
 
4770
 
 
4771
    if (rps > rows_this_strip)
 
4772
      rps = rows_this_strip;
 
4773
    dst = obuf + (dst_rowsize * rows_processed);
 
4774
    if ((bps % 8) == 0)
 
4775
      {
 
4776
      if (combineSeparateSamplesBytes (srcbuffs, dst, width, rps,
 
4777
                                       spp, bps, dump->infile, 
 
4778
                                       dump->format, dump->level))
 
4779
        {
 
4780
        result = 0;
 
4781
        break;
 
4782
        }
 
4783
      }
 
4784
    else
 
4785
      {
 
4786
      switch (shift_width)
 
4787
        {
 
4788
        case 1: if (combineSeparateSamples8bits (srcbuffs, dst, width, rps,
 
4789
                                                 spp, bps, dump->infile,
 
4790
                                                 dump->format, dump->level))
 
4791
                  {
 
4792
                  result = 0;
 
4793
                  break;
 
4794
                  }
 
4795
                break;
 
4796
        case 2: if (combineSeparateSamples16bits (srcbuffs, dst, width, rps,
 
4797
                                                  spp, bps, dump->infile,
 
4798
                                                  dump->format, dump->level))
 
4799
                  {
 
4800
                  result = 0;
 
4801
                  break;
 
4802
                  }
 
4803
                break;
 
4804
        case 3: if (combineSeparateSamples24bits (srcbuffs, dst, width, rps,
 
4805
                                                  spp, bps, dump->infile,
 
4806
                                                  dump->format, dump->level))
 
4807
                  {
 
4808
                  result = 0;
 
4809
                  break;
 
4810
                  }
 
4811
                break;
 
4812
        case 4: 
 
4813
        case 5:
 
4814
        case 6:
 
4815
        case 7:
 
4816
        case 8: if (combineSeparateSamples32bits (srcbuffs, dst, width, rps,
 
4817
                                                  spp, bps, dump->infile,
 
4818
                                                  dump->format, dump->level))
 
4819
                  {
 
4820
                  result = 0;
 
4821
                  break;
 
4822
                  }
 
4823
                break;
 
4824
        default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
 
4825
                  result = 0;
 
4826
                  break;
 
4827
        }
 
4828
      }
 
4829
 
 
4830
    if ((rows_processed + rps) > length)
 
4831
      {
 
4832
      rows_processed = length;
 
4833
      rps = length - rows_processed;
 
4834
      }
 
4835
    else
 
4836
      rows_processed += rps;
 
4837
    }
 
4838
 
 
4839
  /* free any buffers allocated for each plane or scanline and 
 
4840
   * any temporary buffers 
 
4841
   */
 
4842
  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 
4843
    {
 
4844
    buff = srcbuffs[s];
 
4845
    if (buff != NULL)
 
4846
      _TIFFfree(buff);
 
4847
    }
 
4848
 
 
4849
  return (result);
 
4850
  } /* end readSeparateStripsIntoBuffer */
 
4851
 
 
4852
static int
 
4853
get_page_geometry (char *name, struct pagedef *page)
 
4854
    {
 
4855
    char *ptr;
 
4856
    int n; 
 
4857
 
 
4858
    for (ptr = name; *ptr; ptr++)
 
4859
      *ptr = (char)tolower((int)*ptr);
 
4860
 
 
4861
    for (n = 0; n < MAX_PAPERNAMES; n++)
 
4862
      {
 
4863
      if (strcmp(name, PaperTable[n].name) == 0)
 
4864
        {
 
4865
        page->width = PaperTable[n].width;
 
4866
        page->length = PaperTable[n].length;
 
4867
        strncpy (page->name, PaperTable[n].name, 15);
 
4868
        page->name[15] = '\0';
 
4869
        return (0);
 
4870
        }
 
4871
      }
 
4872
 
 
4873
  return (1);
 
4874
  }
 
4875
 
 
4876
 
 
4877
static void
 
4878
initPageSetup (struct pagedef *page, struct pageseg *pagelist, 
 
4879
               struct buffinfo seg_buffs[])
 
4880
   {
 
4881
   int i; 
 
4882
 
 
4883
   strcpy (page->name, "");
 
4884
   page->mode = PAGE_MODE_NONE;
 
4885
   page->res_unit = RESUNIT_NONE;
 
4886
   page->hres = 0.0;
 
4887
   page->vres = 0.0;
 
4888
   page->width = 0.0;
 
4889
   page->length = 0.0;
 
4890
   page->hmargin = 0.0;
 
4891
   page->vmargin = 0.0;
 
4892
   page->rows = 0;
 
4893
   page->cols = 0;
 
4894
   page->orient = ORIENTATION_NONE;
 
4895
 
 
4896
   for (i = 0; i < MAX_SECTIONS; i++)
 
4897
     {
 
4898
     pagelist[i].x1 = (uint32)0;
 
4899
     pagelist[i].x2 = (uint32)0;
 
4900
     pagelist[i].y1 = (uint32)0;
 
4901
     pagelist[i].y2 = (uint32)0;
 
4902
     pagelist[i].buffsize = (uint32)0;
 
4903
     pagelist[i].position = 0;
 
4904
     pagelist[i].total = 0;
 
4905
     }
 
4906
 
 
4907
   for (i = 0; i < MAX_OUTBUFFS; i++)
 
4908
     {
 
4909
     seg_buffs[i].size = 0;
 
4910
     seg_buffs[i].buffer = NULL;
 
4911
     }
 
4912
   }
 
4913
 
 
4914
static void
 
4915
initImageData (struct image_data *image)
 
4916
  {
 
4917
  image->xres = 0.0;
 
4918
  image->yres = 0.0;
 
4919
  image->width = 0;
 
4920
  image->length = 0;
 
4921
  image->res_unit = RESUNIT_NONE;
 
4922
  image->bps = 0;
 
4923
  image->spp = 0;
 
4924
  image->planar = 0;
 
4925
  image->photometric = 0;
 
4926
  image->orientation = 0;
 
4927
  image->compression = COMPRESSION_NONE;
 
4928
  image->adjustments = 0;
 
4929
  }
 
4930
 
 
4931
static void
 
4932
initCropMasks (struct crop_mask *cps)
 
4933
   {
 
4934
   int i;
 
4935
 
 
4936
   cps->crop_mode = CROP_NONE;
 
4937
   cps->res_unit  = RESUNIT_NONE;
 
4938
   cps->edge_ref  = EDGE_TOP;
 
4939
   cps->width = 0;
 
4940
   cps->length = 0;
 
4941
   for (i = 0; i < 4; i++)
 
4942
     cps->margins[i] = 0.0;
 
4943
   cps->bufftotal = (uint32)0;
 
4944
   cps->combined_width = (uint32)0;
 
4945
   cps->combined_length = (uint32)0;
 
4946
   cps->rotation = (uint16)0;
 
4947
   cps->photometric = INVERT_DATA_AND_TAG;
 
4948
   cps->mirror   = (uint16)0;
 
4949
   cps->invert   = (uint16)0;
 
4950
   cps->zones    = (uint32)0;
 
4951
   cps->regions  = (uint32)0;
 
4952
   for (i = 0; i < MAX_REGIONS; i++)
 
4953
     {
 
4954
     cps->corners[i].X1 = 0.0;
 
4955
     cps->corners[i].X2 = 0.0;
 
4956
     cps->corners[i].Y1 = 0.0;
 
4957
     cps->corners[i].Y2 = 0.0;
 
4958
     cps->regionlist[i].x1 = 0;
 
4959
     cps->regionlist[i].x2 = 0;
 
4960
     cps->regionlist[i].y1 = 0;
 
4961
     cps->regionlist[i].y2 = 0;
 
4962
     cps->regionlist[i].width = 0;
 
4963
     cps->regionlist[i].length = 0;
 
4964
     cps->regionlist[i].buffsize = 0;
 
4965
     cps->regionlist[i].buffptr = NULL;
 
4966
     cps->zonelist[i].position = 0;
 
4967
     cps->zonelist[i].total = 0;
 
4968
     }
 
4969
   cps->exp_mode = ONE_FILE_COMPOSITE;
 
4970
   cps->img_mode = COMPOSITE_IMAGES;
 
4971
   }
 
4972
 
 
4973
static void initDumpOptions(struct dump_opts *dump)
 
4974
  {
 
4975
  dump->debug  = 0;
 
4976
  dump->format = DUMP_NONE;
 
4977
  dump->level  = 1;
 
4978
  sprintf (dump->mode, "w");
 
4979
  memset (dump->infilename, '\0', PATH_MAX + 1);
 
4980
  memset (dump->outfilename, '\0',PATH_MAX + 1);
 
4981
  dump->infile = NULL;
 
4982
  dump->outfile = NULL;
 
4983
  }
 
4984
 
 
4985
/* Compute pixel offsets into the image for margins and fixed regions */
 
4986
static int
 
4987
computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
 
4988
                         struct offset *off)
 
4989
  {
 
4990
  double scale;
 
4991
  float xres, yres;
 
4992
  /* Values for these offsets are in pixels from start of image, not bytes,
 
4993
   * and are indexed from zero to width - 1 or length - 1 */
 
4994
  uint32 tmargin, bmargin, lmargin, rmargin;
 
4995
  uint32 startx, endx;   /* offsets of first and last columns to extract */
 
4996
  uint32 starty, endy;   /* offsets of first and last row to extract */
 
4997
  uint32 width, length, crop_width, crop_length; 
 
4998
  uint32 i, max_width, max_length, zwidth, zlength, buffsize;
 
4999
  uint32 x1, x2, y1, y2;
 
5000
 
 
5001
  if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
 
5002
    {
 
5003
    xres = 1.0;
 
5004
    yres = 1.0;
 
5005
    }
 
5006
  else
 
5007
    {
 
5008
    if (((image->xres == 0) || (image->yres == 0)) && 
 
5009
         (crop->res_unit != RESUNIT_NONE) &&
 
5010
        ((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
 
5011
         (crop->crop_mode & CROP_LENGTH)  || (crop->crop_mode & CROP_WIDTH)))
 
5012
      {
 
5013
      TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
 
5014
      TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
 
5015
      return (-1);
 
5016
      }
 
5017
    xres = image->xres;
 
5018
    yres = image->yres;
 
5019
    }
 
5020
 
 
5021
  /* Translate user units to image units */
 
5022
  scale = 1.0;
 
5023
  switch (crop->res_unit) {
 
5024
    case RESUNIT_CENTIMETER:
 
5025
         if (image->res_unit == RESUNIT_INCH)
 
5026
           scale = 1.0/2.54;
 
5027
         break;
 
5028
    case RESUNIT_INCH:
 
5029
         if (image->res_unit == RESUNIT_CENTIMETER)
 
5030
             scale = 2.54;
 
5031
         break;
 
5032
    case RESUNIT_NONE: /* Dimensions in pixels */
 
5033
    default:
 
5034
    break;
 
5035
    }
 
5036
 
 
5037
  if (crop->crop_mode & CROP_REGIONS)
 
5038
    {
 
5039
    max_width = max_length = 0;
 
5040
    for (i = 0; i < crop->regions; i++)
 
5041
      {
 
5042
      if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
 
5043
        {
 
5044
        x1 = (uint32) (crop->corners[i].X1 * scale * xres);
 
5045
        x2 = (uint32) (crop->corners[i].X2 * scale * xres);
 
5046
        y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
 
5047
        y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
 
5048
        }
 
5049
      else
 
5050
        {
 
5051
        x1 = (uint32) (crop->corners[i].X1);
 
5052
        x2 = (uint32) (crop->corners[i].X2);
 
5053
        y1 = (uint32) (crop->corners[i].Y1);
 
5054
        y2 = (uint32) (crop->corners[i].Y2);       
 
5055
        }
 
5056
      if (x1 < 1)
 
5057
        crop->regionlist[i].x1 = 0;
 
5058
      else
 
5059
        crop->regionlist[i].x1 = (uint32) (x1 - 1);
 
5060
 
 
5061
      if (x2 > image->width - 1)
 
5062
        crop->regionlist[i].x2 = image->width - 1;
 
5063
      else
 
5064
        crop->regionlist[i].x2 = (uint32) (x2 - 1);
 
5065
      zwidth  = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 
 
5066
 
 
5067
      if (y1 < 1)
 
5068
        crop->regionlist[i].y1 = 0;
 
5069
      else
 
5070
        crop->regionlist[i].y1 = (uint32) (y1 - 1);
 
5071
 
 
5072
      if (y2 > image->length - 1)
 
5073
        crop->regionlist[i].y2 = image->length - 1;
 
5074
      else
 
5075
        crop->regionlist[i].y2 = (uint32) (y2 - 1);
 
5076
 
 
5077
      zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 
 
5078
 
 
5079
      if (zwidth > max_width)
 
5080
        max_width = zwidth;
 
5081
      if (zlength > max_length)
 
5082
        max_length = zlength;
 
5083
 
 
5084
      buffsize = (uint32)
 
5085
          (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));
 
5086
 
 
5087
      crop->regionlist[i].buffsize = buffsize;
 
5088
      crop->bufftotal += buffsize;
 
5089
      if (crop->img_mode == COMPOSITE_IMAGES)
 
5090
        {
 
5091
        switch (crop->edge_ref)
 
5092
          {
 
5093
          case EDGE_LEFT:
 
5094
          case EDGE_RIGHT:
 
5095
               crop->combined_length = zlength;
 
5096
               crop->combined_width += zwidth;
 
5097
               break;
 
5098
          case EDGE_BOTTOM:
 
5099
          case EDGE_TOP:  /* width from left, length from top */
 
5100
          default:
 
5101
               crop->combined_width = zwidth;
 
5102
               crop->combined_length += zlength;
 
5103
               break;
 
5104
          }
 
5105
        }
 
5106
      }
 
5107
    return (0);
 
5108
    }
 
5109
  
 
5110
  /* Convert crop margins into offsets into image
 
5111
   * Margins are expressed as pixel rows and columns, not bytes
 
5112
   */
 
5113
  if (crop->crop_mode & CROP_MARGINS)
 
5114
    {
 
5115
    if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
 
5116
      { /* User has specified pixels as reference unit */
 
5117
      tmargin = (uint32)(crop->margins[0]);
 
5118
      lmargin = (uint32)(crop->margins[1]);
 
5119
      bmargin = (uint32)(crop->margins[2]);
 
5120
      rmargin = (uint32)(crop->margins[3]);
 
5121
      }
 
5122
    else
 
5123
      { /* inches or centimeters specified */
 
5124
      tmargin = (uint32)(crop->margins[0] * scale * yres);
 
5125
      lmargin = (uint32)(crop->margins[1] * scale * xres);
 
5126
      bmargin = (uint32)(crop->margins[2] * scale * yres);
 
5127
      rmargin = (uint32)(crop->margins[3] * scale * xres);
 
5128
      }
 
5129
 
 
5130
    if ((lmargin + rmargin) > image->width)
 
5131
      {
 
5132
      TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
 
5133
      lmargin = (uint32) 0;
 
5134
      rmargin = (uint32) 0;
 
5135
      return (-1);
 
5136
      }
 
5137
    if ((tmargin + bmargin) > image->length)
 
5138
      {
 
5139
      TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length"); 
 
5140
      tmargin = (uint32) 0; 
 
5141
      bmargin = (uint32) 0;
 
5142
      return (-1);
 
5143
      }
 
5144
    }
 
5145
  else
 
5146
    { /* no margins requested */
 
5147
    tmargin = (uint32) 0;
 
5148
    lmargin = (uint32) 0;
 
5149
    bmargin = (uint32) 0;
 
5150
    rmargin = (uint32) 0;
 
5151
    }
 
5152
 
 
5153
  /* Width, height, and margins are expressed as pixel offsets into image */
 
5154
  if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
 
5155
    {
 
5156
    if (crop->crop_mode & CROP_WIDTH)
 
5157
      width = (uint32)crop->width;
 
5158
    else
 
5159
      width = image->width - lmargin - rmargin;
 
5160
 
 
5161
    if (crop->crop_mode & CROP_LENGTH)
 
5162
      length  = (uint32)crop->length;
 
5163
    else
 
5164
      length = image->length - tmargin - bmargin;
 
5165
    }
 
5166
  else
 
5167
    {
 
5168
    if (crop->crop_mode & CROP_WIDTH)
 
5169
      width = (uint32)(crop->width * scale * image->xres);
 
5170
    else
 
5171
      width = image->width - lmargin - rmargin;
 
5172
 
 
5173
    if (crop->crop_mode & CROP_LENGTH)
 
5174
      length  = (uint32)(crop->length * scale * image->yres);
 
5175
    else
 
5176
      length = image->length - tmargin - bmargin;
 
5177
    }
 
5178
 
 
5179
  off->tmargin = tmargin;
 
5180
  off->bmargin = bmargin;
 
5181
  off->lmargin = lmargin;
 
5182
  off->rmargin = rmargin;
 
5183
 
 
5184
  /* Calculate regions defined by margins, width, and length. 
 
5185
   * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
 
5186
   * since they are used to compute offsets into buffers */
 
5187
  switch (crop->edge_ref) {
 
5188
    case EDGE_BOTTOM:
 
5189
         startx = lmargin;
 
5190
         if ((startx + width) >= (image->width - rmargin))
 
5191
           endx = image->width - rmargin - 1;
 
5192
         else
 
5193
           endx = startx + width - 1;
 
5194
 
 
5195
         endy = image->length - bmargin - 1;
 
5196
         if ((endy - length) <= tmargin)
 
5197
           starty = tmargin;
 
5198
         else
 
5199
           starty = endy - length + 1;
 
5200
         break;
 
5201
    case EDGE_RIGHT:
 
5202
         endx = image->width - rmargin - 1;
 
5203
         if ((endx - width) <= lmargin)
 
5204
           startx = lmargin;
 
5205
         else
 
5206
           startx = endx - width + 1;
 
5207
 
 
5208
         starty = tmargin;
 
5209
         if ((starty + length) >= (image->length - bmargin))
 
5210
           endy = image->length - bmargin - 1;
 
5211
         else
 
5212
           endy = starty + length - 1;
 
5213
         break;
 
5214
    case EDGE_TOP:  /* width from left, length from top */
 
5215
    case EDGE_LEFT:
 
5216
    default:
 
5217
         startx = lmargin;
 
5218
         if ((startx + width) >= (image->width - rmargin))
 
5219
           endx = image->width - rmargin - 1;
 
5220
         else
 
5221
           endx = startx + width - 1;
 
5222
 
 
5223
         starty = tmargin;
 
5224
         if ((starty + length) >= (image->length - bmargin))
 
5225
           endy = image->length - bmargin - 1;
 
5226
         else
 
5227
           endy = starty + length - 1;
 
5228
         break;
 
5229
    }
 
5230
  off->startx = startx;
 
5231
  off->starty = starty;
 
5232
  off->endx   = endx;
 
5233
  off->endy   = endy;
 
5234
 
 
5235
  crop_width  = endx - startx + 1;
 
5236
  crop_length = endy - starty + 1;
 
5237
 
 
5238
  if (crop_width <= 0)
 
5239
    {
 
5240
    TIFFError("computeInputPixelOffsets", 
 
5241
               "Invalid left/right margins and /or image crop width requested");
 
5242
    return (-1);
 
5243
    }
 
5244
  if (crop_width > image->width)
 
5245
    crop_width = image->width;
 
5246
 
 
5247
  if (crop_length <= 0)
 
5248
    {
 
5249
    TIFFError("computeInputPixelOffsets", 
 
5250
              "Invalid top/bottom margins and /or image crop length requested");
 
5251
    return (-1);
 
5252
    }
 
5253
  if (crop_length > image->length)
 
5254
    crop_length = image->length;
 
5255
 
 
5256
  off->crop_width = crop_width;
 
5257
  off->crop_length = crop_length;
 
5258
 
 
5259
  return (0);
 
5260
  } /* end computeInputPixelOffsets */
 
5261
 
 
5262
/* 
 
5263
 * Translate crop options into pixel offsets for one or more regions of the image.
 
5264
 * Options are applied in this order: margins, specific width and length, zones,
 
5265
 * but all are optional. Margins are relative to each edge. Width, length and
 
5266
 * zones are relative to the specified reference edge. Zones are expressed as
 
5267
 * X:Y where X is the ordinal value in a set of Y equal sized portions. eg.
 
5268
 * 2:3 would indicate the middle third of the region qualified by margins and
 
5269
 * any explicit width and length specified. Regions are specified by coordinates
 
5270
 * of the top left and lower right corners with range 1 to width or height.
 
5271
 */
 
5272
 
 
5273
static int
 
5274
getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
 
5275
  {
 
5276
  struct offset offsets;
 
5277
  int    i;
 
5278
  int32  test;
 
5279
  uint32 seg, total, need_buff = 0;
 
5280
  uint32 buffsize;
 
5281
  uint32 zwidth, zlength;
 
5282
 
 
5283
  memset(&offsets, '\0', sizeof(struct offset));
 
5284
  crop->bufftotal = 0;
 
5285
  crop->combined_width  = (uint32)0;
 
5286
  crop->combined_length = (uint32)0;
 
5287
  crop->selections = 0;
 
5288
 
 
5289
  /* Compute pixel offsets if margins or fixed width or length specified */
 
5290
  if ((crop->crop_mode & CROP_MARGINS) ||
 
5291
      (crop->crop_mode & CROP_REGIONS) ||
 
5292
      (crop->crop_mode & CROP_LENGTH)  || 
 
5293
      (crop->crop_mode & CROP_WIDTH))
 
5294
    {
 
5295
    if (computeInputPixelOffsets(crop, image, &offsets))
 
5296
      {
 
5297
      TIFFError ("getCropOffsets", "Unable to compute crop margins");
 
5298
      return (-1);
 
5299
      }
 
5300
    need_buff = TRUE;
 
5301
    crop->selections = crop->regions;
 
5302
    /* Regions are only calculated from top and left edges with no margins */
 
5303
    if (crop->crop_mode & CROP_REGIONS)
 
5304
      return (0);
 
5305
    }
 
5306
  else
 
5307
    { /* cropped area is the full image */
 
5308
    offsets.tmargin = 0;
 
5309
    offsets.lmargin = 0;
 
5310
    offsets.bmargin = 0;
 
5311
    offsets.rmargin = 0;
 
5312
    offsets.crop_width = image->width;
 
5313
    offsets.crop_length = image->length;
 
5314
    offsets.startx = 0;
 
5315
    offsets.endx = image->width - 1;
 
5316
    offsets.starty = 0;
 
5317
    offsets.endy = image->length - 1;
 
5318
    need_buff = FALSE;
 
5319
    }
 
5320
 
 
5321
  if (dump->outfile != NULL)
 
5322
    {
 
5323
    dump_info (dump->outfile, dump->format, "", "Margins: Top: %d  Left: %d  Bottom: %d  Right: %d", 
 
5324
           offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin); 
 
5325
    dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width:  %6d  Length: %6d", 
 
5326
           offsets.crop_width, offsets.crop_length);
 
5327
    }
 
5328
 
 
5329
  if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
 
5330
    {
 
5331
    if (need_buff == FALSE)  /* No margins or fixed width or length areas */
 
5332
      {
 
5333
      crop->selections = 0;
 
5334
      crop->combined_width  = image->width;
 
5335
      crop->combined_length = image->length;
 
5336
      return (0);
 
5337
      }
 
5338
    else 
 
5339
      {
 
5340
      /* Use one region for margins and fixed width or length areas
 
5341
       * even though it was not formally declared as a region.
 
5342
       */
 
5343
      crop->selections = 1;
 
5344
      crop->zones = 1;
 
5345
      crop->zonelist[0].total = 1;
 
5346
      crop->zonelist[0].position = 1;
 
5347
      }
 
5348
    }     
 
5349
  else
 
5350
    crop->selections = crop->zones;
 
5351
 
 
5352
  for (i = 0; i < crop->zones; i++)
 
5353
    {
 
5354
    seg = crop->zonelist[i].position;
 
5355
    total = crop->zonelist[i].total;
 
5356
 
 
5357
    switch (crop->edge_ref) 
 
5358
      {
 
5359
      case EDGE_LEFT: /* zones from left to right, length from top */
 
5360
           zlength = offsets.crop_length;
 
5361
           crop->regionlist[i].y1 = offsets.starty;
 
5362
           crop->regionlist[i].y2 = offsets.endy;
 
5363
 
 
5364
           crop->regionlist[i].x1 = offsets.startx + 
 
5365
                                  (uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
 
5366
           test = (int32)offsets.startx + 
 
5367
                  (int32)(offsets.crop_width * 1.0 * seg / total);
 
5368
           if (test < 1 )
 
5369
             crop->regionlist[i].x2 = 0;
 
5370
           else
 
5371
             {
 
5372
             if (test > (int32)(image->width - 1))
 
5373
               crop->regionlist[i].x2 = image->width - 1;
 
5374
             else
 
5375
               crop->regionlist[i].x2 = test - 1;
 
5376
             }
 
5377
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
 
5378
 
 
5379
           /* This is passed to extractCropZone or extractCompositeZones */
 
5380
           crop->combined_length = (uint32)zlength;
 
5381
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
5382
             crop->combined_width += (uint32)zwidth;
 
5383
           else
 
5384
             crop->combined_width = (uint32)zwidth;
 
5385
           break;
 
5386
      case EDGE_BOTTOM: /* width from left, zones from bottom to top */
 
5387
           zwidth = offsets.crop_width;
 
5388
           crop->regionlist[i].x1 = offsets.startx;
 
5389
           crop->regionlist[i].x2 = offsets.endx;
 
5390
 
 
5391
           test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
 
5392
           if (test < 1 )
 
5393
             crop->regionlist[i].y1 = 0;
 
5394
           else
 
5395
             crop->regionlist[i].y1 = test + 1;
 
5396
 
 
5397
           test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total);
 
5398
           if (test < 1 )
 
5399
             crop->regionlist[i].y2 = 0;
 
5400
           else
 
5401
             {
 
5402
             if (test > (int32)(image->length - 1))
 
5403
               crop->regionlist[i].y2 = image->length - 1;
 
5404
             else 
 
5405
               crop->regionlist[i].y2 = test;
 
5406
             }
 
5407
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
 
5408
 
 
5409
           /* This is passed to extractCropZone or extractCompositeZones */
 
5410
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
5411
             crop->combined_length += (uint32)zlength;
 
5412
           else
 
5413
             crop->combined_length = (uint32)zlength;
 
5414
           crop->combined_width = (uint32)zwidth;
 
5415
           break;
 
5416
      case EDGE_RIGHT: /* zones from right to left, length from top */
 
5417
           zlength = offsets.crop_length;
 
5418
           crop->regionlist[i].y1 = offsets.starty;
 
5419
           crop->regionlist[i].y2 = offsets.endy;
 
5420
 
 
5421
           crop->regionlist[i].x1 = offsets.startx +
 
5422
                                  (uint32)(offsets.crop_width  * (total - seg) * 1.0 / total);
 
5423
           test = offsets.startx + 
 
5424
                  (offsets.crop_width * (total - seg + 1) * 1.0 / total);
 
5425
           if (test < 1 )
 
5426
             crop->regionlist[i].x2 = 0;
 
5427
           else
 
5428
             {
 
5429
             if (test > (int32)(image->width - 1))
 
5430
               crop->regionlist[i].x2 = image->width - 1;
 
5431
             else
 
5432
               crop->regionlist[i].x2 = test - 1;
 
5433
             }
 
5434
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;
 
5435
 
 
5436
           /* This is passed to extractCropZone or extractCompositeZones */
 
5437
           crop->combined_length = (uint32)zlength;
 
5438
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
5439
             crop->combined_width += (uint32)zwidth;
 
5440
           else
 
5441
             crop->combined_width = (uint32)zwidth;
 
5442
           break;
 
5443
      case EDGE_TOP: /* width from left, zones from top to bottom */
 
5444
      default:
 
5445
           zwidth = offsets.crop_width;
 
5446
           crop->regionlist[i].x1 = offsets.startx;
 
5447
           crop->regionlist[i].x2 = offsets.endx;
 
5448
 
 
5449
           crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
 
5450
           test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
 
5451
           if (test < 1 )
 
5452
             crop->regionlist[i].y2 = 0;
 
5453
           else
 
5454
             {
 
5455
             if (test > (int32)(image->length - 1))
 
5456
               crop->regionlist[i].y2 = image->length - 1;
 
5457
             else
 
5458
               crop->regionlist[i].y2 = test - 1;
 
5459
             }
 
5460
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
 
5461
 
 
5462
           /* This is passed to extractCropZone or extractCompositeZones */
 
5463
           if (crop->exp_mode == COMPOSITE_IMAGES)
 
5464
             crop->combined_length += (uint32)zlength;
 
5465
           else
 
5466
             crop->combined_length = (uint32)zlength;
 
5467
           crop->combined_width = (uint32)zwidth;
 
5468
           break;
 
5469
      } /* end switch statement */
 
5470
 
 
5471
    buffsize = (uint32)
 
5472
          ((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
 
5473
    crop->regionlist[i].width = (uint32) zwidth;
 
5474
    crop->regionlist[i].length = (uint32) zlength;
 
5475
    crop->regionlist[i].buffsize = buffsize;
 
5476
    crop->bufftotal += buffsize;
 
5477
 
 
5478
 
 
5479
  if (dump->outfile != NULL)
 
5480
    dump_info (dump->outfile, dump->format, "",  "Zone %d, width: %4d, length: %4d, x1: %4d  x2: %4d  y1: %4d  y2: %4d",
 
5481
                    i + 1, (uint32)zwidth, (uint32)zlength,
 
5482
                    crop->regionlist[i].x1, crop->regionlist[i].x2, 
 
5483
                    crop->regionlist[i].y1, crop->regionlist[i].y2);
 
5484
    }
 
5485
 
 
5486
  return (0);
 
5487
  } /* end getCropOffsets */
 
5488
 
 
5489
 
 
5490
static int
 
5491
computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
 
5492
                           struct pagedef *page, struct pageseg *sections,
 
5493
                           struct dump_opts* dump)
 
5494
  {
 
5495
  double scale;
 
5496
  double pwidth, plength;          /* Output page width and length in user units*/
 
5497
  uint32 iwidth, ilength;          /* Input image width and length in pixels*/
 
5498
  uint32 owidth, olength;          /* Output image width and length in pixels*/
 
5499
  uint32 orows, ocols;             /* rows and cols for output */
 
5500
  uint32 hmargin, vmargin;         /* Horizontal and vertical margins */
 
5501
  uint32 x1, x2, y1, y2, line_bytes;
 
5502
  unsigned int orientation;
 
5503
  uint32 i, j, k;
 
5504
 
 
5505
  scale = 1.0;
 
5506
  if (page->res_unit == RESUNIT_NONE)
 
5507
    page->res_unit = image->res_unit;
 
5508
 
 
5509
  switch (image->res_unit) {
 
5510
    case RESUNIT_CENTIMETER:
 
5511
         if (page->res_unit == RESUNIT_INCH)
 
5512
           scale = 1.0/2.54;
 
5513
         break;
 
5514
    case RESUNIT_INCH:
 
5515
         if (page->res_unit == RESUNIT_CENTIMETER)
 
5516
             scale = 2.54;
 
5517
         break;
 
5518
    case RESUNIT_NONE: /* Dimensions in pixels */
 
5519
    default:
 
5520
    break;
 
5521
    }
 
5522
 
 
5523
  /* get width, height, resolutions of input image selection */
 
5524
  if (crop->combined_width > 0)
 
5525
    iwidth = crop->combined_width;
 
5526
  else
 
5527
    iwidth = image->width;
 
5528
  if (crop->combined_length > 0)
 
5529
    ilength = crop->combined_length;
 
5530
  else
 
5531
    ilength = image->length;
 
5532
 
 
5533
  if (page->hres <= 1.0)
 
5534
    page->hres = image->xres;
 
5535
  if (page->vres <= 1.0)
 
5536
    page->vres = image->yres;
 
5537
 
 
5538
  if ((page->hres < 1.0) || (page->vres < 1.0))
 
5539
    {
 
5540
    TIFFError("computeOutputPixelOffsets",
 
5541
    "Invalid horizontal or vertical resolution specified or read from input image");
 
5542
    return (1);
 
5543
    }
 
5544
 
 
5545
  /* If no page sizes are being specified, we just use the input image size to
 
5546
   * calculate maximum margins that can be taken from image.
 
5547
   */
 
5548
  if (page->width <= 0)
 
5549
    pwidth = iwidth;
 
5550
  else
 
5551
    pwidth = page->width;
 
5552
 
 
5553
  if (page->length <= 0)
 
5554
    plength = ilength;
 
5555
  else
 
5556
    plength = page->length;
 
5557
 
 
5558
  if (dump->debug)
 
5559
    {
 
5560
    TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
 
5561
                   "Hmargin: %3.2f, Vmargin: %3.2f",
 
5562
             page->name, page->vres, page->hres,
 
5563
             page->hmargin, page->vmargin);
 
5564
    TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f", 
 
5565
           page->res_unit, scale, pwidth, plength);
 
5566
    }
 
5567
 
 
5568
  /* compute margins at specified unit and resolution */
 
5569
  if (page->mode & PAGE_MODE_MARGINS)
 
5570
    {
 
5571
    if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
 
5572
      { /* inches or centimeters specified */
 
5573
      hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
 
5574
      vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
 
5575
      }
 
5576
    else
 
5577
      { /* Otherwise user has specified pixels as reference unit */
 
5578
      hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
 
5579
      vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
 
5580
      }
 
5581
 
 
5582
    if ((hmargin * 2.0) > (pwidth * page->hres))
 
5583
      {
 
5584
      TIFFError("computeOutputPixelOffsets", 
 
5585
                "Combined left and right margins exceed page width");
 
5586
      hmargin = (uint32) 0;
 
5587
      return (-1);
 
5588
      }
 
5589
    if ((vmargin * 2.0) > (plength * page->vres))
 
5590
      {
 
5591
      TIFFError("computeOutputPixelOffsets", 
 
5592
                "Combined top and bottom margins exceed page length"); 
 
5593
      vmargin = (uint32) 0; 
 
5594
      return (-1);
 
5595
      }
 
5596
    }
 
5597
  else
 
5598
    {
 
5599
    hmargin = 0;
 
5600
    vmargin = 0;
 
5601
    }
 
5602
 
 
5603
  if (page->mode & PAGE_MODE_ROWSCOLS )
 
5604
    {
 
5605
    /* Maybe someday but not for now */
 
5606
    if (page->mode & PAGE_MODE_MARGINS)
 
5607
      TIFFError("computeOutputPixelOffsets", 
 
5608
      "Output margins cannot be specified with rows and columns"); 
 
5609
 
 
5610
    owidth  = TIFFhowmany(iwidth, page->cols);
 
5611
    olength = TIFFhowmany(ilength, page->rows);
 
5612
    }
 
5613
  else
 
5614
    {
 
5615
    if (page->mode & PAGE_MODE_PAPERSIZE )
 
5616
      {
 
5617
      owidth  = (uint32)((pwidth * page->hres) - (hmargin * 2));
 
5618
      olength = (uint32)((plength * page->vres) - (vmargin * 2));
 
5619
      }
 
5620
    else
 
5621
      {
 
5622
      owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
 
5623
      olength = (uint32)(ilength - (vmargin * 2 * page->vres));
 
5624
      }
 
5625
    }
 
5626
 
 
5627
  if (owidth > iwidth)
 
5628
    owidth = iwidth;
 
5629
  if (olength > ilength)
 
5630
    olength = ilength;
 
5631
 
 
5632
  /* Compute the number of pages required for Portrait or Landscape */
 
5633
  switch (page->orient)
 
5634
    {
 
5635
    case ORIENTATION_NONE:
 
5636
    case ORIENTATION_PORTRAIT:
 
5637
         ocols = TIFFhowmany(iwidth, owidth);
 
5638
         orows = TIFFhowmany(ilength, olength);
 
5639
         orientation = ORIENTATION_PORTRAIT;
 
5640
         break;
 
5641
 
 
5642
    case ORIENTATION_LANDSCAPE:
 
5643
         ocols = TIFFhowmany(iwidth, olength);
 
5644
         orows = TIFFhowmany(ilength, owidth);
 
5645
         x1 = olength;
 
5646
         olength = owidth;
 
5647
         owidth = x1;
 
5648
         orientation = ORIENTATION_LANDSCAPE;
 
5649
         break;
 
5650
 
 
5651
    case ORIENTATION_AUTO:
 
5652
    default:
 
5653
         x1 = TIFFhowmany(iwidth, owidth);
 
5654
         x2 = TIFFhowmany(ilength, olength); 
 
5655
         y1 = TIFFhowmany(iwidth, olength);
 
5656
         y2 = TIFFhowmany(ilength, owidth); 
 
5657
 
 
5658
         if ( (x1 * x2) < (y1 * y2))
 
5659
           { /* Portrait */
 
5660
           ocols = x1;
 
5661
           orows = x2;
 
5662
           orientation = ORIENTATION_PORTRAIT;
 
5663
           }
 
5664
         else
 
5665
           { /* Landscape */
 
5666
           ocols = y1;
 
5667
           orows = y2;
 
5668
           x1 = olength;
 
5669
           olength = owidth;
 
5670
           owidth = x1;
 
5671
           orientation = ORIENTATION_LANDSCAPE;
 
5672
           }
 
5673
    }
 
5674
 
 
5675
  if (ocols < 1)
 
5676
    ocols = 1;
 
5677
  if (orows < 1)
 
5678
    orows = 1;
 
5679
 
 
5680
  /* If user did not specify rows and cols, set them from calcuation */
 
5681
  if (page->rows < 1)
 
5682
    page->rows = orows;
 
5683
  if (page->cols < 1)
 
5684
    page->cols = ocols;
 
5685
 
 
5686
  line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;
 
5687
 
 
5688
  if ((page->rows * page->cols) > MAX_SECTIONS)
 
5689
   {
 
5690
   TIFFError("computeOutputPixelOffsets",
 
5691
             "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
 
5692
   return (-1);
 
5693
   }
 
5694
 
 
5695
  /* build the list of offsets for each output section */
 
5696
  for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
 
5697
    {
 
5698
    y1 = (uint32)(olength * i);
 
5699
    y2 = (uint32)(olength * (i +  1) - 1);
 
5700
    if (y2 >= ilength)
 
5701
      y2 = ilength - 1;
 
5702
    for (j = 0; j < ocols; j++, k++)
 
5703
      {
 
5704
      x1 = (uint32)(owidth * j); 
 
5705
      x2 = (uint32)(owidth * (j + 1) - 1);
 
5706
      if (x2 >= iwidth)
 
5707
        x2 = iwidth - 1;
 
5708
      sections[k].x1 = x1;
 
5709
      sections[k].x2 = x2;
 
5710
      sections[k].y1 = y1;
 
5711
      sections[k].y2 = y2;
 
5712
      sections[k].buffsize = line_bytes * olength;
 
5713
      sections[k].position = k + 1;
 
5714
      sections[k].total = orows * ocols;
 
5715
      } 
 
5716
    } 
 
5717
  return (0);
 
5718
  } /* end computeOutputPixelOffsets */
 
5719
 
 
5720
static int
 
5721
loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned char **read_ptr)
 
5722
  {
 
5723
  uint32   i;
 
5724
  float    xres = 0.0, yres = 0.0;
 
5725
  uint16   nstrips = 0, ntiles = 0, planar = 0;
 
5726
  uint16   bps = 0, spp = 0, res_unit = 0;
 
5727
  uint16   orientation = 0;
 
5728
  uint16   input_compression = 0, input_photometric = 0;
 
5729
  uint16   subsampling_horiz, subsampling_vert;
 
5730
  uint32   width = 0, length = 0;
 
5731
  uint32   stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
 
5732
  uint32   tw = 0, tl = 0;       /* Tile width and length */
 
5733
  uint32   tile_rowsize = 0;
 
5734
  unsigned char *read_buff = NULL;
 
5735
  unsigned char *new_buff  = NULL;
 
5736
  int      readunit = 0;
 
5737
  static   uint32  prev_readsize = 0;
 
5738
 
 
5739
  TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
 
5740
  TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
 
5741
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
 
5742
  TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
 
5743
  if (! TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric))
 
5744
    TIFFError("loadImage","Image lacks Photometric interpreation tag");
 
5745
  if (! TIFFGetField(in, TIFFTAG_IMAGEWIDTH,  &width))
 
5746
    TIFFError("loadimage","Image lacks image width tag");
 
5747
  if(! TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length))
 
5748
    TIFFError("loadimage","Image lacks image length tag");
 
5749
  TIFFGetFieldDefaulted(in, TIFFTAG_XRESOLUTION, &xres);
 
5750
  TIFFGetFieldDefaulted(in, TIFFTAG_YRESOLUTION, &yres);
 
5751
  if (!TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit))
 
5752
    res_unit = RESUNIT_INCH;
 
5753
  if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression))
 
5754
    input_compression = COMPRESSION_NONE;
 
5755
 
 
5756
#ifdef DEBUG2
 
5757
  char compressionid[16];
 
5758
 
 
5759
  switch (input_compression)
 
5760
    {
 
5761
    case COMPRESSION_NONE:      /* 1  dump mode */
 
5762
         strcpy (compressionid, "None/dump");
 
5763
         break;         
 
5764
    case COMPRESSION_CCITTRLE:    /* 2 CCITT modified Huffman RLE */
 
5765
         strcpy (compressionid, "Huffman RLE");
 
5766
         break;         
 
5767
    case COMPRESSION_CCITTFAX3:   /* 3 CCITT Group 3 fax encoding */
 
5768
         strcpy (compressionid, "Group3 Fax");
 
5769
         break;         
 
5770
    case COMPRESSION_CCITTFAX4:   /* 4 CCITT Group 4 fax encoding */
 
5771
         strcpy (compressionid, "Group4 Fax");
 
5772
         break;         
 
5773
    case COMPRESSION_LZW:         /* 5 Lempel-Ziv  & Welch */
 
5774
         strcpy (compressionid, "LZW");
 
5775
         break;         
 
5776
    case COMPRESSION_OJPEG:       /* 6 !6.0 JPEG */
 
5777
         strcpy (compressionid, "Old Jpeg");
 
5778
         break;         
 
5779
    case COMPRESSION_JPEG:        /* 7 %JPEG DCT compression */
 
5780
         strcpy (compressionid, "New Jpeg");
 
5781
         break;         
 
5782
    case COMPRESSION_NEXT:        /* 32766 NeXT 2-bit RLE */
 
5783
         strcpy (compressionid, "Next RLE");
 
5784
         break;         
 
5785
    case COMPRESSION_CCITTRLEW:   /* 32771 #1 w/ word alignment */
 
5786
         strcpy (compressionid, "CITTRLEW");
 
5787
         break;         
 
5788
    case COMPRESSION_PACKBITS:    /* 32773 Macintosh RLE */
 
5789
         strcpy (compressionid, "Mac Packbits");
 
5790
         break;         
 
5791
    case COMPRESSION_THUNDERSCAN: /* 32809 ThunderScan RLE */
 
5792
         strcpy (compressionid, "Thunderscan");
 
5793
         break;         
 
5794
    case COMPRESSION_IT8CTPAD:    /* 32895 IT8 CT w/padding */
 
5795
         strcpy (compressionid, "IT8 padded");
 
5796
         break;         
 
5797
    case COMPRESSION_IT8LW:       /* 32896 IT8 Linework RLE */
 
5798
         strcpy (compressionid, "IT8 RLE");
 
5799
         break;         
 
5800
    case COMPRESSION_IT8MP:       /* 32897 IT8 Monochrome picture */
 
5801
         strcpy (compressionid, "IT8 mono");
 
5802
         break;         
 
5803
    case COMPRESSION_IT8BL:       /* 32898 IT8 Binary line art */
 
5804
         strcpy (compressionid, "IT8 lineart");
 
5805
         break;         
 
5806
    case COMPRESSION_PIXARFILM:   /* 32908 Pixar companded 10bit LZW */
 
5807
         strcpy (compressionid, "Pixar 10 bit");
 
5808
         break;         
 
5809
    case COMPRESSION_PIXARLOG:    /* 32909 Pixar companded 11bit ZIP */
 
5810
         strcpy (compressionid, "Pixar 11bit");
 
5811
         break;         
 
5812
    case COMPRESSION_DEFLATE:     /* 32946 Deflate compression */
 
5813
         strcpy (compressionid, "Deflate");
 
5814
         break;         
 
5815
    case COMPRESSION_ADOBE_DEFLATE: /* 8 Deflate compression */
 
5816
         strcpy (compressionid, "Adobe deflate");
 
5817
         break;         
 
5818
    default:
 
5819
         strcpy (compressionid, "None/unknown");
 
5820
         break;         
 
5821
    }
 
5822
  TIFFError("loadImage", "Input compression %s", compressionid);
 
5823
#endif
 
5824
 
 
5825
  scanlinesize = TIFFScanlineSize(in);
 
5826
  image->bps = bps;
 
5827
  image->spp = spp;
 
5828
  image->planar = planar;
 
5829
  image->width = width;
 
5830
  image->length = length;
 
5831
  image->xres = xres;
 
5832
  image->yres = yres;
 
5833
  image->res_unit = res_unit;
 
5834
  image->compression = input_compression;
 
5835
  image->photometric = input_photometric;
 
5836
#ifdef DEBUG2
 
5837
  char photometricid[12];
 
5838
 
 
5839
  switch (input_photometric)
 
5840
    {
 
5841
    case PHOTOMETRIC_MINISWHITE:
 
5842
         strcpy (photometricid, "MinIsWhite");
 
5843
         break;
 
5844
    case PHOTOMETRIC_MINISBLACK:
 
5845
         strcpy (photometricid, "MinIsBlack");
 
5846
         break;
 
5847
    case PHOTOMETRIC_RGB:
 
5848
         strcpy (photometricid, "RGB");
 
5849
         break;
 
5850
    case PHOTOMETRIC_PALETTE:
 
5851
         strcpy (photometricid, "Palette");
 
5852
         break;
 
5853
    case PHOTOMETRIC_MASK:
 
5854
         strcpy (photometricid, "Mask");
 
5855
         break;
 
5856
    case PHOTOMETRIC_SEPARATED:
 
5857
         strcpy (photometricid, "Separated");
 
5858
         break;
 
5859
    case PHOTOMETRIC_YCBCR:
 
5860
         strcpy (photometricid, "YCBCR");
 
5861
         break;
 
5862
    case PHOTOMETRIC_CIELAB:
 
5863
         strcpy (photometricid, "CIELab");
 
5864
         break;
 
5865
    case PHOTOMETRIC_ICCLAB:
 
5866
         strcpy (photometricid, "ICCLab");
 
5867
         break;
 
5868
    case PHOTOMETRIC_ITULAB:
 
5869
         strcpy (photometricid, "ITULab");
 
5870
         break;
 
5871
    case PHOTOMETRIC_LOGL:
 
5872
         strcpy (photometricid, "LogL");
 
5873
         break;
 
5874
    case PHOTOMETRIC_LOGLUV:
 
5875
         strcpy (photometricid, "LOGLuv");
 
5876
         break;
 
5877
    default:
 
5878
         strcpy (photometricid, "Unknown");
 
5879
         break;
 
5880
    }
 
5881
  TIFFError("loadImage", "Input photometric interpretation %s", photometricid);
 
5882
 
 
5883
#endif
 
5884
  image->orientation = orientation;
 
5885
  switch (orientation)
 
5886
    {
 
5887
    case 0:
 
5888
    case ORIENTATION_TOPLEFT:
 
5889
         image->adjustments = 0;
 
5890
         break;
 
5891
    case ORIENTATION_TOPRIGHT:
 
5892
         image->adjustments = MIRROR_HORIZ;
 
5893
         break;
 
5894
    case ORIENTATION_BOTRIGHT:
 
5895
         image->adjustments = ROTATECW_180;
 
5896
         break;
 
5897
    case ORIENTATION_BOTLEFT:
 
5898
         image->adjustments = MIRROR_VERT; 
 
5899
         break;
 
5900
    case ORIENTATION_LEFTTOP:
 
5901
         image->adjustments = MIRROR_VERT | ROTATECW_90;
 
5902
         break;
 
5903
    case ORIENTATION_RIGHTTOP:
 
5904
         image->adjustments = ROTATECW_90;
 
5905
         break;
 
5906
    case ORIENTATION_RIGHTBOT:
 
5907
         image->adjustments = MIRROR_VERT | ROTATECW_270;
 
5908
         break; 
 
5909
    case ORIENTATION_LEFTBOT:
 
5910
         image->adjustments = ROTATECW_270;
 
5911
         break;
 
5912
    default:
 
5913
         image->adjustments = 0;
 
5914
         image->orientation = ORIENTATION_TOPLEFT;
 
5915
   }
 
5916
 
 
5917
  if ((bps == 0) || (spp == 0))
 
5918
    {
 
5919
    TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
 
5920
               spp, bps);
 
5921
    return (-1);
 
5922
    }
 
5923
 
 
5924
  if (TIFFIsTiled(in))
 
5925
    {
 
5926
    readunit = TILE;
 
5927
    tlsize = TIFFTileSize(in);
 
5928
    ntiles = TIFFNumberOfTiles(in);
 
5929
    TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 
5930
    TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
5931
 
 
5932
    tile_rowsize  = TIFFTileRowSize(in);      
 
5933
    buffsize = tlsize * ntiles;
 
5934
 
 
5935
        
 
5936
    if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
 
5937
      {
 
5938
      buffsize = ntiles * tl * tile_rowsize;
 
5939
#ifdef DEBUG2
 
5940
      TIFFError("loadImage",
 
5941
                "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
 
5942
                tlsize, (unsigned long)buffsize);
 
5943
#endif
 
5944
      }
 
5945
    
 
5946
    if (dump->infile != NULL)
 
5947
      dump_info (dump->infile, dump->format, "", 
 
5948
                 "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
 
5949
                 tlsize, ntiles, tile_rowsize);
 
5950
    }
 
5951
  else
 
5952
    {
 
5953
    readunit = STRIP;
 
5954
    TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
 
5955
    stsize = TIFFStripSize(in);
 
5956
    nstrips = TIFFNumberOfStrips(in);
 
5957
    buffsize = stsize * nstrips;
 
5958
    
 
5959
    if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
 
5960
      {
 
5961
      buffsize =  ((length * width * spp * bps) + 7) / 8;
 
5962
#ifdef DEBUG2
 
5963
      TIFFError("loadImage",
 
5964
                "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
 
5965
                stsize, (unsigned long)buffsize);
 
5966
#endif
 
5967
      }
 
5968
    
 
5969
    if (dump->infile != NULL)
 
5970
      dump_info (dump->infile, dump->format, "",
 
5971
                 "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
 
5972
                 stsize, nstrips, rowsperstrip, scanlinesize);
 
5973
    }
 
5974
  
 
5975
  if (input_compression == COMPRESSION_JPEG)
 
5976
    {  /* Force conversion to RGB */
 
5977
    jpegcolormode = JPEGCOLORMODE_RGB;
 
5978
    TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
5979
    }
 
5980
  /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
 
5981
  else 
 
5982
    {   /* Otherwise, can't handle subsampled input */
 
5983
    if (input_photometric == PHOTOMETRIC_YCBCR)
 
5984
      {
 
5985
      TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
 
5986
                           &subsampling_horiz, &subsampling_vert);
 
5987
      if (subsampling_horiz != 1 || subsampling_vert != 1)
 
5988
        {
 
5989
        TIFFError("loadImage", 
 
5990
                "Can't copy/convert subsampled image with subsampling %d horiz %d vert",
 
5991
                subsampling_horiz, subsampling_vert);
 
5992
        return (-1);
 
5993
        }
 
5994
        }
 
5995
    }
 
5996
 
 
5997
  read_buff = *read_ptr;
 
5998
  if (!read_buff)
 
5999
    read_buff = (unsigned char *)_TIFFmalloc(buffsize);
 
6000
  else
 
6001
    {
 
6002
    if (prev_readsize < buffsize)
 
6003
      {
 
6004
      new_buff = _TIFFrealloc(read_buff, buffsize);
 
6005
      if (!new_buff)
 
6006
        {
 
6007
        free (read_buff);
 
6008
        read_buff = (unsigned char *)_TIFFmalloc(buffsize);
 
6009
        }
 
6010
      else
 
6011
        read_buff = new_buff;
 
6012
      }
 
6013
    }
 
6014
 
 
6015
  if (!read_buff)
 
6016
    {
 
6017
    TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
 
6018
    return (-1);
 
6019
    }
 
6020
 
 
6021
  prev_readsize = buffsize;
 
6022
  *read_ptr = read_buff;
 
6023
 
 
6024
  /* N.B. The read functions used copy separate plane data into a buffer as interleaved
 
6025
   * samples rather than separate planes so the same logic works to extract regions
 
6026
   * regardless of the way the data are organized in the input file.
 
6027
   */
 
6028
  switch (readunit) {
 
6029
    case STRIP:
 
6030
         if (planar == PLANARCONFIG_CONTIG)
 
6031
           {
 
6032
             if (!(readContigStripsIntoBuffer(in, read_buff)))
 
6033
             {
 
6034
             TIFFError("loadImage", "Unable to read contiguous strips into buffer");
 
6035
             return (-1);
 
6036
             }
 
6037
           }
 
6038
         else
 
6039
           {
 
6040
           if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
 
6041
             {
 
6042
             TIFFError("loadImage", "Unable to read separate strips into buffer");
 
6043
             return (-1);
 
6044
             }
 
6045
           }
 
6046
         break;
 
6047
 
 
6048
    case TILE:
 
6049
         if (planar == PLANARCONFIG_CONTIG)
 
6050
           {
 
6051
           if (!(readContigTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
 
6052
             {
 
6053
             TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
 
6054
             return (-1);
 
6055
             }
 
6056
           }
 
6057
         else
 
6058
           {
 
6059
           if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
 
6060
             {
 
6061
             TIFFError("loadImage", "Unable to read separate tiles into buffer");
 
6062
             return (-1);
 
6063
             }
 
6064
           }
 
6065
         break;
 
6066
    default: TIFFError("loadImage", "Unsupported image file format");
 
6067
          return (-1);
 
6068
          break;
 
6069
    }
 
6070
  if ((dump->infile != NULL) && (dump->level == 2))
 
6071
    {
 
6072
    dump_info  (dump->infile, dump->format, "loadImage", 
 
6073
                "Image width %d, length %d, Raw image data, %4d bytes",
 
6074
                width, length,  buffsize);
 
6075
    dump_info  (dump->infile, dump->format, "", 
 
6076
                "Bits per sample %d, Samples per pixel %d", bps, spp);
 
6077
 
 
6078
    for (i = 0; i < length; i++)
 
6079
      dump_buffer(dump->infile, dump->format, 1, scanlinesize, 
 
6080
                  i, read_buff + (i * scanlinesize));
 
6081
    }
 
6082
  return (0);
 
6083
  }   /* end loadImage */
 
6084
 
 
6085
static int  correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
 
6086
  {
 
6087
  uint16 mirror, rotation;
 
6088
  unsigned char *work_buff;
 
6089
 
 
6090
  work_buff = *work_buff_ptr;
 
6091
  if ((image == NULL) || (work_buff == NULL))
 
6092
    {
 
6093
    TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
 
6094
    return (-1);
 
6095
    }
 
6096
 
 
6097
  if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
 
6098
    {
 
6099
    mirror = (uint16)(image->adjustments & MIRROR_BOTH);
 
6100
    if (mirrorImage(image->spp, image->bps, mirror, 
 
6101
        image->width, image->length, work_buff))
 
6102
      {
 
6103
      TIFFError ("correct_orientation", "Unable to mirror image");
 
6104
      return (-1);
 
6105
      }
 
6106
    }
 
6107
 
 
6108
  if (image->adjustments & ROTATE_ANY)
 
6109
    {
 
6110
    if (image->adjustments & ROTATECW_90)
 
6111
      rotation = (uint16) 90;
 
6112
    else
 
6113
    if (image->adjustments & ROTATECW_180)
 
6114
      rotation = (uint16) 180;
 
6115
    else
 
6116
    if (image->adjustments & ROTATECW_270)
 
6117
      rotation = (uint16) 270;
 
6118
    else
 
6119
      {
 
6120
      TIFFError ("correct_orientation", "Invalid rotation value: %d", 
 
6121
                  image->adjustments & ROTATE_ANY);
 
6122
      return (-1);
 
6123
      }
 
6124
 
 
6125
    if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
 
6126
      {
 
6127
      TIFFError ("correct_orientation", "Unable to rotate image");
 
6128
      return (-1);
 
6129
      }
 
6130
    image->orientation = ORIENTATION_TOPLEFT;
 
6131
    }
 
6132
 
 
6133
  return (0);
 
6134
  } /* end correct_orientation */
 
6135
 
 
6136
 
 
6137
/* Extract multiple zones from an image and combine into a single composite image */
 
6138
static int
 
6139
extractCompositeRegions(struct image_data *image,  struct crop_mask *crop, 
 
6140
                        unsigned char *read_buff, unsigned char *crop_buff)
 
6141
  {
 
6142
  int       shift_width, bytes_per_sample, bytes_per_pixel;
 
6143
  uint32    i, trailing_bits, prev_trailing_bits;
 
6144
  uint32    row, first_row, last_row, first_col, last_col;
 
6145
  uint32    src_rowsize, dst_rowsize, src_offset, dst_offset;
 
6146
  uint32    crop_width, crop_length, img_width, img_length;
 
6147
  uint32    prev_length, prev_width, composite_width;
 
6148
  uint16    bps, spp;
 
6149
  uint8    *src, *dst;
 
6150
  tsample_t count, sample = 0;   /* Update to extract one or more samples */
 
6151
 
 
6152
  img_width = image->width;
 
6153
  img_length = image->length;
 
6154
  bps = image->bps;
 
6155
  spp = image->spp;
 
6156
  count = spp;
 
6157
 
 
6158
  bytes_per_sample = (bps + 7) / 8; 
 
6159
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
6160
  if ((bps % 8) == 0)
 
6161
    shift_width = 0;
 
6162
  else
 
6163
    {
 
6164
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
6165
      shift_width = bytes_per_pixel;
 
6166
    else
 
6167
      shift_width = bytes_per_sample + 1;
 
6168
    }
 
6169
  src = read_buff;
 
6170
  dst = crop_buff;
 
6171
 
 
6172
  /* These are setup for adding additional sections */
 
6173
  prev_width = prev_length = 0;
 
6174
  prev_trailing_bits = trailing_bits = 0;
 
6175
  composite_width = crop->combined_width;
 
6176
  crop->combined_width = 0;
 
6177
  crop->combined_length = 0;
 
6178
 
 
6179
  for (i = 0; i < crop->selections; i++)
 
6180
    {
 
6181
    /* rows, columns, width, length are expressed in pixels */
 
6182
    first_row = crop->regionlist[i].y1;
 
6183
    last_row  = crop->regionlist[i].y2;
 
6184
    first_col = crop->regionlist[i].x1;
 
6185
    last_col  = crop->regionlist[i].x2;
 
6186
 
 
6187
    crop_width = last_col - first_col + 1;
 
6188
    crop_length = last_row - first_row + 1;
 
6189
 
 
6190
    /* These should not be needed for composite images */
 
6191
    crop->regionlist[i].width = crop_width;
 
6192
    crop->regionlist[i].length = crop_length;
 
6193
    crop->regionlist[i].buffptr = crop_buff;
 
6194
 
 
6195
    src_rowsize = ((img_width * bps * spp) + 7) / 8;
 
6196
    dst_rowsize = (((crop_width * bps * count) + 7) / 8);
 
6197
 
 
6198
    switch (crop->edge_ref)
 
6199
      {
 
6200
      default:
 
6201
      case EDGE_TOP:
 
6202
      case EDGE_BOTTOM:
 
6203
           if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
 
6204
             {
 
6205
             TIFFError ("extractCompositeRegions", 
 
6206
                          "Only equal width regions can be combined for -E top or bottom");
 
6207
             return (1);
 
6208
             }
 
6209
 
 
6210
           crop->combined_width = crop_width;
 
6211
           crop->combined_length += crop_length;
 
6212
 
 
6213
           for (row = first_row; row <= last_row; row++)
 
6214
             {
 
6215
             src_offset = row * src_rowsize;
 
6216
             dst_offset = (row - first_row) * dst_rowsize;
 
6217
             src = read_buff + src_offset;
 
6218
             dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
 
6219
             switch (shift_width)
 
6220
               {
 
6221
               case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
 
6222
                                                      spp, bps, count, first_col,
 
6223
                                                      last_col + 1))
 
6224
                         {
 
6225
                         TIFFError("extractCompositeRegions",
 
6226
                                   "Unable to extract row %d", row);
 
6227
                         return (1);
 
6228
                         }
 
6229
                       break;
 
6230
               case 1: if (bps == 1)
 
6231
                         { 
 
6232
                         if (extractContigSamplesShifted8bits (src, dst, img_width,
 
6233
                                                               sample, spp, bps, count, 
 
6234
                                                               first_col, last_col + 1,
 
6235
                                                               prev_trailing_bits))
 
6236
                           {
 
6237
                           TIFFError("extractCompositeRegions",
 
6238
                                     "Unable to extract row %d", row);
 
6239
                           return (1);
 
6240
                           }
 
6241
                         break;
 
6242
                         }
 
6243
                       else
 
6244
                         if (extractContigSamplesShifted16bits (src, dst, img_width,
 
6245
                                                                sample, spp, bps, count, 
 
6246
                                                                first_col, last_col + 1,
 
6247
                                                                prev_trailing_bits))
 
6248
                           {
 
6249
                           TIFFError("extractCompositeRegions",
 
6250
                                     "Unable to extract row %d", row);
 
6251
                           return (1);
 
6252
                           }
 
6253
                        break;
 
6254
               case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
6255
                                                               sample, spp, bps, count, 
 
6256
                                                               first_col, last_col + 1,
 
6257
                                                               prev_trailing_bits))
 
6258
                          {
 
6259
                          TIFFError("extractCompositeRegions",
 
6260
                                    "Unable to extract row %d", row);
 
6261
                          return (1);
 
6262
                          }
 
6263
                        break;
 
6264
               case 3:
 
6265
               case 4:
 
6266
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
6267
                                                               sample, spp, bps, count, 
 
6268
                                                               first_col, last_col + 1,
 
6269
                                                               prev_trailing_bits))
 
6270
                          {
 
6271
                          TIFFError("extractCompositeRegions",
 
6272
                                    "Unable to extract row %d", row);
 
6273
                          return (1);
 
6274
                          }
 
6275
                        break;
 
6276
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
 
6277
                        return (1);
 
6278
               }
 
6279
             }
 
6280
           prev_length += crop_length;
 
6281
           break;
 
6282
      case EDGE_LEFT:  /* splice the pieces of each row together, side by side */
 
6283
      case EDGE_RIGHT:
 
6284
           if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
 
6285
             {
 
6286
             TIFFError ("extractCompositeRegions", 
 
6287
                          "Only equal length regions can be combined for -E left or right");
 
6288
             return (1);
 
6289
             }
 
6290
           crop->combined_width += crop_width;
 
6291
           crop->combined_length = crop_length;
 
6292
           dst_rowsize = (((composite_width * bps * count) + 7) / 8);
 
6293
           trailing_bits = (crop_width * bps * count) % 8;
 
6294
           for (row = first_row; row <= last_row; row++)
 
6295
             {
 
6296
             src_offset = row * src_rowsize;
 
6297
             dst_offset = (row - first_row) * dst_rowsize;
 
6298
             src = read_buff + src_offset;
 
6299
             dst = crop_buff + dst_offset + prev_width;
 
6300
 
 
6301
             switch (shift_width)
 
6302
               {
 
6303
               case 0: if (extractContigSamplesBytes (src, dst, img_width,
 
6304
                                                      sample, spp, bps, count,
 
6305
                                                      first_col, last_col + 1))
 
6306
                         {
 
6307
                         TIFFError("extractCompositeRegions",
 
6308
                                   "Unable to extract row %d", row);
 
6309
                         return (1);
 
6310
                         }
 
6311
                       break;
 
6312
               case 1: if (bps == 1)
 
6313
                         { 
 
6314
                         if (extractContigSamplesShifted8bits (src, dst, img_width,
 
6315
                                                               sample, spp, bps, count, 
 
6316
                                                               first_col, last_col + 1,
 
6317
                                                               prev_trailing_bits))
 
6318
                           {
 
6319
                           TIFFError("extractCompositeRegions",
 
6320
                                     "Unable to extract row %d", row);
 
6321
                           return (1);
 
6322
                           }
 
6323
                         break;
 
6324
                         }
 
6325
                       else
 
6326
                         if (extractContigSamplesShifted16bits (src, dst, img_width,
 
6327
                                                                sample, spp, bps, count, 
 
6328
                                                                first_col, last_col + 1,
 
6329
                                                                prev_trailing_bits))
 
6330
                           {
 
6331
                           TIFFError("extractCompositeRegions",
 
6332
                                     "Unable to extract row %d", row);
 
6333
                           return (1);
 
6334
                           }
 
6335
                        break;
 
6336
              case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
6337
                                                               sample, spp, bps, count, 
 
6338
                                                               first_col, last_col + 1,
 
6339
                                                               prev_trailing_bits))
 
6340
                          {
 
6341
                          TIFFError("extractCompositeRegions",
 
6342
                                    "Unable to extract row %d", row);
 
6343
                          return (1);
 
6344
                          }
 
6345
                        break;
 
6346
               case 3:
 
6347
               case 4:
 
6348
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
6349
                                                               sample, spp, bps, count, 
 
6350
                                                               first_col, last_col + 1,
 
6351
                                                               prev_trailing_bits))
 
6352
                          {
 
6353
                          TIFFError("extractCompositeRegions",
 
6354
                                    "Unable to extract row %d", row);
 
6355
                          return (1);
 
6356
                          }
 
6357
                        break;
 
6358
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
 
6359
                        return (1);
 
6360
               }
 
6361
             }
 
6362
           prev_width += (crop_width * bps * count) / 8;
 
6363
           prev_trailing_bits += trailing_bits;
 
6364
           if (prev_trailing_bits > 7)
 
6365
             prev_trailing_bits-= 8;
 
6366
           break;
 
6367
      }
 
6368
    }
 
6369
  if (crop->combined_width != composite_width)
 
6370
    TIFFError("combineSeparateRegions","Combined width does not match composite width");
 
6371
      
 
6372
  return (0);
 
6373
  }  /* end extractCompositeRegions */
 
6374
 
 
6375
/* Copy a single region of input buffer to an output buffer. 
 
6376
 * The read functions used copy separate plane data into a buffer 
 
6377
 * as interleaved samples rather than separate planes so the same
 
6378
 * logic works to extract regions regardless of the way the data 
 
6379
 * are organized in the input file. This function can be used to
 
6380
 * extract one or more samples from the input image by updating the 
 
6381
 * parameters for starting sample and number of samples to copy in the
 
6382
 * fifth and eighth arguments of the call to extractContigSamples.
 
6383
 * They would be passed as new elements of the crop_mask struct.
 
6384
 */
 
6385
 
 
6386
static int
 
6387
extractSeparateRegion(struct image_data *image,  struct crop_mask *crop,
 
6388
                      unsigned char *read_buff, unsigned char *crop_buff,
 
6389
                      int region)
 
6390
  {
 
6391
  int     shift_width, prev_trailing_bits = 0;
 
6392
  uint32  bytes_per_sample, bytes_per_pixel;
 
6393
  uint32  src_rowsize, dst_rowsize;
 
6394
  uint32  row, first_row, last_row, first_col, last_col;
 
6395
  uint32  src_offset, dst_offset;
 
6396
  uint32  crop_width, crop_length, img_width, img_length;
 
6397
  uint16  bps, spp;
 
6398
  uint8  *src, *dst;
 
6399
  tsample_t count, sample = 0;   /* Update to extract more or more samples */
 
6400
 
 
6401
  img_width = image->width;
 
6402
  img_length = image->length;
 
6403
  bps = image->bps;
 
6404
  spp = image->spp;
 
6405
  count = spp;
 
6406
 
 
6407
  bytes_per_sample = (bps + 7) / 8; 
 
6408
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
6409
  if ((bps % 8) == 0)
 
6410
    shift_width = 0; /* Byte aligned data only */
 
6411
  else
 
6412
    {
 
6413
    if (bytes_per_pixel < (bytes_per_sample + 1))
 
6414
      shift_width = bytes_per_pixel;
 
6415
    else
 
6416
      shift_width = bytes_per_sample + 1;
 
6417
    }
 
6418
 
 
6419
  /* rows, columns, width, length are expressed in pixels */
 
6420
  first_row = crop->regionlist[region].y1;
 
6421
  last_row  = crop->regionlist[region].y2;
 
6422
  first_col = crop->regionlist[region].x1;
 
6423
  last_col  = crop->regionlist[region].x2;
 
6424
 
 
6425
  crop_width = last_col - first_col + 1;
 
6426
  crop_length = last_row - first_row + 1;
 
6427
 
 
6428
  crop->regionlist[region].width = crop_width;
 
6429
  crop->regionlist[region].length = crop_length;
 
6430
  crop->regionlist[region].buffptr = crop_buff;
 
6431
 
 
6432
  src = read_buff;
 
6433
  dst = crop_buff;
 
6434
  src_rowsize = ((img_width * bps * spp) + 7) / 8;
 
6435
  dst_rowsize = (((crop_width * bps * spp) + 7) / 8);
 
6436
 
 
6437
  for (row = first_row; row <= last_row; row++)
 
6438
    {
 
6439
    src_offset = row * src_rowsize;
 
6440
    dst_offset = (row  - first_row) * dst_rowsize;
 
6441
    src = read_buff + src_offset;
 
6442
    dst = crop_buff + dst_offset;
 
6443
 
 
6444
    switch (shift_width)
 
6445
      {
 
6446
      case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
 
6447
                                             spp, bps, count, first_col,
 
6448
                                             last_col + 1))
 
6449
                {
 
6450
                TIFFError("extractSeparateRegion",
 
6451
                          "Unable to extract row %d", row);
 
6452
                return (1);
 
6453
                }
 
6454
              break;
 
6455
      case 1: if (bps == 1)
 
6456
                { 
 
6457
                if (extractContigSamplesShifted8bits (src, dst, img_width,
 
6458
                                                      sample, spp, bps, count, 
 
6459
                                                      first_col, last_col + 1,
 
6460
                                                      prev_trailing_bits))
 
6461
                  {
 
6462
                  TIFFError("extractSeparateRegion",
 
6463
                            "Unable to extract row %d", row);
 
6464
                  return (1);
 
6465
                  }
 
6466
                  break;
 
6467
                }
 
6468
              else
 
6469
                if (extractContigSamplesShifted16bits (src, dst, img_width,
 
6470
                                                       sample, spp, bps, count, 
 
6471
                                                       first_col, last_col + 1,
 
6472
                                                       prev_trailing_bits))
 
6473
                  {
 
6474
                  TIFFError("extractSeparateRegion",
 
6475
                            "Unable to extract row %d", row);
 
6476
                  return (1);
 
6477
                  }
 
6478
              break;
 
6479
      case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
 
6480
                                                     sample, spp, bps, count, 
 
6481
                                                     first_col, last_col + 1,
 
6482
                                                     prev_trailing_bits))
 
6483
                {
 
6484
                TIFFError("extractSeparateRegion",
 
6485
                          "Unable to extract row %d", row);
 
6486
                return (1);
 
6487
                }
 
6488
              break;
 
6489
      case 3:
 
6490
      case 4:
 
6491
      case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
 
6492
                                                     sample, spp, bps, count, 
 
6493
                                                     first_col, last_col + 1,
 
6494
                                                     prev_trailing_bits))
 
6495
                {
 
6496
                TIFFError("extractSeparateRegion",
 
6497
                          "Unable to extract row %d", row);
 
6498
                return (1);
 
6499
                }
 
6500
              break;
 
6501
      default: TIFFError("extractSeparateRegion", "Unsupported bit depth %d", bps);
 
6502
               return (1);
 
6503
      }
 
6504
    }
 
6505
          
 
6506
  return (0);
 
6507
  }  /* end extractSeparateRegion */
 
6508
 
 
6509
static int
 
6510
extractImageSection(struct image_data *image, struct pageseg *section, 
 
6511
                    unsigned char *src_buff, unsigned char *sect_buff)
 
6512
  {
 
6513
  unsigned  char  bytebuff1, bytebuff2;
 
6514
  unsigned  char *src, *dst;
 
6515
 
 
6516
  uint32    img_width, img_length, img_rowsize;
 
6517
  uint32    j, shift1, shift2, trailing_bits;
 
6518
  uint32    row, first_row, last_row, first_col, last_col;
 
6519
  uint32    src_offset, dst_offset, row_offset, col_offset;
 
6520
  uint32    offset1, offset2, full_bytes;
 
6521
  uint32    sect_width, sect_length;
 
6522
  uint16    bps, spp;
 
6523
 
 
6524
#ifdef DEVELMODE
 
6525
  int      k;
 
6526
  unsigned char bitset;
 
6527
  static char *bitarray = NULL;
 
6528
#endif
 
6529
 
 
6530
  img_width = image->width;
 
6531
  img_length = image->length;
 
6532
  bps = image->bps;
 
6533
  spp = image->spp;
 
6534
 
 
6535
  src = src_buff;
 
6536
  dst = sect_buff;
 
6537
  src_offset = 0;
 
6538
  dst_offset = 0;
 
6539
 
 
6540
#ifdef DEVELMODE
 
6541
  if (bitarray == NULL)
 
6542
    {
 
6543
    if ((bitarray = (char *)malloc(img_width)) == NULL)
 
6544
      {
 
6545
      TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
 
6546
      return (-1);
 
6547
      }
 
6548
    }
 
6549
#endif
 
6550
 
 
6551
  /* rows, columns, width, length are expressed in pixels */
 
6552
  first_row = section->y1;
 
6553
  last_row  = section->y2;
 
6554
  first_col = section->x1;
 
6555
  last_col  = section->x2;
 
6556
 
 
6557
  sect_width = last_col - first_col + 1;
 
6558
  sect_length = last_row - first_row + 1;
 
6559
  img_rowsize = ((img_width * bps + 7) / 8) * spp;
 
6560
  full_bytes = (sect_width * spp * bps) / 8;   /* number of COMPLETE bytes per row in section */
 
6561
  trailing_bits = (sect_width * bps) % 8;
 
6562
 
 
6563
#ifdef DEVELMODE
 
6564
    TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
 
6565
           first_row, last_row, first_col, last_col);
 
6566
    TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
 
6567
           img_width, img_length, bps, spp);
 
6568
    TIFFError ("", "Sect  width: %d,  Sect length: %d, full bytes: %d trailing bits %d\n", 
 
6569
           sect_width, sect_length, full_bytes, trailing_bits);
 
6570
#endif
 
6571
 
 
6572
  if ((bps % 8) == 0)
 
6573
    {
 
6574
    col_offset = first_col * spp * bps / 8;
 
6575
    for (row = first_row; row <= last_row; row++)
 
6576
      {
 
6577
      /* row_offset = row * img_width * spp * bps / 8; */
 
6578
      row_offset = row * img_rowsize;
 
6579
      src_offset = row_offset + col_offset;
 
6580
 
 
6581
#ifdef DEVELMODE
 
6582
        TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset, dst_offset); 
 
6583
#endif
 
6584
      _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
 
6585
      dst_offset += full_bytes;
 
6586
      }        
 
6587
    }
 
6588
  else
 
6589
    { /* bps != 8 */
 
6590
    shift1  = spp * ((first_col * bps) % 8);
 
6591
    shift2  = spp * ((last_col * bps) % 8);
 
6592
    for (row = first_row; row <= last_row; row++)
 
6593
      {
 
6594
      /* pull out the first byte */
 
6595
      row_offset = row * img_rowsize;
 
6596
      offset1 = row_offset + (first_col * bps / 8);
 
6597
      offset2 = row_offset + (last_col * bps / 8);
 
6598
 
 
6599
#ifdef DEVELMODE
 
6600
      for (j = 0, k = 7; j < 8; j++, k--)
 
6601
        {
 
6602
        bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
 
6603
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6604
        }
 
6605
      sprintf(&bitarray[8], " ");
 
6606
      sprintf(&bitarray[9], " ");
 
6607
      for (j = 10, k = 7; j < 18; j++, k--)
 
6608
        {
 
6609
        bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
 
6610
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6611
        }
 
6612
      bitarray[18] = '\0';
 
6613
      TIFFError ("", "Row: %3d Offset1: %d,  Shift1: %d,    Offset2: %d,  Shift2:  %d\n", 
 
6614
                 row, offset1, shift1, offset2, shift2); 
 
6615
#endif
 
6616
 
 
6617
      bytebuff1 = bytebuff2 = 0;
 
6618
      if (shift1 == 0) /* the region is byte and sample alligned */
 
6619
        {
 
6620
        _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);
 
6621
 
 
6622
#ifdef DEVELMODE
 
6623
        TIFFError ("", "        Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset); 
 
6624
        sprintf(&bitarray[18], "\n");
 
6625
        sprintf(&bitarray[19], "\t");
 
6626
        for (j = 20, k = 7; j < 28; j++, k--)
 
6627
          {
 
6628
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
6629
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6630
          }
 
6631
        bitarray[28] = ' ';
 
6632
        bitarray[29] = ' ';
 
6633
#endif
 
6634
        dst_offset += full_bytes;
 
6635
 
 
6636
        if (trailing_bits != 0)
 
6637
          {
 
6638
          bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
 
6639
          sect_buff[dst_offset] = bytebuff2;
 
6640
#ifdef DEVELMODE
 
6641
          TIFFError ("", "        Trailing bits src offset:  %8d, Dst offset: %8d\n", 
 
6642
                              offset2, dst_offset); 
 
6643
          for (j = 30, k = 7; j < 38; j++, k--)
 
6644
            {
 
6645
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
6646
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6647
            }
 
6648
          bitarray[38] = '\0';
 
6649
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
 
6650
#endif
 
6651
          dst_offset++;
 
6652
          }
 
6653
        }
 
6654
      else   /* each destination byte will have to be built from two source bytes*/
 
6655
        {
 
6656
#ifdef DEVELMODE
 
6657
          TIFFError ("", "        Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset); 
 
6658
#endif
 
6659
        for (j = 0; j <= full_bytes; j++) 
 
6660
          {
 
6661
          bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
 
6662
          bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
 
6663
          sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
 
6664
          }
 
6665
#ifdef DEVELMODE
 
6666
        sprintf(&bitarray[18], "\n");
 
6667
        sprintf(&bitarray[19], "\t");
 
6668
        for (j = 20, k = 7; j < 28; j++, k--)
 
6669
          {
 
6670
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
6671
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6672
          }
 
6673
        bitarray[28] = ' ';
 
6674
        bitarray[29] = ' ';
 
6675
#endif
 
6676
        dst_offset += full_bytes;
 
6677
 
 
6678
        if (trailing_bits != 0)
 
6679
          {
 
6680
#ifdef DEVELMODE
 
6681
            TIFFError ("", "        Trailing bits   src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset); 
 
6682
#endif
 
6683
          if (shift2 > shift1)
 
6684
            {
 
6685
            bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
 
6686
            bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
 
6687
            sect_buff[dst_offset] = bytebuff2;
 
6688
#ifdef DEVELMODE
 
6689
            TIFFError ("", "        Shift2 > Shift1\n"); 
 
6690
#endif
 
6691
            }
 
6692
          else
 
6693
            {
 
6694
            if (shift2 < shift1)
 
6695
              {
 
6696
              bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
 
6697
              sect_buff[dst_offset] &= bytebuff2;
 
6698
#ifdef DEVELMODE
 
6699
              TIFFError ("", "        Shift2 < Shift1\n"); 
 
6700
#endif
 
6701
              }
 
6702
#ifdef DEVELMODE
 
6703
            else
 
6704
              TIFFError ("", "        Shift2 == Shift1\n"); 
 
6705
#endif
 
6706
            }
 
6707
          }
 
6708
#ifdef DEVELMODE
 
6709
          sprintf(&bitarray[28], " ");
 
6710
          sprintf(&bitarray[29], " ");
 
6711
          for (j = 30, k = 7; j < 38; j++, k--)
 
6712
            {
 
6713
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
 
6714
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
 
6715
            }
 
6716
          bitarray[38] = '\0';
 
6717
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
 
6718
#endif
 
6719
        dst_offset++;
 
6720
        }
 
6721
      }
 
6722
    }
 
6723
 
 
6724
  return (0);
 
6725
  } /* end extractImageSection */
 
6726
 
 
6727
static int 
 
6728
writeSelections(TIFF *in, TIFF **out, struct crop_mask *crop, 
 
6729
                struct image_data *image, struct dump_opts *dump,
 
6730
                struct buffinfo seg_buffs[], char *mp, char *filename, 
 
6731
                unsigned int *page, unsigned int total_pages)
 
6732
  {
 
6733
  int i, page_count;
 
6734
  int autoindex = 0;
 
6735
  unsigned char *crop_buff = NULL;
 
6736
 
 
6737
  /* Where we open a new file depends on the export mode */  
 
6738
  switch (crop->exp_mode)
 
6739
    {
 
6740
    case ONE_FILE_COMPOSITE: /* Regions combined into single image */
 
6741
         autoindex = 0;
 
6742
         crop_buff = seg_buffs[0].buffer;
 
6743
         if (update_output_file (out, mp, autoindex, filename, page))
 
6744
           return (1);
 
6745
         page_count = total_pages;
 
6746
         if (writeCroppedImage(in, *out, image, dump,
 
6747
                               crop->combined_width, 
 
6748
                               crop->combined_length,
 
6749
                               crop_buff, *page, total_pages))
 
6750
            {
 
6751
             TIFFError("writeRegions", "Unable to write new image");
 
6752
             return (-1);
 
6753
             }
 
6754
         break;
 
6755
    case ONE_FILE_SEPARATED: /* Regions as separated images */
 
6756
         autoindex = 0;
 
6757
         if (update_output_file (out, mp, autoindex, filename, page))
 
6758
           return (1);
 
6759
         page_count = crop->selections * total_pages;
 
6760
         for (i = 0; i < crop->selections; i++)
 
6761
           {
 
6762
           crop_buff = seg_buffs[i].buffer;
 
6763
           if (writeCroppedImage(in, *out, image, dump,
 
6764
                                 crop->regionlist[i].width, 
 
6765
                                 crop->regionlist[i].length, 
 
6766
                                 crop_buff, *page, page_count))
 
6767
             {
 
6768
             TIFFError("writeRegions", "Unable to write new image");
 
6769
             return (-1);
 
6770
             }
 
6771
           }
 
6772
         break;
 
6773
    case FILE_PER_IMAGE_COMPOSITE: /* Regions as composite image */
 
6774
         autoindex = 1;
 
6775
         if (update_output_file (out, mp, autoindex, filename, page))
 
6776
           return (1);
 
6777
 
 
6778
         crop_buff = seg_buffs[0].buffer;
 
6779
         if (writeCroppedImage(in, *out, image, dump,
 
6780
                               crop->combined_width, 
 
6781
                               crop->combined_length, 
 
6782
                               crop_buff, *page, total_pages))
 
6783
           {
 
6784
           TIFFError("writeRegions", "Unable to write new image");
 
6785
           return (-1);
 
6786
           }
 
6787
         break;
 
6788
    case FILE_PER_IMAGE_SEPARATED: /* Regions as separated images */
 
6789
         autoindex = 1;
 
6790
         page_count = crop->selections;
 
6791
         if (update_output_file (out, mp, autoindex, filename, page))
 
6792
           return (1);
 
6793
                
 
6794
         for (i = 0; i < crop->selections; i++)
 
6795
           {
 
6796
           crop_buff = seg_buffs[i].buffer;
 
6797
           /* Write the current region to the current file */
 
6798
           if (writeCroppedImage(in, *out, image, dump,
 
6799
                                 crop->regionlist[i].width, 
 
6800
                                 crop->regionlist[i].length, 
 
6801
                                 crop_buff, *page, page_count))
 
6802
             {
 
6803
             TIFFError("writeRegions", "Unable to write new image");
 
6804
             return (-1);
 
6805
             }
 
6806
           }
 
6807
         break;
 
6808
    case FILE_PER_SELECTION:
 
6809
         autoindex = 1;
 
6810
         page_count = 1;
 
6811
         for (i = 0; i < crop->selections; i++)
 
6812
           {
 
6813
           if (update_output_file (out, mp, autoindex, filename, page))
 
6814
             return (1);
 
6815
 
 
6816
           crop_buff = seg_buffs[i].buffer;
 
6817
           /* Write the current region to the current file */
 
6818
           if (writeCroppedImage(in, *out, image, dump,
 
6819
                                 crop->regionlist[i].width, 
 
6820
                                 crop->regionlist[i].length, 
 
6821
                                 crop_buff, *page, page_count))
 
6822
             {
 
6823
             TIFFError("writeRegions", "Unable to write new image");
 
6824
             return (-1);
 
6825
             }
 
6826
           }
 
6827
         break;
 
6828
    default: return (1);
 
6829
    }
 
6830
 
 
6831
  return (0);
 
6832
  } /* end writeRegions */
 
6833
 
 
6834
static int
 
6835
writeImageSections(TIFF *in, TIFF *out, struct image_data *image,
 
6836
                   struct pagedef *page, struct pageseg *sections,
 
6837
                   struct dump_opts * dump, unsigned char *src_buff,
 
6838
                   unsigned char **sect_buff_ptr)
 
6839
  {
 
6840
  double  hres, vres;
 
6841
  uint32  i, k, width, length, sectsize;
 
6842
  unsigned char *sect_buff = *sect_buff_ptr;
 
6843
 
 
6844
  hres = page->hres;
 
6845
  vres = page->vres;
 
6846
 
 
6847
  k = page->cols * page->rows;
 
6848
  if ((k < 1) || (k > MAX_SECTIONS))
 
6849
   {
 
6850
   TIFFError("writeImageSections",
 
6851
             "%d Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections", k);
 
6852
   return (-1);
 
6853
   }
 
6854
 
 
6855
  for (i = 0; i < k; i++)
 
6856
    {
 
6857
    width  = sections[i].x2 - sections[i].x1 + 1;
 
6858
    length = sections[i].y2 - sections[i].y1 + 1;
 
6859
    sectsize = (uint32)
 
6860
            ceil((width * image->bps + 7) / (double)8) * image->spp * length;
 
6861
    /* allocate a buffer if we don't have one already */
 
6862
    if (createImageSection(sectsize, sect_buff_ptr))
 
6863
      {
 
6864
      TIFFError("writeImageSections", "Unable to allocate section buffer");
 
6865
      exit (-1);
 
6866
      }
 
6867
    sect_buff = *sect_buff_ptr;
 
6868
 
 
6869
    if (extractImageSection (image, &sections[i], src_buff, sect_buff))
 
6870
      {
 
6871
      TIFFError("writeImageSections", "Unable to extract image sections");
 
6872
      exit (-1);
 
6873
      }
 
6874
 
 
6875
  /* call the write routine here instead of outside the loop */
 
6876
    if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff))
 
6877
      {
 
6878
      TIFFError("writeImageSections", "Unable to write image section");
 
6879
      exit (-1);
 
6880
      }
 
6881
    }
 
6882
 
 
6883
  return (0);
 
6884
  } /* end writeImageSections */
 
6885
 
 
6886
/* Code in this function is heavily indebted to code in tiffcp
 
6887
 * with modifications by Richard Nolde to handle orientation correctly.
 
6888
 * It will have to be updated significantly if support is added to
 
6889
 * extract one or more samples from original image since the 
 
6890
 * original code assumes we are always copying all samples.
 
6891
 */
 
6892
static int  
 
6893
writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
 
6894
                   struct dump_opts *dump, uint32 width, uint32 length,
 
6895
                   double hres, double vres,
 
6896
                   unsigned char *sect_buff)
 
6897
  {
 
6898
  uint16 bps, spp;
 
6899
  uint16 input_compression, input_photometric;
 
6900
  uint16 input_planar;
 
6901
  struct cpTag* p;
 
6902
 
 
6903
  /*  Calling this seems to reset the compression mode on the TIFF *in file.
 
6904
  TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
 
6905
  */
 
6906
  input_compression = image->compression;
 
6907
  input_photometric = image->photometric;
 
6908
 
 
6909
  spp = image->spp;
 
6910
  bps = image->bps;
 
6911
  TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
 
6912
  TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
 
6913
  TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
 
6914
  TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
 
6915
 
 
6916
#ifdef DEBUG2
 
6917
  TIFFError("writeSingleSection", "Input compression: %s",
 
6918
            (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
 
6919
            ((input_compression == COMPRESSION_JPEG) ?  "New Jpeg" : "Non Jpeg"));
 
6920
#endif
 
6921
  /* This is the global variable compression which is set 
 
6922
   * if the user has specified a command line option for 
 
6923
   * a compression option.  Should be passed around in one
 
6924
   * of the parameters instead of as a global. If no user
 
6925
   * option specified it will still be (uint16) -1. */
 
6926
  if (compression != (uint16)-1)
 
6927
    TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
6928
  else
 
6929
    { /* OJPEG is no longer supported for writing so upgrade to JPEG */
 
6930
    if (input_compression == COMPRESSION_OJPEG)
 
6931
      {
 
6932
      compression = COMPRESSION_JPEG;
 
6933
      jpegcolormode = JPEGCOLORMODE_RAW;
 
6934
      TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
 
6935
      }
 
6936
    else /* Use the compression from the input file */
 
6937
      TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
6938
    }
 
6939
 
 
6940
  if (compression == COMPRESSION_JPEG)
 
6941
    {
 
6942
    if ((input_photometric == PHOTOMETRIC_PALETTE) ||  /* color map indexed */
 
6943
        (input_photometric == PHOTOMETRIC_MASK))       /* holdout mask */
 
6944
      {
 
6945
      TIFFError ("writeSingleSection",
 
6946
                 "JPEG compression cannot be used with %s image data",
 
6947
                 (input_photometric == PHOTOMETRIC_PALETTE) ?
 
6948
                 "palette" : "mask");
 
6949
      return (-1);
 
6950
      }
 
6951
    if ((input_photometric == PHOTOMETRIC_RGB) &&
 
6952
        (jpegcolormode == JPEGCOLORMODE_RGB))
 
6953
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
 
6954
    else
 
6955
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
 
6956
    }
 
6957
  else
 
6958
    {
 
6959
    if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
 
6960
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
 
6961
                        PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
6962
    else
 
6963
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
 
6964
    }
 
6965
 
 
6966
#ifdef DEBUG2
 
6967
  TIFFError("writeSingleSection", "Input photometric: %s",
 
6968
            (input_photometric == PHOTOMETRIC_RGB) ? "RGB" :
 
6969
            ((input_photometric == PHOTOMETRIC_YCBCR) ?  "YCbCr" : "Not RGB or YCbCr"));
 
6970
#endif
 
6971
 
 
6972
  if (((input_photometric == PHOTOMETRIC_LOGL) ||
 
6973
       (input_photometric ==  PHOTOMETRIC_LOGLUV)) &&
 
6974
      ((compression != COMPRESSION_SGILOG) && 
 
6975
       (compression != COMPRESSION_SGILOG24)))
 
6976
    {
 
6977
    TIFFError("writeSingleSection",
 
6978
              "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
 
6979
    return (-1);
 
6980
    }
 
6981
 
 
6982
  if (fillorder != 0)
 
6983
    TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
 
6984
  else
 
6985
    CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
 
6986
 
 
6987
  /* The loadimage function reads input orientation and sets
 
6988
   * image->orientation. The correct_image_orientation function
 
6989
   * applies the required rotation and mirror operations to 
 
6990
   * present the data in TOPLEFT orientation and updates 
 
6991
   * image->orientation if any transforms are performed, 
 
6992
   * as per EXIF standard.
 
6993
   */
 
6994
  TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
 
6995
 
 
6996
  /*
 
6997
   * Choose tiles/strip for the output image according to
 
6998
   * the command line arguments (-tiles, -strips) and the
 
6999
   * structure of the input image.
 
7000
   */
 
7001
  if (outtiled == -1)
 
7002
    outtiled = TIFFIsTiled(in);
 
7003
  if (outtiled) {
 
7004
    /*
 
7005
     * Setup output file's tile width&height.  If either
 
7006
     * is not specified, use either the value from the
 
7007
     * input image or, if nothing is defined, use the
 
7008
     * library default.
 
7009
     */
 
7010
    if (tilewidth == (uint32) 0)
 
7011
      TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
 
7012
    if (tilelength == (uint32) 0)
 
7013
      TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
 
7014
 
 
7015
    if (tilewidth == 0 || tilelength == 0)
 
7016
      TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
7017
    TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
7018
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
 
7019
    TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
 
7020
    } else {
 
7021
       /*
 
7022
        * RowsPerStrip is left unspecified: use either the
 
7023
        * value from the input image or, if nothing is defined,
 
7024
        * use the library default.
 
7025
        */
 
7026
        if (rowsperstrip == (uint32) 0)
 
7027
          {
 
7028
          if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
 
7029
            rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
 
7030
          if (compression != COMPRESSION_JPEG)
 
7031
            {
 
7032
            if (rowsperstrip > length)
 
7033
              rowsperstrip = length;
 
7034
            }
 
7035
          }
 
7036
        else 
 
7037
          if (rowsperstrip == (uint32) -1)
 
7038
            rowsperstrip = length;
 
7039
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
7040
        }
 
7041
 
 
7042
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
 
7043
  if (config != (uint16) -1)
 
7044
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
7045
  else
 
7046
    CopyField(TIFFTAG_PLANARCONFIG, config);
 
7047
  if (spp <= 4)
 
7048
    CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
 
7049
  CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
 
7050
 
 
7051
/* SMinSampleValue & SMaxSampleValue */
 
7052
  switch (compression) {
 
7053
    /* These are references to GLOBAL variables set by defaults
 
7054
     * and /or the compression flag
 
7055
     */
 
7056
    case COMPRESSION_JPEG:
 
7057
         if (((bps % 8) == 0) || ((bps % 12) == 0))
 
7058
           {
 
7059
           TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
7060
           TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
7061
           }
 
7062
         else
 
7063
           {
 
7064
           TIFFError("writeSingleSection",
 
7065
                     "JPEG compression requires 8 or 12 bits per sample");
 
7066
           return (-1);
 
7067
           }
 
7068
         break;
 
7069
   case COMPRESSION_LZW:
 
7070
   case COMPRESSION_ADOBE_DEFLATE:
 
7071
   case COMPRESSION_DEFLATE:
 
7072
        if (predictor != (uint16)-1)
 
7073
          TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
7074
        else
 
7075
          CopyField(TIFFTAG_PREDICTOR, predictor);
 
7076
        break;
 
7077
   case COMPRESSION_CCITTFAX3:
 
7078
   case COMPRESSION_CCITTFAX4:
 
7079
        if (compression == COMPRESSION_CCITTFAX3) {
 
7080
          if (g3opts != (uint32) -1)
 
7081
            TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
 
7082
          else
 
7083
            CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
 
7084
        } else
 
7085
            CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
 
7086
            CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
 
7087
            CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
 
7088
            CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
 
7089
            CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
 
7090
            CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
 
7091
            CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
 
7092
        break;
 
7093
   }
 
7094
   { uint32 len32;
 
7095
     void** data;
 
7096
     if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
 
7097
       TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
 
7098
   }
 
7099
   { uint16 ninks;
 
7100
     const char* inknames;
 
7101
     if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
 
7102
       TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
 
7103
       if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
 
7104
         int inknameslen = strlen(inknames) + 1;
 
7105
         const char* cp = inknames;
 
7106
         while (ninks > 1) {
 
7107
           cp = strchr(cp, '\0');
 
7108
           if (cp) {
 
7109
             cp++;
 
7110
             inknameslen += (strlen(cp) + 1);
 
7111
           }
 
7112
           ninks--;
 
7113
         }
 
7114
         TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
 
7115
       }
 
7116
     }
 
7117
   }
 
7118
   {
 
7119
   unsigned short pg0, pg1;
 
7120
   if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
 
7121
     if (pageNum < 0) /* only one input file */
 
7122
        TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
 
7123
     else 
 
7124
        TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
 
7125
     }
 
7126
   }
 
7127
 
 
7128
  for (p = tags; p < &tags[NTAGS]; p++)
 
7129
                CopyTag(p->tag, p->count, p->type);
 
7130
 
 
7131
  /* Update these since they are overwritten from input res by loop above */
 
7132
  TIFFSetField(out, TIFFTAG_XRESOLUTION, (float)hres);
 
7133
  TIFFSetField(out, TIFFTAG_YRESOLUTION, (float)vres);
 
7134
 
 
7135
  /* Compute the tile or strip dimensions and write to disk */
 
7136
  if (outtiled)
 
7137
    {
 
7138
    if (config == PLANARCONFIG_CONTIG)
 
7139
      writeBufferToContigTiles (out, sect_buff, length, width, spp, dump);
 
7140
    else
 
7141
      writeBufferToSeparateTiles (out, sect_buff, length, width, spp, dump);
 
7142
    }
 
7143
  else
 
7144
    {
 
7145
    if (config == PLANARCONFIG_CONTIG)
 
7146
      writeBufferToContigStrips (out, sect_buff, length);
 
7147
    else
 
7148
      writeBufferToSeparateStrips(out, sect_buff, length, width, spp, dump);
 
7149
    }
 
7150
 
 
7151
  if (!TIFFWriteDirectory(out))
 
7152
    {
 
7153
    TIFFClose(out);
 
7154
    return (-1);
 
7155
    }
 
7156
 
 
7157
  return (0);
 
7158
  } /* end writeSingleSection */
 
7159
 
 
7160
 
 
7161
/* Create a buffer to write one section at a time */
 
7162
static int
 
7163
createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
 
7164
  {
 
7165
  unsigned  char *sect_buff = NULL;
 
7166
  unsigned  char *new_buff  = NULL;
 
7167
  static    uint32  prev_sectsize = 0;
 
7168
  
 
7169
  sect_buff = *sect_buff_ptr;
 
7170
 
 
7171
  if (!sect_buff)
 
7172
    {
 
7173
    sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
 
7174
    *sect_buff_ptr = sect_buff;
 
7175
    _TIFFmemset(sect_buff, 0, sectsize);
 
7176
    }
 
7177
  else
 
7178
    {
 
7179
    if (prev_sectsize < sectsize)
 
7180
      {
 
7181
      new_buff = _TIFFrealloc(sect_buff, sectsize);
 
7182
      if (!new_buff)
 
7183
        {
 
7184
        free (sect_buff);
 
7185
        sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
 
7186
        }
 
7187
      else
 
7188
        sect_buff = new_buff;
 
7189
 
 
7190
      _TIFFmemset(sect_buff, 0, sectsize);
 
7191
      }
 
7192
    }
 
7193
 
 
7194
  if (!sect_buff)
 
7195
    {
 
7196
    TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
 
7197
    return (-1);
 
7198
    }
 
7199
  prev_sectsize = sectsize;
 
7200
  *sect_buff_ptr = sect_buff;
 
7201
 
 
7202
  return (0);
 
7203
  }  /* end createImageSection */
 
7204
 
 
7205
 
 
7206
/* Process selections defined by regions, zones, margins, or fixed sized areas */
 
7207
static int
 
7208
processCropSelections(struct image_data *image, struct crop_mask *crop, 
 
7209
                      unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
 
7210
  {
 
7211
  int       i;
 
7212
  uint32    width, length, total_width, total_length;
 
7213
  tsize_t   cropsize;
 
7214
  unsigned  char *crop_buff = NULL;
 
7215
  unsigned  char *read_buff = NULL;
 
7216
  unsigned  char *next_buff = NULL;
 
7217
  tsize_t   prev_cropsize = 0;
 
7218
 
 
7219
  read_buff = *read_buff_ptr;
 
7220
 
 
7221
  if (crop->img_mode == COMPOSITE_IMAGES)
 
7222
    {
 
7223
    cropsize = crop->bufftotal;
 
7224
    crop_buff = seg_buffs[0].buffer; 
 
7225
    if (!crop_buff)
 
7226
      crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7227
    else
 
7228
      {
 
7229
      prev_cropsize = seg_buffs[0].size;
 
7230
      if (prev_cropsize < cropsize)
 
7231
        {
 
7232
        next_buff = _TIFFrealloc(crop_buff, cropsize);
 
7233
        if (! next_buff)
 
7234
          {
 
7235
          _TIFFfree (crop_buff);
 
7236
          crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7237
          }
 
7238
        else
 
7239
          crop_buff = next_buff;
 
7240
        }
 
7241
      }
 
7242
 
 
7243
    if (!crop_buff)
 
7244
      {
 
7245
      TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
 
7246
      return (-1);
 
7247
      }
 
7248
 
 
7249
    _TIFFmemset(crop_buff, 0, cropsize);
 
7250
    seg_buffs[0].buffer = crop_buff;
 
7251
    seg_buffs[0].size = cropsize;
 
7252
 
 
7253
    /* Checks for matching width or length as required */
 
7254
    if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
 
7255
      return (1);
 
7256
 
 
7257
    if (crop->crop_mode & CROP_INVERT)
 
7258
      {
 
7259
      switch (crop->photometric)
 
7260
        {
 
7261
        /* Just change the interpretation */
 
7262
        case PHOTOMETRIC_MINISWHITE:
 
7263
        case PHOTOMETRIC_MINISBLACK:
 
7264
             image->photometric = crop->photometric;
 
7265
             break;
 
7266
        case INVERT_DATA_ONLY:
 
7267
        case INVERT_DATA_AND_TAG:
 
7268
             if (invertImage(image->photometric, image->spp, image->bps, 
 
7269
                             crop->combined_width, crop->combined_length, crop_buff))
 
7270
               {
 
7271
               TIFFError("processCropSelections", 
 
7272
                         "Failed to invert colorspace for composite regions");
 
7273
               return (-1);
 
7274
               }
 
7275
             if (crop->photometric == INVERT_DATA_AND_TAG)
 
7276
               {
 
7277
               switch (image->photometric)
 
7278
                 {
 
7279
                 case PHOTOMETRIC_MINISWHITE:
 
7280
                      image->photometric = PHOTOMETRIC_MINISBLACK;
 
7281
                      break;
 
7282
                 case PHOTOMETRIC_MINISBLACK:
 
7283
                      image->photometric = PHOTOMETRIC_MINISWHITE;
 
7284
                      break;
 
7285
                 default:
 
7286
                      break;
 
7287
                 }
 
7288
               }
 
7289
             break;
 
7290
        default: break;
 
7291
        }
 
7292
      }
 
7293
 
 
7294
    /* Mirror and Rotate will not work with multiple regions unless they are the same width */
 
7295
    if (crop->crop_mode & CROP_MIRROR)
 
7296
      {
 
7297
      if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
7298
                      crop->combined_width, crop->combined_length, crop_buff))
 
7299
        {
 
7300
        TIFFError("processCropSelections", "Failed to mirror composite regions %s", 
 
7301
                 (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
7302
        return (-1);
 
7303
        }
 
7304
      }
 
7305
 
 
7306
    if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
7307
      {
 
7308
      if (rotateImage(crop->rotation, image, &crop->combined_width, 
 
7309
                      &crop->combined_length, &crop_buff))
 
7310
        {
 
7311
        TIFFError("processCropSelections", 
 
7312
                  "Failed to rotate composite regions by %d degrees", crop->rotation);
 
7313
        return (-1);
 
7314
        }
 
7315
      seg_buffs[0].buffer = crop_buff;
 
7316
      seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
 
7317
                            * image->spp) * crop->combined_length; 
 
7318
      }
 
7319
    }
 
7320
  else  /* Separated Images */
 
7321
    {
 
7322
    total_width = total_length = 0;
 
7323
    for (i = 0; i < crop->selections; i++)
 
7324
      {
 
7325
      cropsize = crop->bufftotal;
 
7326
      crop_buff = seg_buffs[i].buffer; 
 
7327
      if (!crop_buff)
 
7328
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7329
      else
 
7330
        {
 
7331
        prev_cropsize = seg_buffs[0].size;
 
7332
        if (prev_cropsize < cropsize)
 
7333
          {
 
7334
          next_buff = _TIFFrealloc(crop_buff, cropsize);
 
7335
          if (! next_buff)
 
7336
            {
 
7337
            _TIFFfree (crop_buff);
 
7338
            crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7339
            }
 
7340
          else
 
7341
            crop_buff = next_buff;
 
7342
          }
 
7343
        }
 
7344
 
 
7345
      if (!crop_buff)
 
7346
        {
 
7347
        TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
 
7348
        return (-1);
 
7349
        }
 
7350
 
 
7351
      _TIFFmemset(crop_buff, 0, cropsize);
 
7352
      seg_buffs[i].buffer = crop_buff;
 
7353
      seg_buffs[i].size = cropsize;
 
7354
 
 
7355
      if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
 
7356
        {
 
7357
        TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
 
7358
        return (-1);
 
7359
        }
 
7360
    
 
7361
      width  = crop->regionlist[i].width;
 
7362
      length = crop->regionlist[i].length;
 
7363
 
 
7364
      if (crop->crop_mode & CROP_INVERT)
 
7365
        {
 
7366
        switch (crop->photometric)
 
7367
          {
 
7368
          /* Just change the interpretation */
 
7369
          case PHOTOMETRIC_MINISWHITE:
 
7370
          case PHOTOMETRIC_MINISBLACK:
 
7371
               image->photometric = crop->photometric;
 
7372
               break;
 
7373
          case INVERT_DATA_ONLY:
 
7374
          case INVERT_DATA_AND_TAG:
 
7375
               if (invertImage(image->photometric, image->spp, image->bps, 
 
7376
                               width, length, crop_buff))
 
7377
                 {
 
7378
                 TIFFError("processCropSelections", 
 
7379
                           "Failed to invert colorspace for region");
 
7380
                 return (-1);
 
7381
                 }
 
7382
               if (crop->photometric == INVERT_DATA_AND_TAG)
 
7383
                 {
 
7384
                 switch (image->photometric)
 
7385
                   {
 
7386
                   case PHOTOMETRIC_MINISWHITE:
 
7387
                        image->photometric = PHOTOMETRIC_MINISBLACK;
 
7388
                        break;
 
7389
                   case PHOTOMETRIC_MINISBLACK:
 
7390
                        image->photometric = PHOTOMETRIC_MINISWHITE;
 
7391
                        break;
 
7392
                   default:
 
7393
                        break;
 
7394
                   }
 
7395
                 }
 
7396
               break;
 
7397
          default: break;
 
7398
          }
 
7399
        }
 
7400
 
 
7401
      if (crop->crop_mode & CROP_MIRROR)
 
7402
        {
 
7403
        if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
7404
                        width, length, crop_buff))
 
7405
          {
 
7406
          TIFFError("processCropSelections", "Failed to mirror crop region %s", 
 
7407
                   (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
7408
          return (-1);
 
7409
          }
 
7410
        }
 
7411
 
 
7412
      if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
7413
        {
 
7414
        if (rotateImage(crop->rotation, image, &crop->regionlist[i].width, 
 
7415
                        &crop->regionlist[i].length, &crop_buff))
 
7416
          {
 
7417
          TIFFError("processCropSelections", 
 
7418
                    "Failed to rotate crop region by %d degrees", crop->rotation);
 
7419
          return (-1);
 
7420
          }
 
7421
        total_width  += crop->regionlist[i].width;
 
7422
        total_length += crop->regionlist[i].length;
 
7423
        crop->combined_width = total_width;
 
7424
        crop->combined_length = total_length;
 
7425
        seg_buffs[i].buffer = crop_buff;
 
7426
        seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
 
7427
                               * image->spp) * crop->regionlist[i].length; 
 
7428
        }
 
7429
      }
 
7430
    }
 
7431
  return (0);
 
7432
  } /* end processCropSelections */
 
7433
 
 
7434
/* Copy the crop section of the data from the current image into a buffer
 
7435
 * and adjust the IFD values to reflect the new size. If no cropping is
 
7436
 * required, use the origial read buffer as the crop buffer.
 
7437
 *
 
7438
 * There is quite a bit of redundancy between this routine and the more
 
7439
 * specialized processCropSelections, but this provides
 
7440
 * the most optimized path when no Zones or Regions are required.
 
7441
 */
 
7442
static int
 
7443
createCroppedImage(struct image_data *image, struct crop_mask *crop, 
 
7444
                   unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
 
7445
  {
 
7446
  tsize_t   cropsize;
 
7447
  unsigned  char *read_buff = NULL;
 
7448
  unsigned  char *crop_buff = NULL;
 
7449
  unsigned  char *new_buff  = NULL;
 
7450
  static    tsize_t  prev_cropsize = 0;
 
7451
 
 
7452
  read_buff = *read_buff_ptr;
 
7453
 
 
7454
  /* process full image, no crop buffer needed */
 
7455
  crop_buff = read_buff;
 
7456
  *crop_buff_ptr = read_buff;
 
7457
  crop->combined_width = image->width;
 
7458
  crop->combined_length = image->length;
 
7459
 
 
7460
  cropsize = crop->bufftotal;
 
7461
  crop_buff = *crop_buff_ptr;
 
7462
  if (!crop_buff)
 
7463
    {
 
7464
    crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7465
    *crop_buff_ptr = crop_buff;
 
7466
    _TIFFmemset(crop_buff, 0, cropsize);
 
7467
    prev_cropsize = cropsize;
 
7468
    }
 
7469
  else
 
7470
    {
 
7471
    if (prev_cropsize < cropsize)
 
7472
      {
 
7473
      new_buff = _TIFFrealloc(crop_buff, cropsize);
 
7474
      if (!new_buff)
 
7475
        {
 
7476
        free (crop_buff);
 
7477
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
 
7478
        }
 
7479
      else
 
7480
        crop_buff = new_buff;
 
7481
      _TIFFmemset(crop_buff, 0, cropsize);
 
7482
      }
 
7483
    }
 
7484
 
 
7485
  if (!crop_buff)
 
7486
    {
 
7487
    TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
 
7488
    return (-1);
 
7489
    }
 
7490
  *crop_buff_ptr = crop_buff;
 
7491
 
 
7492
  if (crop->crop_mode & CROP_INVERT)
 
7493
    {
 
7494
    switch (crop->photometric)
 
7495
      {
 
7496
      /* Just change the interpretation */
 
7497
      case PHOTOMETRIC_MINISWHITE:
 
7498
      case PHOTOMETRIC_MINISBLACK:
 
7499
           image->photometric = crop->photometric;
 
7500
           break;
 
7501
      case INVERT_DATA_ONLY:
 
7502
      case INVERT_DATA_AND_TAG:
 
7503
           if (invertImage(image->photometric, image->spp, image->bps, 
 
7504
                           crop->combined_width, crop->combined_length, crop_buff))
 
7505
             {
 
7506
             TIFFError("createCroppedImage", 
 
7507
                       "Failed to invert colorspace for image or cropped selection");
 
7508
             return (-1);
 
7509
             }
 
7510
           if (crop->photometric == INVERT_DATA_AND_TAG)
 
7511
             {
 
7512
             switch (image->photometric)
 
7513
               {
 
7514
               case PHOTOMETRIC_MINISWHITE:
 
7515
                    image->photometric = PHOTOMETRIC_MINISBLACK;
 
7516
                    break;
 
7517
               case PHOTOMETRIC_MINISBLACK:
 
7518
                    image->photometric = PHOTOMETRIC_MINISWHITE;
 
7519
                    break;
 
7520
               default:
 
7521
                    break;
 
7522
               }
 
7523
             }
 
7524
           break;
 
7525
      default: break;
 
7526
      }
 
7527
    }
 
7528
 
 
7529
  if (crop->crop_mode & CROP_MIRROR)
 
7530
    {
 
7531
    if (mirrorImage(image->spp, image->bps, crop->mirror, 
 
7532
                    crop->combined_width, crop->combined_length, crop_buff))
 
7533
      {
 
7534
      TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s", 
 
7535
               (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
 
7536
      return (-1);
 
7537
      }
 
7538
    }
 
7539
 
 
7540
  if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
 
7541
    {
 
7542
    if (rotateImage(crop->rotation, image, &crop->combined_width, 
 
7543
                    &crop->combined_length, crop_buff_ptr))
 
7544
      {
 
7545
      TIFFError("createCroppedImage", 
 
7546
                "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
 
7547
      return (-1);
 
7548
      }
 
7549
    }
 
7550
 
 
7551
  if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
 
7552
    *read_buff_ptr = NULL;    /* so we don't try to free it later */
 
7553
 
 
7554
  return (0);
 
7555
  } /* end createCroppedImage */
 
7556
 
 
7557
 
 
7558
/* Code in this function is heavily indebted to code in tiffcp
 
7559
 * with modifications by Richard Nolde to handle orientation correctly.
 
7560
 * It will have to be updated significantly if support is added to
 
7561
 * extract one or more samples from original image since the 
 
7562
 * original code assumes we are always copying all samples.
 
7563
 * Use of global variables for config, compression and others
 
7564
 * should be replaced by addition to the crop_mask struct (which
 
7565
 * will be renamed to proc_opts indicating that is controlls
 
7566
 * user supplied processing options, not just cropping) and 
 
7567
 * then passed in as an argument.
 
7568
 */
 
7569
static int  
 
7570
writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image, 
 
7571
                  struct dump_opts *dump, uint32 width, uint32 length, 
 
7572
                  unsigned char *crop_buff, int pagenum, int total_pages)
 
7573
  {
 
7574
  uint16 bps, spp;
 
7575
  uint16 input_compression, input_photometric;
 
7576
  uint16 input_planar;
 
7577
  struct cpTag* p;
 
7578
 
 
7579
  input_compression = image->compression;
 
7580
  input_photometric = image->photometric;
 
7581
  spp = image->spp;
 
7582
  bps = image->bps;
 
7583
 
 
7584
  TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
 
7585
  TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
 
7586
  TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bps);
 
7587
  TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
 
7588
 
 
7589
#ifdef DEBUG2
 
7590
  TIFFError("writeCroppedImage", "Input compression: %s",
 
7591
            (input_compression == COMPRESSION_OJPEG) ? "Old Jpeg" :
 
7592
            ((input_compression == COMPRESSION_JPEG) ?  "New Jpeg" : "Non Jpeg"));
 
7593
#endif
 
7594
 
 
7595
  if (compression != (uint16)-1)
 
7596
    TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
7597
  else
 
7598
    {
 
7599
    if (input_compression == COMPRESSION_OJPEG)
 
7600
      {
 
7601
      compression = COMPRESSION_JPEG;
 
7602
      jpegcolormode = JPEGCOLORMODE_RAW;
 
7603
      TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
 
7604
      }
 
7605
    else
 
7606
      CopyField(TIFFTAG_COMPRESSION, compression);
 
7607
    }
 
7608
 
 
7609
  if (compression == COMPRESSION_JPEG)
 
7610
    {
 
7611
    if ((input_photometric == PHOTOMETRIC_PALETTE) ||  /* color map indexed */
 
7612
        (input_photometric == PHOTOMETRIC_MASK))       /* $holdout mask */
 
7613
      {
 
7614
      TIFFError ("writeCroppedImage",
 
7615
                 "JPEG compression cannot be used with %s image data",
 
7616
                (input_photometric == PHOTOMETRIC_PALETTE) ?
 
7617
                 "palette" : "mask");
 
7618
      return (-1);
 
7619
      }
 
7620
    if ((input_photometric == PHOTOMETRIC_RGB) &&
 
7621
        (jpegcolormode == JPEGCOLORMODE_RGB))
 
7622
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
 
7623
    else
 
7624
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
 
7625
    }
 
7626
  else
 
7627
    {
 
7628
    if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
 
7629
      {
 
7630
      TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
 
7631
                        PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
7632
      }
 
7633
    else
 
7634
      {
 
7635
      if (input_compression == COMPRESSION_SGILOG ||
 
7636
          input_compression == COMPRESSION_SGILOG24)
 
7637
        {
 
7638
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, spp == 1 ?
 
7639
                          PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
7640
        }
 
7641
      else
 
7642
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, image->photometric);
 
7643
      }
 
7644
    }
 
7645
 
 
7646
  if (((input_photometric == PHOTOMETRIC_LOGL) ||
 
7647
       (input_photometric ==  PHOTOMETRIC_LOGLUV)) &&
 
7648
      ((compression != COMPRESSION_SGILOG) && 
 
7649
       (compression != COMPRESSION_SGILOG24)))
 
7650
    {
 
7651
    TIFFError("writeCroppedImage",
 
7652
              "LogL and LogLuv source data require SGI_LOG or SGI_LOG24 compression");
 
7653
    return (-1);
 
7654
    }
 
7655
 
 
7656
  if (fillorder != 0)
 
7657
    TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
 
7658
  else
 
7659
    CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
 
7660
 
 
7661
  /* The loadimage function reads input orientation and sets
 
7662
   * image->orientation. The correct_image_orientation function
 
7663
   * applies the required rotation and mirror operations to 
 
7664
   * present the data in TOPLEFT orientation and updates 
 
7665
   * image->orientation if any transforms are performed, 
 
7666
   * as per EXIF standard. 
 
7667
   */
 
7668
  TIFFSetField(out, TIFFTAG_ORIENTATION, image->orientation);
 
7669
        
 
7670
  /*
 
7671
   * Choose tiles/strip for the output image according to
 
7672
   * the command line arguments (-tiles, -strips) and the
 
7673
   * structure of the input image.
 
7674
   */
 
7675
  if (outtiled == -1)
 
7676
    outtiled = TIFFIsTiled(in);
 
7677
  if (outtiled) {
 
7678
    /*
 
7679
     * Setup output file's tile width&height.  If either
 
7680
     * is not specified, use either the value from the
 
7681
     * input image or, if nothing is defined, use the
 
7682
     * library default.
 
7683
     */
 
7684
    if (tilewidth == (uint32) 0)
 
7685
      TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
 
7686
    if (tilelength == (uint32) 0)
 
7687
      TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
 
7688
 
 
7689
    if (tilewidth == 0 || tilelength == 0)
 
7690
      TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
7691
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
 
7692
    TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
 
7693
    } else {
 
7694
       /*
 
7695
        * RowsPerStrip is left unspecified: use either the
 
7696
        * value from the input image or, if nothing is defined,
 
7697
        * use the library default.
 
7698
        */
 
7699
        if (rowsperstrip == (uint32) 0)
 
7700
          {
 
7701
          if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
 
7702
            rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
 
7703
          if (compression != COMPRESSION_JPEG)
 
7704
            {
 
7705
            if (rowsperstrip > length)
 
7706
              rowsperstrip = length;
 
7707
            }
 
7708
          }
 
7709
        else 
 
7710
          if (rowsperstrip == (uint32) -1)
 
7711
            rowsperstrip = length;
 
7712
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
7713
        }
 
7714
 
 
7715
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &input_planar);
 
7716
  if (config != (uint16) -1)
 
7717
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
7718
  else
 
7719
    CopyField(TIFFTAG_PLANARCONFIG, config);
 
7720
  if (spp <= 4)
 
7721
    CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
 
7722
  CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
 
7723
 
 
7724
/* SMinSampleValue & SMaxSampleValue */
 
7725
  switch (compression) {
 
7726
    case COMPRESSION_JPEG:
 
7727
         if (((bps % 8) == 0) || ((bps % 12) == 0))
 
7728
           {
 
7729
           TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
7730
           TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
7731
           }
 
7732
         else
 
7733
           {
 
7734
           TIFFError("writeCroppedImage",
 
7735
                     "JPEG compression requires 8 or 12 bits per sample");
 
7736
           return (-1);
 
7737
           }
 
7738
         break;
 
7739
   case COMPRESSION_LZW:
 
7740
   case COMPRESSION_ADOBE_DEFLATE:
 
7741
   case COMPRESSION_DEFLATE:
 
7742
        if (predictor != (uint16)-1)
 
7743
          TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
7744
        else
 
7745
          CopyField(TIFFTAG_PREDICTOR, predictor);
 
7746
        break;
 
7747
   case COMPRESSION_CCITTFAX3:
 
7748
   case COMPRESSION_CCITTFAX4:
 
7749
        if (bps != 1)
 
7750
          {
 
7751
          TIFFError("writeCroppedImage",
 
7752
            "Group 3/4 compression is not usable with bps > 1");
 
7753
          return (-1);
 
7754
          }
 
7755
        if (compression == COMPRESSION_CCITTFAX3) {
 
7756
          if (g3opts != (uint32) -1)
 
7757
            TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
 
7758
          else
 
7759
            CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
 
7760
        } else
 
7761
            CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
 
7762
            CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
 
7763
            CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
 
7764
            CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
 
7765
            CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
 
7766
            CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
 
7767
            CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
 
7768
         break;
 
7769
    case COMPRESSION_NONE:
 
7770
         break;
 
7771
    default: break;
 
7772
   }
 
7773
   { uint32 len32;
 
7774
     void** data;
 
7775
     if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
 
7776
       TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
 
7777
   }
 
7778
   { uint16 ninks;
 
7779
     const char* inknames;
 
7780
     if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
 
7781
       TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
 
7782
       if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
 
7783
         int inknameslen = strlen(inknames) + 1;
 
7784
         const char* cp = inknames;
 
7785
         while (ninks > 1) {
 
7786
           cp = strchr(cp, '\0');
 
7787
           if (cp) {
 
7788
             cp++;
 
7789
             inknameslen += (strlen(cp) + 1);
 
7790
           }
 
7791
           ninks--;
 
7792
         }
 
7793
         TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
 
7794
       }
 
7795
     }
 
7796
   }
 
7797
   {
 
7798
   unsigned short pg0, pg1;
 
7799
   if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
 
7800
     TIFFSetField(out, TIFFTAG_PAGENUMBER, pagenum, total_pages);
 
7801
     }
 
7802
   }
 
7803
 
 
7804
  for (p = tags; p < &tags[NTAGS]; p++)
 
7805
                CopyTag(p->tag, p->count, p->type);
 
7806
 
 
7807
  /* Compute the tile or strip dimensions and write to disk */
 
7808
  if (outtiled)
 
7809
    {
 
7810
    if (config == PLANARCONFIG_CONTIG)
 
7811
      {
 
7812
      if (writeBufferToContigTiles (out, crop_buff, length, width, spp, dump))
 
7813
        TIFFError("","Unable to write contiguous tile data for page %d", pagenum);
 
7814
      }
 
7815
    else
 
7816
      {
 
7817
      if (writeBufferToSeparateTiles (out, crop_buff, length, width, spp, dump))
 
7818
        TIFFError("","Unable to write separate tile data for page %d", pagenum);
 
7819
      }
 
7820
    }
 
7821
  else
 
7822
    {
 
7823
    if (config == PLANARCONFIG_CONTIG)
 
7824
      {
 
7825
      if (writeBufferToContigStrips (out, crop_buff, length))
 
7826
        TIFFError("","Unable to write contiguous strip data for page %d", pagenum);
 
7827
      }
 
7828
    else
 
7829
      {
 
7830
      if (writeBufferToSeparateStrips(out, crop_buff, length, width, spp, dump))
 
7831
        TIFFError("","Unable to write separate strip data for page %d", pagenum);
 
7832
      }
 
7833
    }
 
7834
 
 
7835
  if (!TIFFWriteDirectory(out))
 
7836
    {
 
7837
    TIFFError("","Failed to write IFD for page number %d", pagenum);
 
7838
    TIFFClose(out);
 
7839
    return (-1);
 
7840
    }
 
7841
 
 
7842
  return (0);
 
7843
  } /* end writeCroppedImage */
 
7844
 
 
7845
static int
 
7846
rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
7847
                         uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
7848
  {
 
7849
  int      ready_bits = 0;
 
7850
  uint32   src_byte = 0, src_bit = 0;
 
7851
  uint32   row, rowsize = 0, bit_offset = 0;
 
7852
  uint8    matchbits = 0, maskbits = 0;
 
7853
  uint8    buff1 = 0, buff2 = 0;
 
7854
  uint8   *next;
 
7855
  tsample_t sample;
 
7856
 
 
7857
  if ((src == NULL) || (dst == NULL))
 
7858
    {
 
7859
    TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
 
7860
    return (1);
 
7861
    }
 
7862
 
 
7863
  rowsize = ((bps * spp * width) + 7) / 8;
 
7864
  ready_bits = 0;
 
7865
  maskbits =  (uint8)-1 >> ( 8 - bps);
 
7866
  buff1 = buff2 = 0;
 
7867
 
 
7868
  for (row = 0; row < length ; row++)
 
7869
    {
 
7870
    bit_offset = col * bps * spp;
 
7871
    for (sample = 0; sample < spp; sample++)
 
7872
      {
 
7873
      if (sample == 0)
 
7874
        {
 
7875
        src_byte = bit_offset / 8;
 
7876
        src_bit  = bit_offset % 8;
 
7877
        }
 
7878
      else
 
7879
        {
 
7880
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7881
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7882
        }
 
7883
 
 
7884
      switch (rotation)
 
7885
        {
 
7886
        case  90: next = src + src_byte - (row * rowsize);
 
7887
                  break;
 
7888
        case 270: next = src + src_byte + (row * rowsize);
 
7889
                  break;
 
7890
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
7891
                  return (1);
 
7892
        }
 
7893
      matchbits = maskbits << (8 - src_bit - bps); 
 
7894
      buff1 = ((*next) & matchbits) << (src_bit);
 
7895
 
 
7896
       /* If we have a full buffer's worth, write it out */
 
7897
      if (ready_bits >= 8)
 
7898
        {
 
7899
        *dst++ = buff2;
 
7900
        buff2 = buff1;
 
7901
        ready_bits -= 8;
 
7902
        }
 
7903
      else
 
7904
        {
 
7905
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7906
        }
 
7907
      ready_bits += bps;
 
7908
      }
 
7909
    }
 
7910
 
 
7911
  if (ready_bits > 0)
 
7912
    {
 
7913
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
7914
    *dst++ = buff1;
 
7915
    }
 
7916
 
 
7917
  return (0);
 
7918
  }  /* end rotateContigSamples8bits */
 
7919
 
 
7920
 
 
7921
static int
 
7922
rotateContigSamples16bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
7923
                         uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
7924
  {
 
7925
  int      ready_bits = 0;
 
7926
  uint32   row, rowsize, bit_offset;
 
7927
  uint32   src_byte = 0, src_bit = 0;
 
7928
  uint16   matchbits = 0, maskbits = 0;
 
7929
  uint16   buff1 = 0, buff2 = 0;
 
7930
  uint8    bytebuff = 0;
 
7931
  uint8   *next;
 
7932
  tsample_t sample;
 
7933
 
 
7934
  if ((src == NULL) || (dst == NULL))
 
7935
    {
 
7936
    TIFFError("rotateContigSamples16bits","Invalid src or destination buffer");
 
7937
    return (1);
 
7938
    }
 
7939
 
 
7940
  rowsize = ((bps * spp * width) + 7) / 8;
 
7941
  ready_bits = 0;
 
7942
  maskbits =  (uint16)-1 >> (16 - bps);
 
7943
  buff1 = buff2 = 0;
 
7944
  for (row = 0; row < length; row++)
 
7945
    {
 
7946
    bit_offset = col * bps * spp;
 
7947
    for (sample = 0; sample < spp; sample++)
 
7948
      {
 
7949
      if (sample == 0)
 
7950
        {
 
7951
        src_byte = bit_offset / 8;
 
7952
        src_bit  = bit_offset % 8;
 
7953
        }
 
7954
      else
 
7955
        {
 
7956
        src_byte = (bit_offset + (sample * bps)) / 8;
 
7957
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
7958
        }
 
7959
 
 
7960
      switch (rotation)
 
7961
        {
 
7962
        case  90: next = src + src_byte - (row * rowsize);
 
7963
                  break;
 
7964
        case 270: next = src + src_byte + (row * rowsize);
 
7965
                  break;
 
7966
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
7967
                  return (1);
 
7968
        }
 
7969
      matchbits = maskbits << (16 - src_bit - bps); 
 
7970
      if (little_endian)
 
7971
        buff1 = (next[0] << 8) | next[1];
 
7972
      else
 
7973
        buff1 = (next[1] << 8) | next[0];
 
7974
 
 
7975
      buff1 = (buff1 & matchbits) << (src_bit);
 
7976
 
 
7977
      /* If we have a full buffer's worth, write it out */
 
7978
      if (ready_bits >= 8)
 
7979
        {
 
7980
        bytebuff = (buff2 >> 8);
 
7981
        *dst++ = bytebuff;
 
7982
        ready_bits -= 8;
 
7983
        /* shift in new bits */
 
7984
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
7985
        }
 
7986
      else
 
7987
        { /* add another bps bits to the buffer */
 
7988
        bytebuff = 0;
 
7989
        buff2 = (buff2 | (buff1 >> ready_bits));
 
7990
        }
 
7991
      ready_bits += bps;
 
7992
      }
 
7993
    }
 
7994
 
 
7995
  if (ready_bits > 0)
 
7996
    {
 
7997
    bytebuff = (buff2 >> 8);
 
7998
    *dst++ = bytebuff;
 
7999
    }
 
8000
 
 
8001
  return (0);
 
8002
  }  /* end rotateContigSamples16bits */
 
8003
 
 
8004
static int
 
8005
rotateContigSamples24bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
8006
                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
8007
  {
 
8008
  int      ready_bits = 0;
 
8009
  uint32   row, rowsize, bit_offset;
 
8010
  uint32   src_byte = 0, src_bit = 0;
 
8011
  uint32   matchbits = 0, maskbits = 0;
 
8012
  uint32   buff1 = 0, buff2 = 0;
 
8013
  uint8    bytebuff1 = 0, bytebuff2 = 0;
 
8014
  uint8   *next;
 
8015
  tsample_t sample;
 
8016
 
 
8017
 
 
8018
  if ((src == NULL) || (dst == NULL))
 
8019
    {
 
8020
    TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
 
8021
    return (1);
 
8022
    }
 
8023
 
 
8024
  rowsize = ((bps * spp * width) + 7) / 8;
 
8025
  ready_bits = 0;
 
8026
  maskbits =  (uint32)-1 >> (32 - bps);
 
8027
  buff1 = buff2 = 0;
 
8028
  for (row = 0; row < length; row++)
 
8029
    {
 
8030
    bit_offset = col * bps * spp;
 
8031
    for (sample = 0; sample < spp; sample++)
 
8032
      {
 
8033
      if (sample == 0)
 
8034
        {
 
8035
        src_byte = bit_offset / 8;
 
8036
        src_bit  = bit_offset % 8;
 
8037
        }
 
8038
      else
 
8039
        {
 
8040
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8041
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
8042
        }
 
8043
 
 
8044
      switch (rotation)
 
8045
        {
 
8046
        case  90: next = src + src_byte - (row * rowsize);
 
8047
                  break;
 
8048
        case 270: next = src + src_byte + (row * rowsize);
 
8049
                  break;
 
8050
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
8051
                  return (1);
 
8052
        }
 
8053
      matchbits = maskbits << (32 - src_bit - bps); 
 
8054
      if (little_endian)
 
8055
        buff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
 
8056
      else
 
8057
        buff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
 
8058
      buff1 = (buff1 & matchbits) << (src_bit);
 
8059
 
 
8060
      /* If we have a full buffer's worth, write it out */
 
8061
      if (ready_bits >= 16)
 
8062
        {
 
8063
        bytebuff1 = (buff2 >> 24);
 
8064
        *dst++ = bytebuff1;
 
8065
        bytebuff2 = (buff2 >> 16);
 
8066
        *dst++ = bytebuff2;
 
8067
        ready_bits -= 16;
 
8068
 
 
8069
        /* shift in new bits */
 
8070
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
8071
        }
 
8072
      else
 
8073
        { /* add another bps bits to the buffer */
 
8074
        bytebuff1 = bytebuff2 = 0;
 
8075
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8076
        }
 
8077
      ready_bits += bps;
 
8078
      }
 
8079
    }
 
8080
 
 
8081
 /* catch any trailing bits at the end of the line */
 
8082
  while (ready_bits > 0)
 
8083
    {
 
8084
    bytebuff1 = (buff2 >> 24);
 
8085
    *dst++ = bytebuff1;
 
8086
 
 
8087
    buff2 = (buff2 << 8);
 
8088
    bytebuff2 = bytebuff1;
 
8089
    ready_bits -= 8;
 
8090
    }
 
8091
 
 
8092
  return (0);
 
8093
  }  /* end rotateContigSamples24bits */
 
8094
 
 
8095
static int
 
8096
rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
 
8097
                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
 
8098
  {
 
8099
  int    ready_bits = 0, shift_width = 0;
 
8100
  int    bytes_per_sample, bytes_per_pixel;
 
8101
  uint32 row, rowsize, bit_offset;
 
8102
  uint32 src_byte, src_bit;
 
8103
  uint32 longbuff1 = 0, longbuff2 = 0;
 
8104
  uint64 maskbits = 0, matchbits = 0;
 
8105
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
8106
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
8107
  uint8   *next;
 
8108
  tsample_t sample;
 
8109
 
 
8110
 
 
8111
  if ((src == NULL) || (dst == NULL))
 
8112
    {
 
8113
    TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
 
8114
    return (1);
 
8115
    }
 
8116
 
 
8117
  bytes_per_sample = (bps + 7) / 8;
 
8118
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
8119
  if (bytes_per_pixel < (bytes_per_sample + 1))
 
8120
    shift_width = bytes_per_pixel;
 
8121
  else
 
8122
    shift_width = bytes_per_sample + 1;
 
8123
 
 
8124
  rowsize = ((bps * spp * width) + 7) / 8;
 
8125
  ready_bits = 0;
 
8126
  maskbits =  (uint64)-1 >> (64 - bps);
 
8127
  buff1 = buff2 = 0;
 
8128
  for (row = 0; row < length; row++)
 
8129
    {
 
8130
    bit_offset = col * bps * spp;
 
8131
    for (sample = 0; sample < spp; sample++)
 
8132
      {
 
8133
      if (sample == 0)
 
8134
        {
 
8135
        src_byte = bit_offset / 8;
 
8136
        src_bit  = bit_offset % 8;
 
8137
        }
 
8138
      else
 
8139
        {
 
8140
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8141
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
8142
        }
 
8143
 
 
8144
      switch (rotation)
 
8145
        {
 
8146
        case  90: next = src + src_byte - (row * rowsize);
 
8147
                  break;
 
8148
        case 270: next = src + src_byte + (row * rowsize);
 
8149
                  break;
 
8150
        default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
 
8151
                  return (1);
 
8152
        }
 
8153
      matchbits = maskbits << (64 - src_bit - bps); 
 
8154
      if (little_endian)
 
8155
        {
 
8156
        longbuff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
 
8157
        longbuff2 = longbuff1;
 
8158
        }
 
8159
      else
 
8160
        {
 
8161
        longbuff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
 
8162
        longbuff2 = longbuff1;
 
8163
        }
 
8164
 
 
8165
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
8166
      buff1 = (buff3 & matchbits) << (src_bit);
 
8167
 
 
8168
      if (ready_bits < 32)
 
8169
        { /* add another bps bits to the buffer */
 
8170
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
8171
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8172
        }
 
8173
      else /* If we have a full buffer's worth, write it out */
 
8174
        {
 
8175
        bytebuff1 = (buff2 >> 56);
 
8176
        *dst++ = bytebuff1;
 
8177
        bytebuff2 = (buff2 >> 48);
 
8178
        *dst++ = bytebuff2;
 
8179
        bytebuff3 = (buff2 >> 40);
 
8180
        *dst++ = bytebuff3;
 
8181
        bytebuff4 = (buff2 >> 32);
 
8182
        *dst++ = bytebuff4;
 
8183
        ready_bits -= 32;
 
8184
                    
 
8185
        /* shift in new bits */
 
8186
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
8187
        }
 
8188
      ready_bits += bps;
 
8189
      }
 
8190
    }
 
8191
  while (ready_bits > 0)
 
8192
    {
 
8193
    bytebuff1 = (buff2 >> 56);
 
8194
    *dst++ = bytebuff1;
 
8195
    buff2 = (buff2 << 8);
 
8196
    ready_bits -= 8;
 
8197
    }
 
8198
 
 
8199
  return (0);
 
8200
  } /* end rotateContigSamples32bits */
 
8201
 
 
8202
 
 
8203
/* Rotate an image by a multiple of 90 degrees clockwise */
 
8204
static int
 
8205
rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, 
 
8206
            uint32 *img_length, unsigned char **ibuff_ptr)
 
8207
  {
 
8208
  int      shift_width;
 
8209
  uint32   bytes_per_pixel, bytes_per_sample;
 
8210
  uint32   row, rowsize, src_offset, dst_offset;
 
8211
  uint32   i, col, width, length;
 
8212
  uint32   colsize, buffsize, col_offset, pix_offset;
 
8213
  unsigned char *ibuff;
 
8214
  unsigned char *src;
 
8215
  unsigned char *dst;
 
8216
  uint16   spp, bps;
 
8217
  float    res_temp;
 
8218
  unsigned char *rbuff = NULL;
 
8219
 
 
8220
  width  = *img_width;
 
8221
  length = *img_length;
 
8222
  spp = image->spp;
 
8223
  bps = image->bps;
 
8224
 
 
8225
  rowsize = ((bps * spp * width) + 7) / 8;
 
8226
  colsize = ((bps * spp * length) + 7) / 8;
 
8227
  if ((colsize * width) > (rowsize * length))
 
8228
    buffsize = (colsize + 1) * width;
 
8229
  else
 
8230
    buffsize = (rowsize + 1) * length;
 
8231
 
 
8232
  bytes_per_sample = (bps + 7) / 8;
 
8233
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
8234
  if (bytes_per_pixel < (bytes_per_sample + 1))
 
8235
    shift_width = bytes_per_pixel;
 
8236
  else
 
8237
    shift_width = bytes_per_sample + 1;
 
8238
 
 
8239
  switch (rotation)
 
8240
    {
 
8241
    case 0:
 
8242
    case 360: return (0);
 
8243
    case 90:
 
8244
    case 180:
 
8245
    case 270: break;
 
8246
    default:  TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
 
8247
              return (-1);
 
8248
    }
 
8249
 
 
8250
  if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
 
8251
    {
 
8252
    TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
 
8253
    return (-1);
 
8254
    }
 
8255
  _TIFFmemset(rbuff, '\0', buffsize);
 
8256
 
 
8257
  ibuff = *ibuff_ptr;
 
8258
  switch (rotation)
 
8259
    {
 
8260
    case 180: if ((bps % 8) == 0) /* byte alligned data */
 
8261
                { 
 
8262
                src = ibuff;
 
8263
                pix_offset = (spp * bps) / 8;
 
8264
                for (row = 0; row < length; row++)
 
8265
                   {
 
8266
                   dst_offset = (length - row - 1) * rowsize;
 
8267
                   for (col = 0; col < width; col++)
 
8268
                     { 
 
8269
                     col_offset = (width - col - 1) * pix_offset;
 
8270
                     dst = rbuff + dst_offset + col_offset;
 
8271
 
 
8272
                     for (i = 0; i  < bytes_per_pixel; i++)
 
8273
                       *dst++ = *src++;
 
8274
                     }
 
8275
                   }
 
8276
                }
 
8277
              else
 
8278
                { /* non 8 bit per sample data */ 
 
8279
                for (row = 0; row < length; row++)
 
8280
                  {
 
8281
                  src_offset = row * rowsize;
 
8282
                  dst_offset = (length - row - 1) * rowsize;
 
8283
                  src = ibuff + src_offset;
 
8284
                  dst = rbuff + dst_offset;
 
8285
                  switch (shift_width)
 
8286
                    {
 
8287
                    case 1: if (bps == 1)
 
8288
                              {
 
8289
                              if (reverseSamples8bits(spp, bps, width, src, dst))
 
8290
                                {
 
8291
                                _TIFFfree(rbuff);
 
8292
                                return (-1);
 
8293
                                }
 
8294
                              break;
 
8295
                              }
 
8296
                            if (reverseSamples16bits(spp, bps, width, src, dst))
 
8297
                              {
 
8298
                              _TIFFfree(rbuff);
 
8299
                              return (-1);
 
8300
                              }
 
8301
                             break;
 
8302
                    case 2: if (reverseSamples24bits(spp, bps, width, src, dst))
 
8303
                              {
 
8304
                              _TIFFfree(rbuff);
 
8305
                              return (-1);
 
8306
                              }
 
8307
                             break;
 
8308
                    case 3: 
 
8309
                    case 4: 
 
8310
                    case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
 
8311
                              {
 
8312
                              _TIFFfree(rbuff);
 
8313
                              return (-1);
 
8314
                              }
 
8315
                             break;
 
8316
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
8317
                             _TIFFfree(rbuff);
 
8318
                             return (-1);      
 
8319
                    }
 
8320
                  }
 
8321
                }
 
8322
              _TIFFfree(ibuff);
 
8323
              *(ibuff_ptr) = rbuff;
 
8324
              break;
 
8325
 
 
8326
    case 90:  if ((bps % 8) == 0) /* byte aligned data */
 
8327
                {
 
8328
                for (col = 0; col < width; col++)
 
8329
                  {
 
8330
                  src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
 
8331
                  dst_offset = col * colsize;
 
8332
                  src = ibuff + src_offset;
 
8333
                  dst = rbuff + dst_offset;
 
8334
                  for (row = length; row > 0; row--)
 
8335
                    {
 
8336
                    for (i = 0; i < bytes_per_pixel; i++)
 
8337
                      *dst++ = *(src + i);
 
8338
                    src -= rowsize;
 
8339
                    }
 
8340
                  }
 
8341
                }
 
8342
              else
 
8343
                { /* non 8 bit per sample data */ 
 
8344
                for (col = 0; col < width; col++)
 
8345
                  {
 
8346
                  src_offset = (length - 1) * rowsize;
 
8347
                  dst_offset = col * colsize;
 
8348
                  src = ibuff + src_offset;
 
8349
                  dst = rbuff + dst_offset;
 
8350
                  switch (shift_width)
 
8351
                    {
 
8352
                    case 1: if (bps == 1)
 
8353
                              {
 
8354
                              if (rotateContigSamples8bits(rotation, spp, bps, width, 
 
8355
                                                         length, col, src, dst))
 
8356
                                {
 
8357
                                _TIFFfree(rbuff);
 
8358
                                return (-1);
 
8359
                                }
 
8360
                              break;
 
8361
                              }
 
8362
                            if (rotateContigSamples16bits(rotation, spp, bps, width, 
 
8363
                                                         length, col, src, dst))
 
8364
                              {
 
8365
                              _TIFFfree(rbuff);
 
8366
                              return (-1);
 
8367
                              }
 
8368
                            break;
 
8369
                    case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
 
8370
                                                          length, col, src, dst))
 
8371
                              {
 
8372
                              _TIFFfree(rbuff);
 
8373
                              return (-1);
 
8374
                              }
 
8375
                             break;
 
8376
                    case 3: 
 
8377
                    case 4: 
 
8378
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
 
8379
                                                          length, col, src, dst))
 
8380
                              {
 
8381
                              _TIFFfree(rbuff);
 
8382
                              return (-1);
 
8383
                              }
 
8384
                             break;
 
8385
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
8386
                             _TIFFfree(rbuff);
 
8387
                             return (-1);      
 
8388
                    }
 
8389
                  }
 
8390
                }
 
8391
              _TIFFfree(ibuff);
 
8392
              *(ibuff_ptr) = rbuff;
 
8393
 
 
8394
              *img_width = length;
 
8395
              *img_length = width;
 
8396
              image->width = length;
 
8397
              image->length = width;
 
8398
              res_temp = image->xres;
 
8399
              image->xres = image->yres;
 
8400
              image->yres = res_temp;
 
8401
              break;
 
8402
 
 
8403
    case 270: if ((bps % 8) == 0) /* byte aligned data */
 
8404
                {
 
8405
                for (col = 0; col < width; col++)
 
8406
                  {
 
8407
                  src_offset = col * bytes_per_pixel;
 
8408
                  dst_offset = (width - col - 1) * colsize;
 
8409
                  src = ibuff + src_offset;
 
8410
                  dst = rbuff + dst_offset;
 
8411
                  for (row = length; row > 0; row--)
 
8412
                    {
 
8413
                    for (i = 0; i < bytes_per_pixel; i++)
 
8414
                      *dst++ = *(src + i);
 
8415
                    src += rowsize;
 
8416
                    }
 
8417
                  }
 
8418
                }
 
8419
              else
 
8420
                { /* non 8 bit per sample data */ 
 
8421
                for (col = 0; col < width; col++)
 
8422
                  {
 
8423
                  src_offset = 0;
 
8424
                  dst_offset = (width - col - 1) * colsize;
 
8425
                  src = ibuff + src_offset;
 
8426
                  dst = rbuff + dst_offset;
 
8427
                  switch (shift_width)
 
8428
                    {
 
8429
                    case 1: if (bps == 1)
 
8430
                              {
 
8431
                              if (rotateContigSamples8bits(rotation, spp, bps, width, 
 
8432
                                                         length, col, src, dst))
 
8433
                                {
 
8434
                                _TIFFfree(rbuff);
 
8435
                                return (-1);
 
8436
                                }
 
8437
                              break;
 
8438
                              }
 
8439
                            if (rotateContigSamples16bits(rotation, spp, bps, width, 
 
8440
                                                         length, col, src, dst))
 
8441
                              {
 
8442
                              _TIFFfree(rbuff);
 
8443
                              return (-1);
 
8444
                              }
 
8445
                            break;
 
8446
                    case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
 
8447
                                                          length, col, src, dst))
 
8448
                              {
 
8449
                              _TIFFfree(rbuff);
 
8450
                              return (-1);
 
8451
                              }
 
8452
                             break;
 
8453
                    case 3: 
 
8454
                    case 4: 
 
8455
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
 
8456
                                                          length, col, src, dst))
 
8457
                              {
 
8458
                              _TIFFfree(rbuff);
 
8459
                              return (-1);
 
8460
                              }
 
8461
                             break;
 
8462
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
 
8463
                             _TIFFfree(rbuff);
 
8464
                             return (-1);      
 
8465
                    }
 
8466
                  }
 
8467
                }
 
8468
              _TIFFfree(ibuff);
 
8469
              *(ibuff_ptr) = rbuff;
 
8470
 
 
8471
              *img_width = length;
 
8472
              *img_length = width;
 
8473
              image->width = length;
 
8474
              image->length = width;
 
8475
              res_temp = image->xres;
 
8476
              image->xres = image->yres;
 
8477
              image->yres = res_temp;
 
8478
              break;
 
8479
    default:
 
8480
              break;
 
8481
    }
 
8482
 
 
8483
  return (0);
 
8484
  } /* end rotateImage */
 
8485
 
 
8486
static int
 
8487
reverseSamples8bits (uint16 spp, uint16 bps, uint32 width, 
 
8488
                     uint8 *ibuff, uint8 *obuff)
 
8489
  {
 
8490
  int      ready_bits = 0;
 
8491
  uint32   col;
 
8492
  uint32   src_byte, src_bit;
 
8493
  uint32   bit_offset = 0;
 
8494
  uint8    match_bits = 0, mask_bits = 0;
 
8495
  uint8    buff1 = 0, buff2 = 0;
 
8496
  unsigned char *src;
 
8497
  unsigned char *dst;
 
8498
  tsample_t sample;
 
8499
 
 
8500
  if ((ibuff == NULL) || (obuff == NULL))
 
8501
    {
 
8502
    TIFFError("reverseSamples8bits","Invalid image or work buffer");
 
8503
    return (1);
 
8504
    }
 
8505
 
 
8506
  ready_bits = 0;
 
8507
  mask_bits =  (uint8)-1 >> ( 8 - bps);
 
8508
  dst = obuff;
 
8509
  for (col = width; col > 0; col--)
 
8510
    {
 
8511
    /* Compute src byte(s) and bits within byte(s) */
 
8512
    bit_offset = (col - 1) * bps * spp;
 
8513
    for (sample = 0; sample < spp; sample++)
 
8514
      {
 
8515
      if (sample == 0)
 
8516
        {
 
8517
        src_byte = bit_offset / 8;
 
8518
        src_bit  = bit_offset % 8;
 
8519
        }
 
8520
      else
 
8521
        {
 
8522
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8523
        src_bit  = (bit_offset + (sample * bps)) % 8;
 
8524
        }
 
8525
 
 
8526
      src = ibuff + src_byte;
 
8527
      match_bits = mask_bits << (8 - src_bit - bps); 
 
8528
      buff1 = ((*src) & match_bits) << (src_bit);
 
8529
 
 
8530
      if (ready_bits < 8)
 
8531
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8532
      else  /* If we have a full buffer's worth, write it out */
 
8533
        {
 
8534
        *dst++ = buff2;
 
8535
        buff2 = buff1;
 
8536
        ready_bits -= 8;
 
8537
        }
 
8538
      ready_bits += bps;
 
8539
      }
 
8540
    }
 
8541
  if (ready_bits > 0)
 
8542
    {
 
8543
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
 
8544
    *dst++ = buff1;
 
8545
    }
 
8546
 
 
8547
  return (0);
 
8548
  } /* end reverseSamples8bits */
 
8549
 
 
8550
 
 
8551
static int
 
8552
reverseSamples16bits (uint16 spp, uint16 bps, uint32 width, 
 
8553
                      uint8 *ibuff, uint8 *obuff)
 
8554
  {
 
8555
  int      ready_bits = 0;
 
8556
  uint32   col;
 
8557
  uint32   src_byte = 0, high_bit = 0;
 
8558
  uint32   bit_offset = 0;
 
8559
  uint16   match_bits = 0, mask_bits = 0;
 
8560
  uint16   buff1 = 0, buff2 = 0;
 
8561
  uint8    bytebuff = 0;
 
8562
  unsigned char *src;
 
8563
  unsigned char *dst;
 
8564
  tsample_t sample;
 
8565
 
 
8566
  if ((ibuff == NULL) || (obuff == NULL))
 
8567
    {
 
8568
    TIFFError("reverseSample16bits","Invalid image or work buffer");
 
8569
    return (1);
 
8570
    }
 
8571
 
 
8572
  ready_bits = 0;
 
8573
  mask_bits =  (uint16)-1 >> (16 - bps);
 
8574
  dst = obuff;
 
8575
  for (col = width; col > 0; col--)
 
8576
    {
 
8577
    /* Compute src byte(s) and bits within byte(s) */
 
8578
    bit_offset = (col - 1) * bps * spp;
 
8579
    for (sample = 0; sample < spp; sample++)
 
8580
      {
 
8581
      if (sample == 0)
 
8582
        {
 
8583
        src_byte = bit_offset / 8;
 
8584
        high_bit  = bit_offset % 8;
 
8585
        }
 
8586
      else
 
8587
        {
 
8588
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8589
        high_bit  = (bit_offset + (sample * bps)) % 8;
 
8590
        }
 
8591
 
 
8592
      src = ibuff + src_byte;
 
8593
      match_bits = mask_bits << (16 - high_bit - bps); 
 
8594
      if (little_endian)
 
8595
        buff1 = (src[0] << 8) | src[1];
 
8596
      else
 
8597
        buff1 = (src[1] << 8) | src[0];
 
8598
      buff1 = (buff1 & match_bits) << (high_bit);
 
8599
      
 
8600
      if (ready_bits < 8)
 
8601
        { /* add another bps bits to the buffer */
 
8602
        bytebuff = 0;
 
8603
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8604
        }
 
8605
      else /* If we have a full buffer's worth, write it out */
 
8606
        {
 
8607
        bytebuff = (buff2 >> 8);
 
8608
        *dst++ = bytebuff;
 
8609
        ready_bits -= 8;
 
8610
        /* shift in new bits */
 
8611
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
 
8612
        }
 
8613
      ready_bits += bps;
 
8614
      }
 
8615
    }
 
8616
 
 
8617
  if (ready_bits > 0)
 
8618
    {
 
8619
    bytebuff = (buff2 >> 8);
 
8620
    *dst++ = bytebuff;
 
8621
    }
 
8622
 
 
8623
  return (0);
 
8624
  } /* end reverseSamples16bits */
 
8625
 
 
8626
static int
 
8627
reverseSamples24bits (uint16 spp, uint16 bps, uint32 width, 
 
8628
                      uint8 *ibuff, uint8 *obuff)
 
8629
  {
 
8630
  int      ready_bits = 0;
 
8631
  uint32   col;
 
8632
  uint32   src_byte = 0, high_bit = 0;
 
8633
  uint32   bit_offset = 0;
 
8634
  uint32   match_bits = 0, mask_bits = 0;
 
8635
  uint32   buff1 = 0, buff2 = 0;
 
8636
  uint8    bytebuff1 = 0, bytebuff2 = 0;
 
8637
  unsigned char *src;
 
8638
  unsigned char *dst;
 
8639
  tsample_t sample;
 
8640
 
 
8641
  if ((ibuff == NULL) || (obuff == NULL))
 
8642
    {
 
8643
    TIFFError("reverseSamples24bits","Invalid image or work buffer");
 
8644
    return (1);
 
8645
    }
 
8646
 
 
8647
  ready_bits = 0;
 
8648
  mask_bits =  (uint32)-1 >> (32 - bps);
 
8649
  dst = obuff;
 
8650
  for (col = width; col > 0; col--)
 
8651
    {
 
8652
    /* Compute src byte(s) and bits within byte(s) */
 
8653
    bit_offset = (col - 1) * bps * spp;
 
8654
    for (sample = 0; sample < spp; sample++)
 
8655
      {
 
8656
      if (sample == 0)
 
8657
        {
 
8658
        src_byte = bit_offset / 8;
 
8659
        high_bit  = bit_offset % 8;
 
8660
        }
 
8661
      else
 
8662
        {
 
8663
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8664
        high_bit  = (bit_offset + (sample * bps)) % 8;
 
8665
        }
 
8666
 
 
8667
      src = ibuff + src_byte;
 
8668
      match_bits = mask_bits << (32 - high_bit - bps); 
 
8669
      if (little_endian)
 
8670
        buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
8671
      else
 
8672
        buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
8673
      buff1 = (buff1 & match_bits) << (high_bit);
 
8674
 
 
8675
      if (ready_bits < 16)
 
8676
        { /* add another bps bits to the buffer */
 
8677
        bytebuff1 = bytebuff2 = 0;
 
8678
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8679
        }
 
8680
      else /* If we have a full buffer's worth, write it out */
 
8681
        {
 
8682
        bytebuff1 = (buff2 >> 24);
 
8683
        *dst++ = bytebuff1;
 
8684
        bytebuff2 = (buff2 >> 16);
 
8685
        *dst++ = bytebuff2;
 
8686
        ready_bits -= 16;
 
8687
 
 
8688
        /* shift in new bits */
 
8689
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
 
8690
        }
 
8691
      ready_bits += bps;
 
8692
      }
 
8693
    }
 
8694
 
 
8695
 /* catch any trailing bits at the end of the line */
 
8696
  while (ready_bits > 0)
 
8697
    {
 
8698
    bytebuff1 = (buff2 >> 24);
 
8699
    *dst++ = bytebuff1;
 
8700
 
 
8701
    buff2 = (buff2 << 8);
 
8702
    bytebuff2 = bytebuff1;
 
8703
    ready_bits -= 8;
 
8704
    }
 
8705
 
 
8706
  return (0);
 
8707
  } /* end reverseSamples24bits */
 
8708
 
 
8709
 
 
8710
static int
 
8711
reverseSamples32bits (uint16 spp, uint16 bps, uint32 width, 
 
8712
                      uint8 *ibuff, uint8 *obuff)
 
8713
  {
 
8714
  int    ready_bits = 0, shift_width = 0;
 
8715
  int    bytes_per_sample, bytes_per_pixel;
 
8716
  uint32 bit_offset;
 
8717
  uint32 src_byte = 0, high_bit = 0;
 
8718
  uint32 col;
 
8719
  uint32 longbuff1 = 0, longbuff2 = 0;
 
8720
  uint64 mask_bits = 0, match_bits = 0;
 
8721
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
 
8722
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
 
8723
  unsigned char *src;
 
8724
  unsigned char *dst;
 
8725
  tsample_t sample;
 
8726
 
 
8727
  if ((ibuff == NULL) || (obuff == NULL))
 
8728
    {
 
8729
    TIFFError("reverseSamples32bits","Invalid image or work buffer");
 
8730
    return (1);
 
8731
    }
 
8732
 
 
8733
  ready_bits = 0;
 
8734
  mask_bits =  (uint64)-1 >> (64 - bps);
 
8735
  dst = obuff;
 
8736
 
 
8737
  bytes_per_sample = (bps + 7) / 8;
 
8738
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
8739
  if (bytes_per_pixel < (bytes_per_sample + 1))
 
8740
    shift_width = bytes_per_pixel;
 
8741
  else
 
8742
    shift_width = bytes_per_sample + 1;
 
8743
 
 
8744
  for (col = width; col > 0; col--)
 
8745
    {
 
8746
    /* Compute src byte(s) and bits within byte(s) */
 
8747
    bit_offset = (col - 1) * bps * spp;
 
8748
    for (sample = 0; sample < spp; sample++)
 
8749
      {
 
8750
      if (sample == 0)
 
8751
        {
 
8752
        src_byte = bit_offset / 8;
 
8753
        high_bit  = bit_offset % 8;
 
8754
        }
 
8755
      else
 
8756
        {
 
8757
        src_byte = (bit_offset + (sample * bps)) / 8;
 
8758
        high_bit  = (bit_offset + (sample * bps)) % 8;
 
8759
        }
 
8760
 
 
8761
      src = ibuff + src_byte;
 
8762
      match_bits = mask_bits << (64 - high_bit - bps); 
 
8763
      if (little_endian)
 
8764
        {
 
8765
        longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
8766
        longbuff2 = longbuff1;
 
8767
        }
 
8768
      else
 
8769
        {
 
8770
        longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
 
8771
        longbuff2 = longbuff1;
 
8772
        }
 
8773
      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
 
8774
      buff1 = (buff3 & match_bits) << (high_bit);
 
8775
 
 
8776
      if (ready_bits < 32)
 
8777
        { /* add another bps bits to the buffer */
 
8778
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
 
8779
        buff2 = (buff2 | (buff1 >> ready_bits));
 
8780
        }
 
8781
      else /* If we have a full buffer's worth, write it out */
 
8782
        {
 
8783
        bytebuff1 = (buff2 >> 56);
 
8784
        *dst++ = bytebuff1;
 
8785
        bytebuff2 = (buff2 >> 48);
 
8786
        *dst++ = bytebuff2;
 
8787
        bytebuff3 = (buff2 >> 40);
 
8788
        *dst++ = bytebuff3;
 
8789
        bytebuff4 = (buff2 >> 32);
 
8790
        *dst++ = bytebuff4;
 
8791
        ready_bits -= 32;
 
8792
                    
 
8793
        /* shift in new bits */
 
8794
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
 
8795
        }
 
8796
      ready_bits += bps;
 
8797
      }
 
8798
    }
 
8799
  while (ready_bits > 0)
 
8800
    {
 
8801
    bytebuff1 = (buff2 >> 56);
 
8802
    *dst++ = bytebuff1;
 
8803
    buff2 = (buff2 << 8);
 
8804
    ready_bits -= 8;
 
8805
    }
 
8806
 
 
8807
  return (0);
 
8808
  } /* end reverseSamples32bits */
 
8809
 
 
8810
static int
 
8811
reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width, 
 
8812
                     uint8 *src, uint8 *dst)
 
8813
  {
 
8814
  int i;
 
8815
  uint32  col, bytes_per_pixel, col_offset;
 
8816
  uint8   bytebuff1;
 
8817
  unsigned char swapbuff[32];
 
8818
  
 
8819
  if ((src == NULL) || (dst == NULL))
 
8820
    {
 
8821
    TIFFError("reverseSamplesBytes","Invalid input or output buffer");
 
8822
    return (1);
 
8823
    }
 
8824
 
 
8825
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
8826
  switch (bps / 8)
 
8827
     {
 
8828
     case 8:  /* Use memcpy for multiple bytes per sample data */
 
8829
     case 4:
 
8830
     case 3:
 
8831
     case 2: for (col = 0; col < (width / 2); col++)
 
8832
               {
 
8833
               col_offset = col * bytes_per_pixel;                     
 
8834
               _TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
 
8835
               _TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
 
8836
               _TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
 
8837
               }
 
8838
             break;
 
8839
     case 1: /* Use byte copy only for single byte per sample data */
 
8840
             for (col = 0; col < (width / 2); col++)
 
8841
               { 
 
8842
               for (i = 0; i < spp; i++)
 
8843
                  {
 
8844
                  bytebuff1 = *src;
 
8845
                  *src++ = *(dst - spp + i);
 
8846
                  *(dst - spp + i) = bytebuff1;
 
8847
                  }
 
8848
                dst -= spp;
 
8849
                }
 
8850
             break;
 
8851
     default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
 
8852
       return (1);
 
8853
     }
 
8854
  return (0);
 
8855
  } /* end reverseSamplesBytes */
 
8856
 
 
8857
 
 
8858
/* Mirror an image horizontally or vertically */
 
8859
static int
 
8860
mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
 
8861
  {
 
8862
  int      shift_width;
 
8863
  uint32   bytes_per_pixel, bytes_per_sample;
 
8864
  uint32   row, rowsize, row_offset;
 
8865
  unsigned char *line_buff = NULL;
 
8866
  unsigned char *src;
 
8867
  unsigned char *dst;
 
8868
 
 
8869
  src = ibuff;
 
8870
  rowsize = ((width * bps * spp) + 7) / 8;
 
8871
  switch (mirror)
 
8872
    {
 
8873
    case MIRROR_BOTH:
 
8874
    case MIRROR_VERT: 
 
8875
             line_buff = (unsigned char *)_TIFFmalloc(rowsize);
 
8876
             if (line_buff == NULL)
 
8877
               {
 
8878
               TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
 
8879
               return (-1);
 
8880
               }
 
8881
 
 
8882
             dst = ibuff + (rowsize * (length - 1));
 
8883
             for (row = 0; row < length / 2; row++)
 
8884
               {
 
8885
              _TIFFmemcpy(line_buff, src, rowsize);
 
8886
              _TIFFmemcpy(src, dst,  rowsize);
 
8887
              _TIFFmemcpy(dst, line_buff, rowsize);
 
8888
               src += (rowsize);
 
8889
               dst -= (rowsize);                                 
 
8890
               }
 
8891
             if (line_buff)
 
8892
               _TIFFfree(line_buff);
 
8893
             if (mirror == MIRROR_VERT)
 
8894
               break;
 
8895
    case MIRROR_HORIZ :
 
8896
              if ((bps % 8) == 0) /* byte alligned data */
 
8897
                { 
 
8898
                for (row = 0; row < length; row++)
 
8899
                  {
 
8900
                  row_offset = row * rowsize;
 
8901
                  src = ibuff + row_offset;
 
8902
                  dst = ibuff + row_offset + rowsize;
 
8903
                  if (reverseSamplesBytes(spp, bps, width, src, dst))
 
8904
                    {
 
8905
                    return (-1);
 
8906
                    }
 
8907
                  }
 
8908
                }
 
8909
              else
 
8910
                { /* non 8 bit per sample  data */
 
8911
                if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
 
8912
                  {
 
8913
                  TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
 
8914
                  return (-1);
 
8915
                  }
 
8916
                bytes_per_sample = (bps + 7) / 8;
 
8917
                bytes_per_pixel  = ((bps * spp) + 7) / 8;
 
8918
                if (bytes_per_pixel < (bytes_per_sample + 1))
 
8919
                  shift_width = bytes_per_pixel;
 
8920
                else
 
8921
                  shift_width = bytes_per_sample + 1;
 
8922
 
 
8923
                for (row = 0; row < length; row++)
 
8924
                  {
 
8925
                  row_offset = row * rowsize;
 
8926
                  src = ibuff + row_offset;
 
8927
                  _TIFFmemset (line_buff, '\0', rowsize);
 
8928
                  switch (shift_width)
 
8929
                    {
 
8930
                    case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
 
8931
                              {
 
8932
                              _TIFFfree(line_buff);
 
8933
                              return (-1);
 
8934
                              }
 
8935
                             _TIFFmemcpy (src, line_buff, rowsize);
 
8936
                             break;
 
8937
                    case 2: if (reverseSamples24bits(spp, bps, width, src, line_buff))
 
8938
                              {
 
8939
                              _TIFFfree(line_buff);
 
8940
                              return (-1);
 
8941
                              }
 
8942
                             _TIFFmemcpy (src, line_buff, rowsize);
 
8943
                             break;
 
8944
                    case 3: 
 
8945
                    case 4: 
 
8946
                    case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
 
8947
                              {
 
8948
                              _TIFFfree(line_buff);
 
8949
                              return (-1);
 
8950
                              }
 
8951
                             _TIFFmemcpy (src, line_buff, rowsize);
 
8952
                             break;
 
8953
                    default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
 
8954
                             _TIFFfree(line_buff);
 
8955
                             return (-1);      
 
8956
                    }
 
8957
                  }
 
8958
                if (line_buff)
 
8959
                  _TIFFfree(line_buff);
 
8960
                }
 
8961
             break;
 
8962
 
 
8963
    default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
 
8964
             return (-1);
 
8965
             break;
 
8966
    }
 
8967
 
 
8968
  return (0);
 
8969
  }
 
8970
 
 
8971
/* Invert the light and dark values for a bilevel or grayscale image */
 
8972
static int
 
8973
invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
 
8974
  {
 
8975
  uint32   row, col;
 
8976
  unsigned char  bytebuff1, bytebuff2, bytebuff3, bytebuff4;
 
8977
  unsigned char *src;
 
8978
  uint16        *src_uint16;
 
8979
  uint32        *src_uint32;
 
8980
 
 
8981
  if (spp != 1)
 
8982
    {
 
8983
    TIFFError("invertImage", "Image inversion not supported for more than one sample per pixel");
 
8984
    return (-1);
 
8985
    }
 
8986
 
 
8987
  if (photometric !=  PHOTOMETRIC_MINISWHITE && photometric !=  PHOTOMETRIC_MINISBLACK)
 
8988
    {
 
8989
    TIFFError("invertImage", "Only black and white and grayscale images can be inverted");
 
8990
    return (-1);
 
8991
    }
 
8992
 
 
8993
  src = work_buff;
 
8994
  if (src == NULL)
 
8995
    {
 
8996
    TIFFError ("invertImage", "Invalid crop buffer passed to invertImage");
 
8997
    return (-1);
 
8998
    }
 
8999
 
 
9000
  switch (bps)
 
9001
    {
 
9002
    case 32: src_uint32 = (uint32 *)src;
 
9003
             for (row = 0; row < length; row++)
 
9004
               for (col = 0; col < width; col++)
 
9005
                 {
 
9006
                 *src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
 
9007
                  src_uint32++;
 
9008
                 }
 
9009
            break;
 
9010
    case 16: src_uint16 = (uint16 *)src;
 
9011
             for (row = 0; row < length; row++)
 
9012
               for (col = 0; col < width; col++)
 
9013
                 {
 
9014
                 *src_uint16 = (uint16)0xFFFF - *src_uint16;
 
9015
                  src_uint16++;
 
9016
                 }
 
9017
            break;
 
9018
    case 8: for (row = 0; row < length; row++)
 
9019
              for (col = 0; col < width; col++)
 
9020
                {
 
9021
                *src = (uint8)255 - *src;
 
9022
                 src++;
 
9023
                }
 
9024
            break;
 
9025
    case 4: for (row = 0; row < length; row++)
 
9026
              for (col = 0; col < width; col++)
 
9027
                {
 
9028
                bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
 
9029
                bytebuff2 = 16 - (*src & 15);
 
9030
                *src = bytebuff1 << 4 & bytebuff2;
 
9031
                src++;
 
9032
                }
 
9033
            break;
 
9034
    case 2: for (row = 0; row < length; row++)
 
9035
              for (col = 0; col < width; col++)
 
9036
                {
 
9037
                bytebuff1 = 4 - (uint8)(*src & 192 >> 6);
 
9038
                bytebuff2 = 4 - (uint8)(*src & 48  >> 4);
 
9039
                bytebuff3 = 4 - (uint8)(*src & 12  >> 2);
 
9040
                bytebuff4 = 4 - (uint8)(*src & 3);
 
9041
                *src = (bytebuff1 << 6) || (bytebuff2 << 4) || (bytebuff3 << 2) || bytebuff4;
 
9042
                src++;
 
9043
                }
 
9044
            break;
 
9045
    case 1: for (row = 0; row < length; row++)
 
9046
              for (col = 0; col < width; col += 8 /(spp * bps))
 
9047
                {
 
9048
                *src = ~(*src);
 
9049
                src++;
 
9050
                }
 
9051
            break;
 
9052
    default: TIFFError("invertImage", "Unsupported bit depth %d", bps);
 
9053
      return (-1);
 
9054
    }
 
9055
 
 
9056
  return (0);
 
9057
  }
 
9058
 
 
9059
/* vim: set ts=8 sts=8 sw=8 noet: */
 
9060
/*
 
9061
 * Local Variables:
 
9062
 * mode: c
 
9063
 * c-basic-offset: 8
 
9064
 * fill-column: 78
 
9065
 * End:
 
9066
 */