|
roentgen |
b75cab |
/* $Id: tiffcp.c,v 1.49 2010-12-23 13:38:47 dron Exp $ */
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Copyright (c) 1988-1997 Sam Leffler
|
|
roentgen |
b75cab |
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Revised: 2/18/01 BAR -- added syntax for extracting single images from
|
|
roentgen |
b75cab |
* multi-image TIFF files.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* New syntax is: sourceFileName,image#
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* image# ranges from 0..<n-1> where n is the # of images in the file.</n-1>
|
|
roentgen |
b75cab |
* There may be no white space between the comma and the filename or
|
|
roentgen |
b75cab |
* image number.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Example: tiffcp source.tif,1 destination.tif
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Copies the 2nd image in source.tif to the destination.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
*****
|
|
roentgen |
b75cab |
* Permission to use, copy, modify, distribute, and sell this software and
|
|
roentgen |
b75cab |
* its documentation for any purpose is hereby granted without fee, provided
|
|
roentgen |
b75cab |
* that (i) the above copyright notices and this permission notice appear in
|
|
roentgen |
b75cab |
* all copies of the software and related documentation, and (ii) the names of
|
|
roentgen |
b75cab |
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
|
roentgen |
b75cab |
* publicity relating to the software without the specific, prior written
|
|
roentgen |
b75cab |
* permission of Sam Leffler and Silicon Graphics.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
|
roentgen |
b75cab |
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
|
roentgen |
b75cab |
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
|
roentgen |
b75cab |
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
|
roentgen |
b75cab |
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
roentgen |
b75cab |
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
|
roentgen |
b75cab |
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
roentgen |
b75cab |
* OF THIS SOFTWARE.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include "tif_config.h"
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include <stdio.h></stdio.h>
|
|
roentgen |
b75cab |
#include <stdlib.h></stdlib.h>
|
|
roentgen |
b75cab |
#include <string.h></string.h>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include <ctype.h></ctype.h>
|
|
roentgen |
b75cab |
#include <assert.h></assert.h>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#ifdef HAVE_UNISTD_H
|
|
roentgen |
b75cab |
# include <unistd.h></unistd.h>
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include "tiffio.h"
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#ifndef HAVE_GETOPT
|
|
roentgen |
b75cab |
extern int getopt(int, char**, char*);
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#if defined(VMS)
|
|
roentgen |
b75cab |
# define unlink delete
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define streq(a,b) (strcmp(a,b) == 0)
|
|
roentgen |
b75cab |
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define TRUE 1
|
|
roentgen |
b75cab |
#define FALSE 0
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int outtiled = -1;
|
|
roentgen |
b75cab |
static uint32 tilewidth;
|
|
roentgen |
b75cab |
static uint32 tilelength;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static uint16 config;
|
|
roentgen |
b75cab |
static uint16 compression;
|
|
roentgen |
b75cab |
static uint16 predictor;
|
|
roentgen |
b75cab |
static int preset;
|
|
roentgen |
b75cab |
static uint16 fillorder;
|
|
roentgen |
b75cab |
static uint16 orientation;
|
|
roentgen |
b75cab |
static uint32 rowsperstrip;
|
|
roentgen |
b75cab |
static uint32 g3opts;
|
|
roentgen |
b75cab |
static int ignore = FALSE; /* if true, ignore read errors */
|
|
roentgen |
b75cab |
static uint32 defg3opts = (uint32) -1;
|
|
roentgen |
b75cab |
static int quality = 75; /* JPEG quality */
|
|
roentgen |
b75cab |
static int jpegcolormode = JPEGCOLORMODE_RGB;
|
|
roentgen |
b75cab |
static uint16 defcompression = (uint16) -1;
|
|
roentgen |
b75cab |
static uint16 defpredictor = (uint16) -1;
|
|
roentgen |
b75cab |
static int defpreset = -1;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int tiffcp(TIFF*, TIFF*);
|
|
roentgen |
b75cab |
static int processCompressOptions(char*);
|
|
roentgen |
b75cab |
static void usage(void);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static char comma = ','; /* (default) comma separator character */
|
|
roentgen |
b75cab |
static TIFF* bias = NULL;
|
|
roentgen |
b75cab |
static int pageNum = 0;
|
|
roentgen |
b75cab |
static int pageInSeq = 0;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int nextSrcImage (TIFF *tif, char **imageSpec)
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
seek to the next image specified in *imageSpec
|
|
roentgen |
b75cab |
returns 1 if success, 0 if no more images to process
|
|
roentgen |
b75cab |
*imageSpec=NULL if subsequent images should be processed in sequence
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if (**imageSpec == comma) { /* if not @comma, we've done all images */
|
|
roentgen |
b75cab |
char *start = *imageSpec + 1;
|
|
roentgen |
b75cab |
tdir_t nextImage = (tdir_t)strtol(start, imageSpec, 0);
|
|
roentgen |
b75cab |
if (start == *imageSpec) nextImage = TIFFCurrentDirectory (tif);
|
|
roentgen |
b75cab |
if (**imageSpec)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if (**imageSpec == comma) {
|
|
roentgen |
b75cab |
/* a trailing comma denotes remaining images in sequence */
|
|
roentgen |
b75cab |
if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
|
|
roentgen |
b75cab |
}else{
|
|
roentgen |
b75cab |
fprintf (stderr,
|
|
roentgen |
b75cab |
"Expected a %c separated image # list after %s\n",
|
|
roentgen |
b75cab |
comma, TIFFFileName (tif));
|
|
roentgen |
b75cab |
exit (-4); /* syntax error */
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFSetDirectory (tif, nextImage)) return 1;
|
|
roentgen |
b75cab |
fprintf (stderr, "%s%c%d not found!\n",
|
|
roentgen |
b75cab |
TIFFFileName(tif), comma, (int) nextImage);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static TIFF* openSrcImage (char **imageSpec)
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
imageSpec points to a pointer to a filename followed by optional ,image#'s
|
|
roentgen |
b75cab |
Open the TIFF file and assign *imageSpec to either NULL if there are
|
|
roentgen |
b75cab |
no images specified, or a pointer to the next image number text
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
TIFF *tif;
|
|
roentgen |
b75cab |
char *fn = *imageSpec;
|
|
roentgen |
b75cab |
*imageSpec = strchr (fn, comma);
|
|
roentgen |
b75cab |
if (*imageSpec) { /* there is at least one image number specifier */
|
|
roentgen |
b75cab |
**imageSpec = '\0';
|
|
roentgen |
b75cab |
tif = TIFFOpen (fn, "r");
|
|
roentgen |
b75cab |
/* but, ignore any single trailing comma */
|
|
roentgen |
b75cab |
if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
|
|
roentgen |
b75cab |
if (tif) {
|
|
roentgen |
b75cab |
**imageSpec = comma; /* replace the comma */
|
|
roentgen |
b75cab |
if (!nextSrcImage(tif, imageSpec)) {
|
|
roentgen |
b75cab |
TIFFClose (tif);
|
|
roentgen |
b75cab |
tif = NULL;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}else
|
|
roentgen |
b75cab |
tif = TIFFOpen (fn, "r");
|
|
roentgen |
b75cab |
return tif;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
int
|
|
roentgen |
b75cab |
main(int argc, char* argv[])
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint16 defconfig = (uint16) -1;
|
|
roentgen |
b75cab |
uint16 deffillorder = 0;
|
|
roentgen |
b75cab |
uint32 deftilewidth = (uint32) -1;
|
|
roentgen |
b75cab |
uint32 deftilelength = (uint32) -1;
|
|
roentgen |
b75cab |
uint32 defrowsperstrip = (uint32) 0;
|
|
roentgen |
b75cab |
uint64 diroff = 0;
|
|
roentgen |
b75cab |
TIFF* in;
|
|
roentgen |
b75cab |
TIFF* out;
|
|
roentgen |
b75cab |
char mode[10];
|
|
roentgen |
b75cab |
char* mp = mode;
|
|
roentgen |
b75cab |
int c;
|
|
roentgen |
b75cab |
extern int optind;
|
|
roentgen |
b75cab |
extern char* optarg;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
*mp++ = 'w';
|
|
roentgen |
b75cab |
*mp = '\0';
|
|
roentgen |
b75cab |
while ((c = getopt(argc, argv, ",:b:c:f:l:o:z:p:r:w:aistBLMC8x")) != -1)
|
|
roentgen |
b75cab |
switch (c) {
|
|
roentgen |
b75cab |
case ',':
|
|
roentgen |
b75cab |
if (optarg[0] != '=') usage();
|
|
roentgen |
b75cab |
comma = optarg[1];
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'b': /* this file is bias image subtracted from others */
|
|
roentgen |
b75cab |
if (bias) {
|
|
roentgen |
b75cab |
fputs ("Only 1 bias image may be specified\n", stderr);
|
|
roentgen |
b75cab |
exit (-2);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint16 samples = (uint16) -1;
|
|
roentgen |
b75cab |
char **biasFn = &optarg;
|
|
roentgen |
b75cab |
bias = openSrcImage (biasFn);
|
|
roentgen |
b75cab |
if (!bias) exit (-5);
|
|
roentgen |
b75cab |
if (TIFFIsTiled (bias)) {
|
|
roentgen |
b75cab |
fputs ("Bias image must be organized in strips\n", stderr);
|
|
roentgen |
b75cab |
exit (-7);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
|
|
roentgen |
b75cab |
if (samples != 1) {
|
|
roentgen |
b75cab |
fputs ("Bias image must be monochrome\n", stderr);
|
|
roentgen |
b75cab |
exit (-7);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'a': /* append to output */
|
|
roentgen |
b75cab |
mode[0] = 'a';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'c': /* compression scheme */
|
|
roentgen |
b75cab |
if (!processCompressOptions(optarg))
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'f': /* fill order */
|
|
roentgen |
b75cab |
if (streq(optarg, "lsb2msb"))
|
|
roentgen |
b75cab |
deffillorder = FILLORDER_LSB2MSB;
|
|
roentgen |
b75cab |
else if (streq(optarg, "msb2lsb"))
|
|
roentgen |
b75cab |
deffillorder = FILLORDER_MSB2LSB;
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'i': /* ignore errors */
|
|
roentgen |
b75cab |
ignore = TRUE;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'l': /* tile length */
|
|
roentgen |
b75cab |
outtiled = TRUE;
|
|
roentgen |
b75cab |
deftilelength = atoi(optarg);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'o': /* initial directory offset */
|
|
roentgen |
b75cab |
diroff = strtoul(optarg, NULL, 0);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'p': /* planar configuration */
|
|
roentgen |
b75cab |
if (streq(optarg, "separate"))
|
|
roentgen |
b75cab |
defconfig = PLANARCONFIG_SEPARATE;
|
|
roentgen |
b75cab |
else if (streq(optarg, "contig"))
|
|
roentgen |
b75cab |
defconfig = PLANARCONFIG_CONTIG;
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'r': /* rows/strip */
|
|
roentgen |
b75cab |
defrowsperstrip = atol(optarg);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 's': /* generate stripped output */
|
|
roentgen |
b75cab |
outtiled = FALSE;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 't': /* generate tiled output */
|
|
roentgen |
b75cab |
outtiled = TRUE;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'w': /* tile width */
|
|
roentgen |
b75cab |
outtiled = TRUE;
|
|
roentgen |
b75cab |
deftilewidth = atoi(optarg);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'B':
|
|
roentgen |
b75cab |
*mp++ = 'b'; *mp = '\0';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'L':
|
|
roentgen |
b75cab |
*mp++ = 'l'; *mp = '\0';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'M':
|
|
roentgen |
b75cab |
*mp++ = 'm'; *mp = '\0';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'C':
|
|
roentgen |
b75cab |
*mp++ = 'c'; *mp = '\0';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case '8':
|
|
roentgen |
b75cab |
*mp++ = '8'; *mp = '\0';
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'x':
|
|
roentgen |
b75cab |
pageInSeq = 1;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case '?':
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
/*NOTREACHED*/
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (argc - optind < 2)
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
out = TIFFOpen(argv[argc-1], mode);
|
|
roentgen |
b75cab |
if (out == NULL)
|
|
roentgen |
b75cab |
return (-2);
|
|
roentgen |
b75cab |
if ((argc - optind) == 2)
|
|
roentgen |
b75cab |
pageNum = -1;
|
|
roentgen |
b75cab |
for (; optind < argc-1 ; optind++) {
|
|
roentgen |
b75cab |
char *imageCursor = argv[optind];
|
|
roentgen |
b75cab |
in = openSrcImage (&imageCursor);
|
|
roentgen |
b75cab |
if (in == NULL) {
|
|
roentgen |
b75cab |
(void) TIFFClose(out);
|
|
roentgen |
b75cab |
return (-3);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, setting subdirectory at " TIFF_UINT64_FORMAT, diroff);
|
|
roentgen |
b75cab |
(void) TIFFClose(in);
|
|
roentgen |
b75cab |
(void) TIFFClose(out);
|
|
roentgen |
b75cab |
return (1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
for (;;) {
|
|
roentgen |
b75cab |
config = defconfig;
|
|
roentgen |
b75cab |
compression = defcompression;
|
|
roentgen |
b75cab |
predictor = defpredictor;
|
|
roentgen |
b75cab |
preset = defpreset;
|
|
roentgen |
b75cab |
fillorder = deffillorder;
|
|
roentgen |
b75cab |
rowsperstrip = defrowsperstrip;
|
|
roentgen |
b75cab |
tilewidth = deftilewidth;
|
|
roentgen |
b75cab |
tilelength = deftilelength;
|
|
roentgen |
b75cab |
g3opts = defg3opts;
|
|
roentgen |
b75cab |
if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
|
|
roentgen |
b75cab |
(void) TIFFClose(in);
|
|
roentgen |
b75cab |
(void) TIFFClose(out);
|
|
roentgen |
b75cab |
return (1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (imageCursor) { /* seek next image directory */
|
|
roentgen |
b75cab |
if (!nextSrcImage(in, &imageCursor)) break;
|
|
roentgen |
b75cab |
}else
|
|
roentgen |
b75cab |
if (!TIFFReadDirectory(in)) break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
(void) TIFFClose(in);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) TIFFClose(out);
|
|
roentgen |
b75cab |
return (0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
processZIPOptions(char* cp)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if ( (cp = strchr(cp, ':')) ) {
|
|
roentgen |
b75cab |
do {
|
|
roentgen |
b75cab |
cp++;
|
|
roentgen |
b75cab |
if (isdigit((int)*cp))
|
|
roentgen |
b75cab |
defpredictor = atoi(cp);
|
|
roentgen |
b75cab |
else if (*cp == 'p')
|
|
roentgen |
b75cab |
defpreset = atoi(++cp);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
} while( (cp = strchr(cp, ':')) );
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
processG3Options(char* cp)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if( (cp = strchr(cp, ':')) ) {
|
|
roentgen |
b75cab |
if (defg3opts == (uint32) -1)
|
|
roentgen |
b75cab |
defg3opts = 0;
|
|
roentgen |
b75cab |
do {
|
|
roentgen |
b75cab |
cp++;
|
|
roentgen |
b75cab |
if (strneq(cp, "1d", 2))
|
|
roentgen |
b75cab |
defg3opts &= ~GROUP3OPT_2DENCODING;
|
|
roentgen |
b75cab |
else if (strneq(cp, "2d", 2))
|
|
roentgen |
b75cab |
defg3opts |= GROUP3OPT_2DENCODING;
|
|
roentgen |
b75cab |
else if (strneq(cp, "fill", 4))
|
|
roentgen |
b75cab |
defg3opts |= GROUP3OPT_FILLBITS;
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
} while( (cp = strchr(cp, ':')) );
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
processCompressOptions(char* opt)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if (streq(opt, "none")) {
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_NONE;
|
|
roentgen |
b75cab |
} else if (streq(opt, "packbits")) {
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_PACKBITS;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "jpeg", 4)) {
|
|
roentgen |
b75cab |
char* cp = strchr(opt, ':');
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_JPEG;
|
|
roentgen |
b75cab |
while( cp )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if (isdigit((int)cp[1]))
|
|
roentgen |
b75cab |
quality = atoi(cp+1);
|
|
roentgen |
b75cab |
else if (cp[1] == 'r' )
|
|
roentgen |
b75cab |
jpegcolormode = JPEGCOLORMODE_RAW;
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
cp = strchr(cp+1,':');
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
} else if (strneq(opt, "g3", 2)) {
|
|
roentgen |
b75cab |
processG3Options(opt);
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_CCITTFAX3;
|
|
roentgen |
b75cab |
} else if (streq(opt, "g4")) {
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_CCITTFAX4;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "lzw", 3)) {
|
|
roentgen |
b75cab |
char* cp = strchr(opt, ':');
|
|
roentgen |
b75cab |
if (cp)
|
|
roentgen |
b75cab |
defpredictor = atoi(cp+1);
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_LZW;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "zip", 3)) {
|
|
roentgen |
b75cab |
processZIPOptions(opt);
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_ADOBE_DEFLATE;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "lzma", 4)) {
|
|
roentgen |
b75cab |
processZIPOptions(opt);
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_LZMA;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "jbig", 4)) {
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_JBIG;
|
|
roentgen |
b75cab |
} else if (strneq(opt, "sgilog", 6)) {
|
|
roentgen |
b75cab |
defcompression = COMPRESSION_SGILOG;
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
return (0);
|
|
roentgen |
b75cab |
return (1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
char* stuff[] = {
|
|
roentgen |
b75cab |
"usage: tiffcp [options] input... output",
|
|
roentgen |
b75cab |
"where options are:",
|
|
roentgen |
b75cab |
" -a append to output instead of overwriting",
|
|
roentgen |
b75cab |
" -o offset set initial directory offset",
|
|
roentgen |
b75cab |
" -p contig pack samples contiguously (e.g. RGBRGB...)",
|
|
roentgen |
b75cab |
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
|
|
roentgen |
b75cab |
" -s write output in strips",
|
|
roentgen |
b75cab |
" -t write output in tiles",
|
|
roentgen |
b75cab |
" -8 write BigTIFF instead of default ClassicTIFF",
|
|
roentgen |
b75cab |
" -i ignore read errors",
|
|
roentgen |
b75cab |
" -b file[,#] bias (dark) monochrome image to be subtracted from all others",
|
|
roentgen |
b75cab |
" -,=% use % rather than , to separate image #'s (per Note below)",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
" -r # make each strip have no more than # rows",
|
|
roentgen |
b75cab |
" -w # set output tile width (pixels)",
|
|
roentgen |
b75cab |
" -l # set output tile length (pixels)",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
" -f lsb2msb force lsb-to-msb FillOrder for output",
|
|
roentgen |
b75cab |
" -f msb2lsb force msb-to-lsb FillOrder for output",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
|
|
roentgen |
b75cab |
" -c zip[:opts] compress output with deflate encoding",
|
|
roentgen |
b75cab |
" -c lzma[:opts] compress output with LZMA2 encoding",
|
|
roentgen |
b75cab |
" -c jpeg[:opts] compress output with JPEG encoding",
|
|
roentgen |
b75cab |
" -c jbig compress output with ISO JBIG encoding",
|
|
roentgen |
b75cab |
" -c packbits compress output with packbits encoding",
|
|
roentgen |
b75cab |
" -c g3[:opts] compress output with CCITT Group 3 encoding",
|
|
roentgen |
b75cab |
" -c g4 compress output with CCITT Group 4 encoding",
|
|
roentgen |
b75cab |
" -c sgilog compress output with SGILOG encoding",
|
|
roentgen |
b75cab |
" -c none use no compression algorithm on output",
|
|
roentgen |
b75cab |
" -x force the merged tiff pages in sequence",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
"Group 3 options:",
|
|
roentgen |
b75cab |
" 1d use default CCITT Group 3 1D-encoding",
|
|
roentgen |
b75cab |
" 2d use optional CCITT Group 3 2D-encoding",
|
|
roentgen |
b75cab |
" fill byte-align EOL codes",
|
|
roentgen |
b75cab |
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
"JPEG options:",
|
|
roentgen |
b75cab |
" # set compression quality level (0-100, default 75)",
|
|
roentgen |
b75cab |
" r output color image as RGB rather than YCbCr",
|
|
roentgen |
b75cab |
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
"LZW, Deflate (ZIP) and LZMA2 options:",
|
|
roentgen |
b75cab |
" # set predictor value",
|
|
roentgen |
b75cab |
" p# set compression level (preset)",
|
|
roentgen |
b75cab |
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing,",
|
|
roentgen |
b75cab |
"-c zip:3:p9 for Deflate encoding with maximum compression level and floating",
|
|
roentgen |
b75cab |
"point predictor.",
|
|
roentgen |
b75cab |
"",
|
|
roentgen |
b75cab |
"Note that input filenames may be of the form filename,x,y,z",
|
|
roentgen |
b75cab |
"where x, y, and z specify image numbers in the filename to copy.",
|
|
roentgen |
b75cab |
"example: tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
|
|
roentgen |
b75cab |
" subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
|
|
roentgen |
b75cab |
NULL
|
|
roentgen |
b75cab |
};
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
usage(void)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
char buf[BUFSIZ];
|
|
roentgen |
b75cab |
int i;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
setbuf(stderr, buf);
|
|
roentgen |
b75cab |
fprintf(stderr, "%s\n\n", TIFFGetVersion());
|
|
roentgen |
b75cab |
for (i = 0; stuff[i] != NULL; i++)
|
|
roentgen |
b75cab |
fprintf(stderr, "%s\n", stuff[i]);
|
|
roentgen |
b75cab |
exit(-1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define CopyField(tag, v) \
|
|
roentgen |
b75cab |
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
|
|
roentgen |
b75cab |
#define CopyField2(tag, v1, v2) \
|
|
roentgen |
b75cab |
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
|
|
roentgen |
b75cab |
#define CopyField3(tag, v1, v2, v3) \
|
|
roentgen |
b75cab |
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
|
|
roentgen |
b75cab |
#define CopyField4(tag, v1, v2, v3, v4) \
|
|
roentgen |
b75cab |
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
switch (type) {
|
|
roentgen |
b75cab |
case TIFF_SHORT:
|
|
roentgen |
b75cab |
if (count == 1) {
|
|
roentgen |
b75cab |
uint16 shortv;
|
|
roentgen |
b75cab |
CopyField(tag, shortv);
|
|
roentgen |
b75cab |
} else if (count == 2) {
|
|
roentgen |
b75cab |
uint16 shortv1, shortv2;
|
|
roentgen |
b75cab |
CopyField2(tag, shortv1, shortv2);
|
|
roentgen |
b75cab |
} else if (count == 4) {
|
|
roentgen |
b75cab |
uint16 *tr, *tg, *tb, *ta;
|
|
roentgen |
b75cab |
CopyField4(tag, tr, tg, tb, ta);
|
|
roentgen |
b75cab |
} else if (count == (uint16) -1) {
|
|
roentgen |
b75cab |
uint16 shortv1;
|
|
roentgen |
b75cab |
uint16* shortav;
|
|
roentgen |
b75cab |
CopyField2(tag, shortv1, shortav);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case TIFF_LONG:
|
|
roentgen |
b75cab |
{ uint32 longv;
|
|
roentgen |
b75cab |
CopyField(tag, longv);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case TIFF_RATIONAL:
|
|
roentgen |
b75cab |
if (count == 1) {
|
|
roentgen |
b75cab |
float floatv;
|
|
roentgen |
b75cab |
CopyField(tag, floatv);
|
|
roentgen |
b75cab |
} else if (count == (uint16) -1) {
|
|
roentgen |
b75cab |
float* floatav;
|
|
roentgen |
b75cab |
CopyField(tag, floatav);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case TIFF_ASCII:
|
|
roentgen |
b75cab |
{ char* stringv;
|
|
roentgen |
b75cab |
CopyField(tag, stringv);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case TIFF_DOUBLE:
|
|
roentgen |
b75cab |
if (count == 1) {
|
|
roentgen |
b75cab |
double doublev;
|
|
roentgen |
b75cab |
CopyField(tag, doublev);
|
|
roentgen |
b75cab |
} else if (count == (uint16) -1) {
|
|
roentgen |
b75cab |
double* doubleav;
|
|
roentgen |
b75cab |
CopyField(tag, doubleav);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Data type %d is not supported, tag %d skipped.",
|
|
roentgen |
b75cab |
tag, type);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static struct cpTag {
|
|
roentgen |
b75cab |
uint16 tag;
|
|
roentgen |
b75cab |
uint16 count;
|
|
roentgen |
b75cab |
TIFFDataType type;
|
|
roentgen |
b75cab |
} tags[] = {
|
|
roentgen |
b75cab |
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
|
|
roentgen |
b75cab |
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
|
|
roentgen |
b75cab |
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
|
|
roentgen |
b75cab |
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
|
|
roentgen |
b75cab |
{ TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
|
|
roentgen |
b75cab |
{ TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
|
|
roentgen |
b75cab |
{ TIFFTAG_STONITS, 1, TIFF_DOUBLE },
|
|
roentgen |
b75cab |
};
|
|
roentgen |
b75cab |
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
typedef int (*copyFunc)
|
|
roentgen |
b75cab |
(TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
|
|
roentgen |
b75cab |
static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/* PODD */
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
tiffcp(TIFF* in, TIFF* out)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint16 bitspersample, samplesperpixel;
|
|
roentgen |
b75cab |
uint16 input_compression, input_photometric;
|
|
roentgen |
b75cab |
copyFunc cf;
|
|
roentgen |
b75cab |
uint32 width, length;
|
|
roentgen |
b75cab |
struct cpTag* p;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_IMAGEWIDTH, width);
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_IMAGELENGTH, length);
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
|
|
roentgen |
b75cab |
if (compression != (uint16)-1)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_COMPRESSION, compression);
|
|
roentgen |
b75cab |
TIFFGetFieldDefaulted(in, TIFFTAG_COMPRESSION, &input_compression);
|
|
roentgen |
b75cab |
TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric);
|
|
roentgen |
b75cab |
if (input_compression == COMPRESSION_JPEG) {
|
|
roentgen |
b75cab |
/* Force conversion to RGB */
|
|
roentgen |
b75cab |
TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
|
|
roentgen |
b75cab |
} else if (input_photometric == PHOTOMETRIC_YCBCR) {
|
|
roentgen |
b75cab |
/* Otherwise, can't handle subsampled input */
|
|
roentgen |
b75cab |
uint16 subsamplinghor,subsamplingver;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
|
|
roentgen |
b75cab |
&subsamplinghor, &subsamplingver);
|
|
roentgen |
b75cab |
if (subsamplinghor!=1 || subsamplingver!=1) {
|
|
roentgen |
b75cab |
fprintf(stderr, "tiffcp: %s: Can't copy/convert subsampled image.\n",
|
|
roentgen |
b75cab |
TIFFFileName(in));
|
|
roentgen |
b75cab |
return FALSE;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (compression == COMPRESSION_JPEG) {
|
|
roentgen |
b75cab |
if (input_photometric == PHOTOMETRIC_RGB &&
|
|
roentgen |
b75cab |
jpegcolormode == JPEGCOLORMODE_RGB)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
else if (compression == COMPRESSION_SGILOG
|
|
roentgen |
b75cab |
|| compression == COMPRESSION_SGILOG24)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
|
|
roentgen |
b75cab |
samplesperpixel == 1 ?
|
|
roentgen |
b75cab |
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
|
|
roentgen |
b75cab |
if (fillorder != 0)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Will copy `Orientation' tag from input image
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
|
|
roentgen |
b75cab |
switch (orientation) {
|
|
roentgen |
b75cab |
case ORIENTATION_BOTRIGHT:
|
|
roentgen |
b75cab |
case ORIENTATION_RIGHTBOT: /* XXX */
|
|
roentgen |
b75cab |
TIFFWarning(TIFFFileName(in), "using bottom-left orientation");
|
|
roentgen |
b75cab |
orientation = ORIENTATION_BOTLEFT;
|
|
roentgen |
b75cab |
/* fall thru... */
|
|
roentgen |
b75cab |
case ORIENTATION_LEFTBOT: /* XXX */
|
|
roentgen |
b75cab |
case ORIENTATION_BOTLEFT:
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case ORIENTATION_TOPRIGHT:
|
|
roentgen |
b75cab |
case ORIENTATION_RIGHTTOP: /* XXX */
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
TIFFWarning(TIFFFileName(in), "using top-left orientation");
|
|
roentgen |
b75cab |
orientation = ORIENTATION_TOPLEFT;
|
|
roentgen |
b75cab |
/* fall thru... */
|
|
roentgen |
b75cab |
case ORIENTATION_LEFTTOP: /* XXX */
|
|
roentgen |
b75cab |
case ORIENTATION_TOPLEFT:
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Choose tiles/strip for the output image according to
|
|
roentgen |
b75cab |
* the command line arguments (-tiles, -strips) and the
|
|
roentgen |
b75cab |
* structure of the input image.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (outtiled == -1)
|
|
roentgen |
b75cab |
outtiled = TIFFIsTiled(in);
|
|
roentgen |
b75cab |
if (outtiled) {
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Setup output file's tile width&height. If either
|
|
roentgen |
b75cab |
* is not specified, use either the value from the
|
|
roentgen |
b75cab |
* input image or, if nothing is defined, use the
|
|
roentgen |
b75cab |
* library default.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (tilewidth == (uint32) -1)
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
|
|
roentgen |
b75cab |
if (tilelength == (uint32) -1)
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
|
|
roentgen |
b75cab |
TIFFDefaultTileSize(out, &tilewidth, &tilelength);
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* RowsPerStrip is left unspecified: use either the
|
|
roentgen |
b75cab |
* value from the input image or, if nothing is defined,
|
|
roentgen |
b75cab |
* use the library default.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (rowsperstrip == (uint32) 0) {
|
|
roentgen |
b75cab |
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,
|
|
roentgen |
b75cab |
&rowsperstrip)) {
|
|
roentgen |
b75cab |
rowsperstrip =
|
|
roentgen |
b75cab |
TIFFDefaultStripSize(out, rowsperstrip);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (rowsperstrip > length && rowsperstrip != (uint32)-1)
|
|
roentgen |
b75cab |
rowsperstrip = length;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
else if (rowsperstrip == (uint32) -1)
|
|
roentgen |
b75cab |
rowsperstrip = length;
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (config != (uint16) -1)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_PLANARCONFIG, config);
|
|
roentgen |
b75cab |
if (samplesperpixel <= 4)
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
|
|
roentgen |
b75cab |
/* SMinSampleValue & SMaxSampleValue */
|
|
roentgen |
b75cab |
switch (compression) {
|
|
roentgen |
b75cab |
case COMPRESSION_JPEG:
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case COMPRESSION_JBIG:
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXDCS, 1, TIFF_ASCII);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case COMPRESSION_LZW:
|
|
roentgen |
b75cab |
case COMPRESSION_ADOBE_DEFLATE:
|
|
roentgen |
b75cab |
case COMPRESSION_DEFLATE:
|
|
roentgen |
b75cab |
case COMPRESSION_LZMA:
|
|
roentgen |
b75cab |
if (predictor != (uint16)-1)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_PREDICTOR, predictor);
|
|
roentgen |
b75cab |
if (preset != -1) {
|
|
roentgen |
b75cab |
if (compression == COMPRESSION_ADOBE_DEFLATE
|
|
roentgen |
b75cab |
|| compression == COMPRESSION_DEFLATE)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_ZIPQUALITY, preset);
|
|
roentgen |
b75cab |
else if (compression == COMPRESSION_LZMA)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_LZMAPRESET, preset);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case COMPRESSION_CCITTFAX3:
|
|
roentgen |
b75cab |
case COMPRESSION_CCITTFAX4:
|
|
roentgen |
b75cab |
if (compression == COMPRESSION_CCITTFAX3) {
|
|
roentgen |
b75cab |
if (g3opts != (uint32) -1)
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
|
|
roentgen |
b75cab |
g3opts);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
|
|
roentgen |
b75cab |
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint32 len32;
|
|
roentgen |
b75cab |
void** data;
|
|
roentgen |
b75cab |
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint16 ninks;
|
|
roentgen |
b75cab |
const char* inknames;
|
|
roentgen |
b75cab |
if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
|
|
roentgen |
b75cab |
if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
|
|
roentgen |
b75cab |
int inknameslen = strlen(inknames) + 1;
|
|
roentgen |
b75cab |
const char* cp = inknames;
|
|
roentgen |
b75cab |
while (ninks > 1) {
|
|
roentgen |
b75cab |
cp = strchr(cp, '\0');
|
|
roentgen |
b75cab |
cp++;
|
|
roentgen |
b75cab |
inknameslen += (strlen(cp) + 1);
|
|
roentgen |
b75cab |
ninks--;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
unsigned short pg0, pg1;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (pageInSeq == 1) {
|
|
roentgen |
b75cab |
if (pageNum < 0) /* only one input file */ {
|
|
roentgen |
b75cab |
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1))
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
|
|
roentgen |
b75cab |
if (pageNum < 0) /* only one input file */
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (p = tags; p < &tags[NTAGS]; p++)
|
|
roentgen |
b75cab |
CopyTag(p->tag, p->count, p->type);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
|
|
roentgen |
b75cab |
return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Copy Functions.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
#define DECLAREcpFunc(x) \
|
|
roentgen |
b75cab |
static int x(TIFF* in, TIFF* out, \
|
|
roentgen |
b75cab |
uint32 imagelength, uint32 imagewidth, tsample_t spp)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define DECLAREreadFunc(x) \
|
|
roentgen |
b75cab |
static int x(TIFF* in, \
|
|
roentgen |
b75cab |
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
|
|
roentgen |
b75cab |
typedef int (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define DECLAREwriteFunc(x) \
|
|
roentgen |
b75cab |
static int x(TIFF* out, \
|
|
roentgen |
b75cab |
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
|
|
roentgen |
b75cab |
typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig -> contig by scanline for rows/strip change.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContig2ContigByRow)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t scanlinesize = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tdata_t buf;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
buf = _TIFFmalloc(scanlinesize);
|
|
roentgen |
b75cab |
if (!buf)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(buf, 0, scanlinesize);
|
|
roentgen |
b75cab |
(void) imagewidth; (void) spp;
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
typedef void biasFn (void *image, void *bias, uint32 pixels);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#define subtract(bits) \
|
|
roentgen |
b75cab |
static void subtract##bits (void *i, void *b, uint32 pixels)\
|
|
roentgen |
b75cab |
{\
|
|
roentgen |
b75cab |
uint##bits *image = i;\
|
|
roentgen |
b75cab |
uint##bits *bias = b;\
|
|
roentgen |
b75cab |
while (pixels--) {\
|
|
roentgen |
b75cab |
*image = *image > *bias ? *image-*bias : 0;\
|
|
roentgen |
b75cab |
image++, bias++; \
|
|
roentgen |
b75cab |
} \
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
subtract(8)
|
|
roentgen |
b75cab |
subtract(16)
|
|
roentgen |
b75cab |
subtract(32)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static biasFn *lineSubtractFn (unsigned bits)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
switch (bits) {
|
|
roentgen |
b75cab |
case 8: return subtract8;
|
|
roentgen |
b75cab |
case 16: return subtract16;
|
|
roentgen |
b75cab |
case 32: return subtract32;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
return NULL;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig -> contig by scanline while subtracting a bias image.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpBiasedContig2Contig)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
if (spp == 1) {
|
|
roentgen |
b75cab |
tsize_t biasSize = TIFFScanlineSize(bias);
|
|
roentgen |
b75cab |
tsize_t bufSize = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tdata_t buf, biasBuf;
|
|
roentgen |
b75cab |
uint32 biasWidth = 0, biasLength = 0;
|
|
roentgen |
b75cab |
TIFFGetField(bias, TIFFTAG_IMAGEWIDTH, &biasWidth);
|
|
roentgen |
b75cab |
TIFFGetField(bias, TIFFTAG_IMAGELENGTH, &biasLength);
|
|
roentgen |
b75cab |
if (biasSize == bufSize &&
|
|
roentgen |
b75cab |
imagelength == biasLength && imagewidth == biasWidth) {
|
|
roentgen |
b75cab |
uint16 sampleBits = 0;
|
|
roentgen |
b75cab |
biasFn *subtractLine;
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &sampleBits);
|
|
roentgen |
b75cab |
subtractLine = lineSubtractFn (sampleBits);
|
|
roentgen |
b75cab |
if (subtractLine) {
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
buf = _TIFFmalloc(bufSize);
|
|
roentgen |
b75cab |
biasBuf = _TIFFmalloc(bufSize);
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, buf, row, 0) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFReadScanline(bias, biasBuf, row, 0) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read biased scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
subtractLine (buf, biasBuf, imagewidth);
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
_TIFFfree(biasBuf);
|
|
roentgen |
b75cab |
TIFFSetDirectory(bias,
|
|
roentgen |
b75cab |
TIFFCurrentDirectory(bias)); /* rewind */
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
_TIFFfree(biasBuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"No support for biasing %d bit pixels\n",
|
|
roentgen |
b75cab |
sampleBits);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Bias image %s,%d\nis not the same size as %s,%d\n",
|
|
roentgen |
b75cab |
TIFFFileName(bias), TIFFCurrentDirectory(bias),
|
|
roentgen |
b75cab |
TIFFFileName(in), TIFFCurrentDirectory(in));
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Can't bias %s,%d as it has >1 Sample/Pixel\n",
|
|
roentgen |
b75cab |
TIFFFileName(in), TIFFCurrentDirectory(in));
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Strip -> strip for change in encoding.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpDecodedStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t stripsize = TIFFStripSize(in);
|
|
roentgen |
b75cab |
tdata_t buf = _TIFFmalloc(stripsize);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) imagewidth; (void) spp;
|
|
roentgen |
b75cab |
if (buf) {
|
|
roentgen |
b75cab |
tstrip_t s, ns = TIFFNumberOfStrips(in);
|
|
roentgen |
b75cab |
uint32 row = 0;
|
|
roentgen |
b75cab |
_TIFFmemset(buf, 0, stripsize);
|
|
roentgen |
b75cab |
for (s = 0; s < ns; s++) {
|
|
roentgen |
b75cab |
tsize_t cc = (row + rowsperstrip > imagelength) ?
|
|
roentgen |
b75cab |
TIFFVStripSize(in, imagelength - row) : stripsize;
|
|
roentgen |
b75cab |
if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read strip %lu",
|
|
roentgen |
b75cab |
(unsigned long) s);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write strip %lu",
|
|
roentgen |
b75cab |
(unsigned long) s);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
row += rowsperstrip;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't allocate memory buffer of size %lu "
|
|
roentgen |
b75cab |
"to read strips", (unsigned long) stripsize);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate -> separate by row for rows/strip change.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparate2SeparateByRow)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t scanlinesize = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tdata_t buf;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) imagewidth;
|
|
roentgen |
b75cab |
buf = _TIFFmalloc(scanlinesize);
|
|
roentgen |
b75cab |
if (!buf)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(buf, 0, scanlinesize);
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(out, buf, row, s) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig -> separate by row.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContig2SeparateByRow)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t scanlinesizein = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tsize_t scanlinesizeout = TIFFScanlineSize(out);
|
|
roentgen |
b75cab |
tdata_t inbuf;
|
|
roentgen |
b75cab |
tdata_t outbuf;
|
|
roentgen |
b75cab |
register uint8 *inp, *outp;
|
|
roentgen |
b75cab |
register uint32 n;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
inbuf = _TIFFmalloc(scanlinesizein);
|
|
roentgen |
b75cab |
outbuf = _TIFFmalloc(scanlinesizeout);
|
|
roentgen |
b75cab |
if (!inbuf || !outbuf)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(inbuf, 0, scanlinesizein);
|
|
roentgen |
b75cab |
_TIFFmemset(outbuf, 0, scanlinesizeout);
|
|
roentgen |
b75cab |
/* unpack channels */
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, inbuf, row, 0) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
inp = ((uint8*)inbuf) + s;
|
|
roentgen |
b75cab |
outp = (uint8*)outbuf;
|
|
roentgen |
b75cab |
for (n = imagewidth; n-- > 0;) {
|
|
roentgen |
b75cab |
*outp++ = *inp;
|
|
roentgen |
b75cab |
inp += spp;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(out, outbuf, row, s) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (inbuf) _TIFFfree(inbuf);
|
|
roentgen |
b75cab |
if (outbuf) _TIFFfree(outbuf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
if (inbuf) _TIFFfree(inbuf);
|
|
roentgen |
b75cab |
if (outbuf) _TIFFfree(outbuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate -> contig by row.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparate2ContigByRow)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t scanlinesizein = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tsize_t scanlinesizeout = TIFFScanlineSize(out);
|
|
roentgen |
b75cab |
tdata_t inbuf;
|
|
roentgen |
b75cab |
tdata_t outbuf;
|
|
roentgen |
b75cab |
register uint8 *inp, *outp;
|
|
roentgen |
b75cab |
register uint32 n;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
inbuf = _TIFFmalloc(scanlinesizein);
|
|
roentgen |
b75cab |
outbuf = _TIFFmalloc(scanlinesizeout);
|
|
roentgen |
b75cab |
if (!inbuf || !outbuf)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(inbuf, 0, scanlinesizein);
|
|
roentgen |
b75cab |
_TIFFmemset(outbuf, 0, scanlinesizeout);
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
/* merge channels */
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, inbuf, row, s) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
inp = (uint8*)inbuf;
|
|
roentgen |
b75cab |
outp = ((uint8*)outbuf) + s;
|
|
roentgen |
b75cab |
for (n = imagewidth; n-- > 0;) {
|
|
roentgen |
b75cab |
*outp = *inp++;
|
|
roentgen |
b75cab |
outp += spp;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(out, outbuf, row, 0) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
goto bad;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (inbuf) _TIFFfree(inbuf);
|
|
roentgen |
b75cab |
if (outbuf) _TIFFfree(outbuf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
bad:
|
|
roentgen |
b75cab |
if (inbuf) _TIFFfree(inbuf);
|
|
roentgen |
b75cab |
if (outbuf) _TIFFfree(outbuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
cpStripToTile(uint8* out, uint8* in,
|
|
roentgen |
b75cab |
uint32 rows, uint32 cols, int outskew, int inskew)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
while (rows-- > 0) {
|
|
roentgen |
b75cab |
uint32 j = cols;
|
|
roentgen |
b75cab |
while (j-- > 0)
|
|
roentgen |
b75cab |
*out++ = *in++;
|
|
roentgen |
b75cab |
out += outskew;
|
|
roentgen |
b75cab |
in += inskew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
cpContigBufToSeparateBuf(uint8* out, uint8* in,
|
|
roentgen |
b75cab |
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
|
|
roentgen |
b75cab |
int bytes_per_sample )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
while (rows-- > 0) {
|
|
roentgen |
b75cab |
uint32 j = cols;
|
|
roentgen |
b75cab |
while (j-- > 0)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int n = bytes_per_sample;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
while( n-- ) {
|
|
roentgen |
b75cab |
*out++ = *in++;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
in += (spp-1) * bytes_per_sample;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
out += outskew;
|
|
roentgen |
b75cab |
in += inskew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
cpSeparateBufToContigBuf(uint8* out, uint8* in,
|
|
roentgen |
b75cab |
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
|
|
roentgen |
b75cab |
int bytes_per_sample)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
while (rows-- > 0) {
|
|
roentgen |
b75cab |
uint32 j = cols;
|
|
roentgen |
b75cab |
while (j-- > 0) {
|
|
roentgen |
b75cab |
int n = bytes_per_sample;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
while( n-- ) {
|
|
roentgen |
b75cab |
*out++ = *in++;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
out += (spp-1)*bytes_per_sample;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
out += outskew;
|
|
roentgen |
b75cab |
in += inskew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
|
|
roentgen |
b75cab |
uint32 imagelength, uint32 imagewidth, tsample_t spp)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int status = 0;
|
|
roentgen |
b75cab |
tdata_t buf = NULL;
|
|
roentgen |
b75cab |
tsize_t scanlinesize = TIFFRasterScanlineSize(in);
|
|
roentgen |
b75cab |
tsize_t bytes = scanlinesize * (tsize_t)imagelength;
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* XXX: Check for integer overflow.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (scanlinesize
|
|
roentgen |
b75cab |
&& imagelength
|
|
roentgen |
b75cab |
&& bytes / (tsize_t)imagelength == scanlinesize) {
|
|
roentgen |
b75cab |
buf = _TIFFmalloc(bytes);
|
|
roentgen |
b75cab |
if (buf) {
|
|
roentgen |
b75cab |
if ((*fin)(in, (uint8*)buf, imagelength,
|
|
roentgen |
b75cab |
imagewidth, spp)) {
|
|
roentgen |
b75cab |
status = (*fout)(out, (uint8*)buf,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(buf);
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't allocate space for image buffer");
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in), "Error, no space for image buffer");
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return status;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREreadFunc(readContigStripsIntoBuffer)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tsize_t scanlinesize = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
uint8* bufp = buf;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) imagewidth; (void) spp;
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += scanlinesize;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREreadFunc(readSeparateStripsIntoBuffer)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int status = 1;
|
|
roentgen |
b75cab |
tsize_t scanlinesize = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
tdata_t scanline;
|
|
roentgen |
b75cab |
if (!scanlinesize)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
scanline = _TIFFmalloc(scanlinesize);
|
|
roentgen |
b75cab |
if (!scanline)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(scanline, 0, scanlinesize);
|
|
roentgen |
b75cab |
(void) imagewidth;
|
|
roentgen |
b75cab |
if (scanline) {
|
|
roentgen |
b75cab |
uint8* bufp = (uint8*) buf;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row++) {
|
|
roentgen |
b75cab |
/* merge channels */
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
uint8* bp = bufp + s;
|
|
roentgen |
b75cab |
tsize_t n = scanlinesize;
|
|
roentgen |
b75cab |
uint8* sbuf = scanline;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (TIFFReadScanline(in, scanline, row, s) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read scanline %lu",
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
status = 0;
|
|
roentgen |
b75cab |
goto done;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
while (n-- > 0)
|
|
roentgen |
b75cab |
*bp = *sbuf++, bp += spp;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += scanlinesize * spp;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
done:
|
|
roentgen |
b75cab |
_TIFFfree(scanline);
|
|
roentgen |
b75cab |
return status;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREreadFunc(readContigTilesIntoBuffer)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int status = 1;
|
|
roentgen |
b75cab |
tsize_t tilesize = TIFFTileSize(in);
|
|
roentgen |
b75cab |
tdata_t tilebuf;
|
|
roentgen |
b75cab |
uint32 imagew = TIFFScanlineSize(in);
|
|
roentgen |
b75cab |
uint32 tilew = TIFFTileRowSize(in);
|
|
roentgen |
b75cab |
int iskew = imagew - tilew;
|
|
roentgen |
b75cab |
uint8* bufp = (uint8*) buf;
|
|
roentgen |
b75cab |
uint32 tw, tl;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) spp;
|
|
roentgen |
b75cab |
tilebuf = _TIFFmalloc(tilesize);
|
|
roentgen |
b75cab |
if (tilebuf == 0)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(tilebuf, 0, tilesize);
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += tl) {
|
|
roentgen |
b75cab |
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
|
|
roentgen |
b75cab |
uint32 colb = 0;
|
|
roentgen |
b75cab |
uint32 col;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (col = 0; col < imagewidth; col += tw) {
|
|
roentgen |
b75cab |
if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read tile at %lu %lu",
|
|
roentgen |
b75cab |
(unsigned long) col,
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
status = 0;
|
|
roentgen |
b75cab |
goto done;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (colb + tilew > imagew) {
|
|
roentgen |
b75cab |
uint32 width = imagew - colb;
|
|
roentgen |
b75cab |
uint32 oskew = tilew - width;
|
|
roentgen |
b75cab |
cpStripToTile(bufp + colb,
|
|
roentgen |
b75cab |
tilebuf, nrow, width,
|
|
roentgen |
b75cab |
oskew + iskew, oskew );
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
cpStripToTile(bufp + colb,
|
|
roentgen |
b75cab |
tilebuf, nrow, tilew,
|
|
roentgen |
b75cab |
iskew, 0);
|
|
roentgen |
b75cab |
colb += tilew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += imagew * nrow;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
done:
|
|
roentgen |
b75cab |
_TIFFfree(tilebuf);
|
|
roentgen |
b75cab |
return status;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREreadFunc(readSeparateTilesIntoBuffer)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
int status = 1;
|
|
roentgen |
b75cab |
uint32 imagew = TIFFRasterScanlineSize(in);
|
|
roentgen |
b75cab |
uint32 tilew = TIFFTileRowSize(in);
|
|
roentgen |
b75cab |
int iskew = imagew - tilew*spp;
|
|
roentgen |
b75cab |
tsize_t tilesize = TIFFTileSize(in);
|
|
roentgen |
b75cab |
tdata_t tilebuf;
|
|
roentgen |
b75cab |
uint8* bufp = (uint8*) buf;
|
|
roentgen |
b75cab |
uint32 tw, tl;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
uint16 bps, bytes_per_sample;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
tilebuf = _TIFFmalloc(tilesize);
|
|
roentgen |
b75cab |
if (tilebuf == 0)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(tilebuf, 0, tilesize);
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
|
|
roentgen |
b75cab |
assert( bps % 8 == 0 );
|
|
roentgen |
b75cab |
bytes_per_sample = bps/8;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += tl) {
|
|
roentgen |
b75cab |
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
|
|
roentgen |
b75cab |
uint32 colb = 0;
|
|
roentgen |
b75cab |
uint32 col;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (col = 0; col < imagewidth; col += tw) {
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
|
|
roentgen |
b75cab |
&& !ignore) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(in),
|
|
roentgen |
b75cab |
"Error, can't read tile at %lu %lu, "
|
|
roentgen |
b75cab |
"sample %lu",
|
|
roentgen |
b75cab |
(unsigned long) col,
|
|
roentgen |
b75cab |
(unsigned long) row,
|
|
roentgen |
b75cab |
(unsigned long) s);
|
|
roentgen |
b75cab |
status = 0;
|
|
roentgen |
b75cab |
goto done;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Tile is clipped horizontally. Calculate
|
|
roentgen |
b75cab |
* visible portion and skewing factors.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (colb + tilew*spp > imagew) {
|
|
roentgen |
b75cab |
uint32 width = imagew - colb;
|
|
roentgen |
b75cab |
int oskew = tilew*spp - width;
|
|
roentgen |
b75cab |
cpSeparateBufToContigBuf(
|
|
roentgen |
b75cab |
bufp+colb+s*bytes_per_sample,
|
|
roentgen |
b75cab |
tilebuf, nrow,
|
|
roentgen |
b75cab |
width/(spp*bytes_per_sample),
|
|
roentgen |
b75cab |
oskew + iskew,
|
|
roentgen |
b75cab |
oskew/spp, spp,
|
|
roentgen |
b75cab |
bytes_per_sample);
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
cpSeparateBufToContigBuf(
|
|
roentgen |
b75cab |
bufp+colb+s*bytes_per_sample,
|
|
roentgen |
b75cab |
tilebuf, nrow, tw,
|
|
roentgen |
b75cab |
iskew, 0, spp,
|
|
roentgen |
b75cab |
bytes_per_sample);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
colb += tilew*spp;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += imagew * nrow;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
done:
|
|
roentgen |
b75cab |
_TIFFfree(tilebuf);
|
|
roentgen |
b75cab |
return status;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREwriteFunc(writeBufferToContigStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint32 row, rowsperstrip;
|
|
roentgen |
b75cab |
tstrip_t strip = 0;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) imagewidth; (void) spp;
|
|
roentgen |
b75cab |
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += rowsperstrip) {
|
|
roentgen |
b75cab |
uint32 nrows = (row+rowsperstrip > imagelength) ?
|
|
roentgen |
b75cab |
imagelength-row : rowsperstrip;
|
|
roentgen |
b75cab |
tsize_t stripsize = TIFFVStripSize(out, nrows);
|
|
roentgen |
b75cab |
if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write strip %u", strip - 1);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
buf += stripsize;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREwriteFunc(writeBufferToSeparateStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint32 rowsize = imagewidth * spp;
|
|
roentgen |
b75cab |
uint32 rowsperstrip;
|
|
roentgen |
b75cab |
tsize_t stripsize = TIFFStripSize(out);
|
|
roentgen |
b75cab |
tdata_t obuf;
|
|
roentgen |
b75cab |
tstrip_t strip = 0;
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
obuf = _TIFFmalloc(stripsize);
|
|
roentgen |
b75cab |
if (obuf == NULL)
|
|
roentgen |
b75cab |
return (0);
|
|
roentgen |
b75cab |
_TIFFmemset(obuf, 0, stripsize);
|
|
roentgen |
b75cab |
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += rowsperstrip) {
|
|
roentgen |
b75cab |
uint32 nrows = (row+rowsperstrip > imagelength) ?
|
|
roentgen |
b75cab |
imagelength-row : rowsperstrip;
|
|
roentgen |
b75cab |
tsize_t stripsize = TIFFVStripSize(out, nrows);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
cpContigBufToSeparateBuf(
|
|
roentgen |
b75cab |
obuf, (uint8*) buf + row*rowsize + s,
|
|
roentgen |
b75cab |
nrows, imagewidth, 0, 0, spp, 1);
|
|
roentgen |
b75cab |
if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write strip %u",
|
|
roentgen |
b75cab |
strip - 1);
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREwriteFunc(writeBufferToContigTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint32 imagew = TIFFScanlineSize(out);
|
|
roentgen |
b75cab |
uint32 tilew = TIFFTileRowSize(out);
|
|
roentgen |
b75cab |
int iskew = imagew - tilew;
|
|
roentgen |
b75cab |
tsize_t tilesize = TIFFTileSize(out);
|
|
roentgen |
b75cab |
tdata_t obuf;
|
|
roentgen |
b75cab |
uint8* bufp = (uint8*) buf;
|
|
roentgen |
b75cab |
uint32 tl, tw;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) spp;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
obuf = _TIFFmalloc(TIFFTileSize(out));
|
|
roentgen |
b75cab |
if (obuf == NULL)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(obuf, 0, tilesize);
|
|
roentgen |
b75cab |
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
|
|
roentgen |
b75cab |
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += tilelength) {
|
|
roentgen |
b75cab |
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
|
|
roentgen |
b75cab |
uint32 colb = 0;
|
|
roentgen |
b75cab |
uint32 col;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (col = 0; col < imagewidth; col += tw) {
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Tile is clipped horizontally. Calculate
|
|
roentgen |
b75cab |
* visible portion and skewing factors.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (colb + tilew > imagew) {
|
|
roentgen |
b75cab |
uint32 width = imagew - colb;
|
|
roentgen |
b75cab |
int oskew = tilew - width;
|
|
roentgen |
b75cab |
cpStripToTile(obuf, bufp + colb, nrow, width,
|
|
roentgen |
b75cab |
oskew, oskew + iskew);
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
cpStripToTile(obuf, bufp + colb, nrow, tilew,
|
|
roentgen |
b75cab |
0, iskew);
|
|
roentgen |
b75cab |
if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write tile at %lu %lu",
|
|
roentgen |
b75cab |
(unsigned long) col,
|
|
roentgen |
b75cab |
(unsigned long) row);
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
colb += tilew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += nrow * imagew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
DECLAREwriteFunc(writeBufferToSeparateTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint32 imagew = TIFFScanlineSize(out);
|
|
roentgen |
b75cab |
tsize_t tilew = TIFFTileRowSize(out);
|
|
roentgen |
b75cab |
uint32 iimagew = TIFFRasterScanlineSize(out);
|
|
roentgen |
b75cab |
int iskew = iimagew - tilew*spp;
|
|
roentgen |
b75cab |
tsize_t tilesize = TIFFTileSize(out);
|
|
roentgen |
b75cab |
tdata_t obuf;
|
|
roentgen |
b75cab |
uint8* bufp = (uint8*) buf;
|
|
roentgen |
b75cab |
uint32 tl, tw;
|
|
roentgen |
b75cab |
uint32 row;
|
|
roentgen |
b75cab |
uint16 bps, bytes_per_sample;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
obuf = _TIFFmalloc(TIFFTileSize(out));
|
|
roentgen |
b75cab |
if (obuf == NULL)
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
_TIFFmemset(obuf, 0, tilesize);
|
|
roentgen |
b75cab |
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
|
|
roentgen |
b75cab |
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
|
|
roentgen |
b75cab |
(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
|
|
roentgen |
b75cab |
assert( bps % 8 == 0 );
|
|
roentgen |
b75cab |
bytes_per_sample = bps/8;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (row = 0; row < imagelength; row += tl) {
|
|
roentgen |
b75cab |
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
|
|
roentgen |
b75cab |
uint32 colb = 0;
|
|
roentgen |
b75cab |
uint32 col;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (col = 0; col < imagewidth; col += tw) {
|
|
roentgen |
b75cab |
tsample_t s;
|
|
roentgen |
b75cab |
for (s = 0; s < spp; s++) {
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Tile is clipped horizontally. Calculate
|
|
roentgen |
b75cab |
* visible portion and skewing factors.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
if (colb + tilew > imagew) {
|
|
roentgen |
b75cab |
uint32 width = (imagew - colb);
|
|
roentgen |
b75cab |
int oskew = tilew - width;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
cpContigBufToSeparateBuf(obuf,
|
|
roentgen |
b75cab |
bufp + (colb*spp) + s,
|
|
roentgen |
b75cab |
nrow, width/bytes_per_sample,
|
|
roentgen |
b75cab |
oskew, (oskew*spp)+iskew, spp,
|
|
roentgen |
b75cab |
bytes_per_sample);
|
|
roentgen |
b75cab |
} else
|
|
roentgen |
b75cab |
cpContigBufToSeparateBuf(obuf,
|
|
roentgen |
b75cab |
bufp + (colb*spp) + s,
|
|
roentgen |
b75cab |
nrow, tilewidth,
|
|
roentgen |
b75cab |
0, iskew, spp,
|
|
roentgen |
b75cab |
bytes_per_sample);
|
|
roentgen |
b75cab |
if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
|
|
roentgen |
b75cab |
TIFFError(TIFFFileName(out),
|
|
roentgen |
b75cab |
"Error, can't write tile at %lu %lu "
|
|
roentgen |
b75cab |
"sample %lu",
|
|
roentgen |
b75cab |
(unsigned long) col,
|
|
roentgen |
b75cab |
(unsigned long) row,
|
|
roentgen |
b75cab |
(unsigned long) s);
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
colb += tilew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
bufp += nrow * iimagew;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
_TIFFfree(obuf);
|
|
roentgen |
b75cab |
return 1;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig strips -> contig tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigStrips2ContigTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigStripsIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig strips -> separate tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigStrips2SeparateTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigStripsIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate strips -> contig tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateStrips2ContigTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateStripsIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate strips -> separate tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateStripsIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig strips -> contig tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigTiles2ContigTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig tiles -> separate tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigTiles2SeparateTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate tiles -> contig tiles.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateTiles2ContigTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate tiles -> separate tiles (tile dimension change).
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateTiles,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig tiles -> contig tiles (tile dimension change).
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigTiles2ContigStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigStrips,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Contig tiles -> separate strips.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpContigTiles2SeparateStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readContigTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateStrips,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate tiles -> contig strips.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateTiles2ContigStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToContigStrips,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Separate tiles -> separate strips.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return cpImage(in, out,
|
|
roentgen |
b75cab |
readSeparateTilesIntoBuffer,
|
|
roentgen |
b75cab |
writeBufferToSeparateStrips,
|
|
roentgen |
b75cab |
imagelength, imagewidth, spp);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Select the appropriate copy function to use.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
static copyFunc
|
|
roentgen |
b75cab |
pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
uint16 shortv;
|
|
roentgen |
b75cab |
uint32 w, l, tw, tl;
|
|
roentgen |
b75cab |
int bychunk;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
|
|
roentgen |
b75cab |
if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
|
|
roentgen |
b75cab |
fprintf(stderr,
|
|
roentgen |
b75cab |
"%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
|
|
roentgen |
b75cab |
TIFFFileName(in));
|
|
roentgen |
b75cab |
return (NULL);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l);
|
|
roentgen |
b75cab |
if (!(TIFFIsTiled(out) || TIFFIsTiled(in))) {
|
|
roentgen |
b75cab |
uint32 irps = (uint32) -1L;
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps);
|
|
roentgen |
b75cab |
/* if biased, force decoded copying to allow image subtraction */
|
|
roentgen |
b75cab |
bychunk = !bias && (rowsperstrip == irps);
|
|
roentgen |
b75cab |
}else{ /* either in or out is tiled */
|
|
roentgen |
b75cab |
if (bias) {
|
|
roentgen |
b75cab |
fprintf(stderr,
|
|
roentgen |
b75cab |
"%s: Cannot handle tiled configuration w/bias image\n",
|
|
roentgen |
b75cab |
TIFFFileName(in));
|
|
roentgen |
b75cab |
return (NULL);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (TIFFIsTiled(out)) {
|
|
roentgen |
b75cab |
if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
|
|
roentgen |
b75cab |
tw = w;
|
|
roentgen |
b75cab |
if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
|
|
roentgen |
b75cab |
tl = l;
|
|
roentgen |
b75cab |
bychunk = (tw == tilewidth && tl == tilelength);
|
|
roentgen |
b75cab |
} else { /* out's not, so in must be tiled */
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
|
|
roentgen |
b75cab |
TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
|
|
roentgen |
b75cab |
bychunk = (tw == w && tl == rowsperstrip);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
#define T 1
|
|
roentgen |
b75cab |
#define F 0
|
|
roentgen |
b75cab |
#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e)))
|
|
roentgen |
b75cab |
switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) {
|
|
roentgen |
b75cab |
/* Strips -> Tiles */
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,T):
|
|
roentgen |
b75cab |
return cpContigStrips2ContigTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,T):
|
|
roentgen |
b75cab |
return cpContigStrips2SeparateTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,T):
|
|
roentgen |
b75cab |
return cpSeparateStrips2ContigTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T):
|
|
roentgen |
b75cab |
return cpSeparateStrips2SeparateTiles;
|
|
roentgen |
b75cab |
/* Tiles -> Tiles */
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,T):
|
|
roentgen |
b75cab |
return cpContigTiles2ContigTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,T):
|
|
roentgen |
b75cab |
return cpContigTiles2SeparateTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,T):
|
|
roentgen |
b75cab |
return cpSeparateTiles2ContigTiles;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T):
|
|
roentgen |
b75cab |
return cpSeparateTiles2SeparateTiles;
|
|
roentgen |
b75cab |
/* Tiles -> Strips */
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,T):
|
|
roentgen |
b75cab |
return cpContigTiles2ContigStrips;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,T):
|
|
roentgen |
b75cab |
return cpContigTiles2SeparateStrips;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,T):
|
|
roentgen |
b75cab |
return cpSeparateTiles2ContigStrips;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T):
|
|
roentgen |
b75cab |
return cpSeparateTiles2SeparateStrips;
|
|
roentgen |
b75cab |
/* Strips -> Strips */
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,F):
|
|
roentgen |
b75cab |
return bias ? cpBiasedContig2Contig : cpContig2ContigByRow;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,T):
|
|
roentgen |
b75cab |
return cpDecodedStrips;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,T):
|
|
roentgen |
b75cab |
return cpContig2SeparateByRow;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,T):
|
|
roentgen |
b75cab |
return cpSeparate2ContigByRow;
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F):
|
|
roentgen |
b75cab |
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T):
|
|
roentgen |
b75cab |
return cpSeparate2SeparateByRow;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
#undef pack
|
|
roentgen |
b75cab |
#undef F
|
|
roentgen |
b75cab |
#undef T
|
|
roentgen |
b75cab |
fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",
|
|
roentgen |
b75cab |
TIFFFileName(in));
|
|
roentgen |
b75cab |
return (NULL);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/* vim: set ts=8 sts=8 sw=8 noet: */
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Local Variables:
|
|
roentgen |
b75cab |
* mode: c
|
|
roentgen |
b75cab |
* c-basic-offset: 8
|
|
roentgen |
b75cab |
* fill-column: 78
|
|
roentgen |
b75cab |
* End:
|
|
roentgen |
b75cab |
*/
|