752 lines
23 KiB
C
752 lines
23 KiB
C
/*
|
|
* Copyright (c) 1988-1997 Sam Leffler
|
|
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and
|
|
* its documentation for any purpose is hereby granted without fee, provided
|
|
* that (i) the above copyright notices and this permission notice appear in
|
|
* all copies of the software and related documentation, and (ii) the names of
|
|
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
|
* publicity relating to the software without the specific, prior written
|
|
* permission of Sam Leffler and Silicon Graphics.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
|
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
|
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
|
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
|
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
* OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "libport.h"
|
|
#include "tif_config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_STRINGS_H
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include "tiffiop.h"
|
|
|
|
#ifndef EXIT_SUCCESS
|
|
#define EXIT_SUCCESS 0
|
|
#endif
|
|
#ifndef EXIT_FAILURE
|
|
#define EXIT_FAILURE 1
|
|
#endif
|
|
|
|
static TIFFErrorHandler old_error_handler = 0;
|
|
static int status = EXIT_SUCCESS; /* exit status */
|
|
static int showdata = 0; /* show data */
|
|
static int rawdata = 0; /* show raw/decoded data */
|
|
static int showwords = 0; /* show data as bytes/words */
|
|
static int readdata = 0; /* read data in file */
|
|
static int stoponerr = 1; /* stop on first read error */
|
|
|
|
static void usage(int);
|
|
static void tiffinfo(TIFF *, uint16_t, long, int);
|
|
|
|
#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024)
|
|
/* malloc size limit (in bytes)
|
|
* disabled when set to 0 */
|
|
static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC;
|
|
|
|
static void PrivateErrorHandler(const char *module, const char *fmt, va_list ap)
|
|
{
|
|
if (old_error_handler)
|
|
(*old_error_handler)(module, fmt, ap);
|
|
status = EXIT_FAILURE;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int dirnum = -1, multiplefiles, c;
|
|
uint16_t order = 0;
|
|
TIFF *tif;
|
|
#if !HAVE_DECL_OPTARG
|
|
extern int optind;
|
|
extern char *optarg;
|
|
#endif
|
|
long flags = 0;
|
|
uint64_t diroff = 0;
|
|
int chopstrips = 0; /* disable strip chopping */
|
|
|
|
while ((c = getopt(argc, argv, "f:o:M:cdDSjilmrsvwz0123456789h")) != -1)
|
|
switch (c)
|
|
{
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
dirnum = atoi(&argv[optind - 1][1]);
|
|
break;
|
|
case 'd':
|
|
showdata++;
|
|
/* fall through... */
|
|
case 'D':
|
|
readdata++;
|
|
break;
|
|
case 'c':
|
|
flags |= TIFFPRINT_COLORMAP | TIFFPRINT_CURVES;
|
|
break;
|
|
case 'f': /* fill order */
|
|
if (streq(optarg, "lsb2msb"))
|
|
order = FILLORDER_LSB2MSB;
|
|
else if (streq(optarg, "msb2lsb"))
|
|
order = FILLORDER_MSB2LSB;
|
|
else
|
|
usage(EXIT_FAILURE);
|
|
break;
|
|
case 'i':
|
|
stoponerr = 0;
|
|
break;
|
|
case 'M':
|
|
maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20;
|
|
break;
|
|
case 'o':
|
|
diroff = strtoul(optarg, NULL, 0);
|
|
break;
|
|
case 'j':
|
|
flags |= TIFFPRINT_JPEGQTABLES | TIFFPRINT_JPEGACTABLES |
|
|
TIFFPRINT_JPEGDCTABLES;
|
|
break;
|
|
case 'r':
|
|
rawdata = 1;
|
|
break;
|
|
case 's':
|
|
flags |= TIFFPRINT_STRIPS;
|
|
break;
|
|
case 'w':
|
|
showwords = 1;
|
|
break;
|
|
case 'z':
|
|
chopstrips = 1;
|
|
break;
|
|
case 'h':
|
|
usage(EXIT_SUCCESS);
|
|
/*NOTREACHED*/
|
|
break;
|
|
case '?':
|
|
usage(EXIT_FAILURE);
|
|
/*NOTREACHED*/
|
|
break;
|
|
}
|
|
if (optind >= argc)
|
|
usage(EXIT_FAILURE);
|
|
|
|
old_error_handler = TIFFSetErrorHandler(PrivateErrorHandler);
|
|
|
|
multiplefiles = (argc - optind > 1);
|
|
for (; optind < argc; optind++)
|
|
{
|
|
if (multiplefiles)
|
|
printf("File %s:\n", argv[optind]);
|
|
TIFFOpenOptions *opts = TIFFOpenOptionsAlloc();
|
|
if (opts == NULL)
|
|
{
|
|
status = EXIT_FAILURE;
|
|
break;
|
|
}
|
|
TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
|
|
tif = TIFFOpenExt(argv[optind], chopstrips ? "rC" : "rc", opts);
|
|
TIFFOpenOptionsFree(opts);
|
|
if (tif != NULL)
|
|
{
|
|
if (dirnum != -1)
|
|
{
|
|
if (TIFFSetDirectory(tif, (tdir_t)dirnum))
|
|
tiffinfo(tif, order, flags, 1);
|
|
}
|
|
else if (diroff != 0)
|
|
{
|
|
if (TIFFSetSubDirectory(tif, diroff))
|
|
tiffinfo(tif, order, flags, 1);
|
|
}
|
|
else
|
|
{
|
|
do
|
|
{
|
|
toff_t offset = 0;
|
|
tdir_t curdir = TIFFCurrentDirectory(tif);
|
|
printf("=== TIFF directory %u ===\n", curdir);
|
|
tiffinfo(tif, order, flags, 1);
|
|
if (TIFFGetField(tif, TIFFTAG_EXIFIFD, &offset))
|
|
{
|
|
printf("--- EXIF directory within directory %u \n",
|
|
curdir);
|
|
if (TIFFReadEXIFDirectory(tif, offset))
|
|
{
|
|
tiffinfo(tif, order, flags, 0);
|
|
/*-- Go back to previous directory, (directory is
|
|
* reloaded from file!) */
|
|
TIFFSetDirectory(tif, curdir);
|
|
}
|
|
}
|
|
if (TIFFGetField(tif, TIFFTAG_GPSIFD, &offset))
|
|
{
|
|
printf("--- GPS directory within directory %u \n",
|
|
curdir);
|
|
if (TIFFReadGPSDirectory(tif, offset))
|
|
{
|
|
tiffinfo(tif, order, flags, 0);
|
|
TIFFSetDirectory(tif, curdir);
|
|
}
|
|
}
|
|
/*-- Check for SubIFDs --*/
|
|
uint16_t nCount;
|
|
void *vPtr;
|
|
uint64_t *subIFDoffsets = NULL;
|
|
if (TIFFGetField(tif, TIFFTAG_SUBIFD, &nCount, &vPtr))
|
|
{
|
|
if (nCount > 0)
|
|
{
|
|
subIFDoffsets = malloc(nCount * sizeof(uint64_t));
|
|
if (subIFDoffsets != NULL)
|
|
{
|
|
memcpy(subIFDoffsets, vPtr,
|
|
nCount * sizeof(subIFDoffsets[0]));
|
|
printf("--- SubIFD image descriptor tag within "
|
|
"TIFF directory %u with array of %d "
|
|
"SubIFD chains ---\n",
|
|
curdir, nCount);
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
offset = subIFDoffsets[i];
|
|
int s = 0;
|
|
if (TIFFSetSubDirectory(tif, offset))
|
|
{
|
|
/* print info and check for SubIFD chain
|
|
*/
|
|
do
|
|
{
|
|
printf("--- SubIFD %d of chain %d "
|
|
"at offset 0x%" PRIx64
|
|
" (%" PRIu64 "):\n",
|
|
s, i, offset, offset);
|
|
tiffinfo(tif, order, flags, 0);
|
|
s++;
|
|
} while (TIFFReadDirectory(tif));
|
|
}
|
|
}
|
|
TIFFSetDirectory(tif, curdir);
|
|
free(subIFDoffsets);
|
|
subIFDoffsets = NULL;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr,
|
|
"Error: Could not allocate memory for "
|
|
"SubIFDs list. SubIFDs not parsed.\n");
|
|
}
|
|
}
|
|
}
|
|
printf("\n");
|
|
} while (TIFFReadDirectory(tif));
|
|
}
|
|
TIFFClose(tif);
|
|
}
|
|
}
|
|
return (status);
|
|
}
|
|
|
|
static const char usage_info[] =
|
|
"Display information about TIFF files\n\n"
|
|
"usage: tiffinfo [options] input...\n"
|
|
"where options are:\n"
|
|
" -D read data\n"
|
|
" -i ignore read errors\n"
|
|
" -c display data for grey/color response curve or "
|
|
"colormap\n"
|
|
" -d display raw/decoded image data\n"
|
|
" -f lsb2msb force lsb-to-msb FillOrder for input\n"
|
|
" -f msb2lsb force msb-to-lsb FillOrder for input\n"
|
|
" -j show JPEG tables\n"
|
|
" -o offset set initial directory offset\n"
|
|
" -r read/display raw image data instead of decoded data\n"
|
|
" -s display strip offsets and byte counts\n"
|
|
" -w display raw data in words rather than bytes\n"
|
|
" -z enable strip chopping\n"
|
|
" -M size set the memory allocation limit in MiB. 0 to disable limit\n"
|
|
" -# set initial directory (first directory is # 0)\n";
|
|
|
|
static void usage(int code)
|
|
{
|
|
FILE *out = (code == EXIT_SUCCESS) ? stdout : stderr;
|
|
|
|
fprintf(out, "%s\n\n", TIFFGetVersion());
|
|
fprintf(out, "%s", usage_info);
|
|
exit(code);
|
|
}
|
|
|
|
static void ShowStrip(tstrip_t strip, unsigned char *pp, uint32_t nrow,
|
|
tsize_t scanline)
|
|
{
|
|
register tsize_t cc;
|
|
|
|
printf("Strip %" PRIu32 ":\n", strip);
|
|
while (nrow-- > 0)
|
|
{
|
|
for (cc = 0; cc < scanline; cc++)
|
|
{
|
|
printf(" %02x", *pp++);
|
|
if (((cc + 1) % 24) == 0)
|
|
putchar('\n');
|
|
}
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
void TIFFReadContigStripData(TIFF *tif)
|
|
{
|
|
unsigned char *buf;
|
|
tsize_t scanline = TIFFScanlineSize(tif);
|
|
tmsize_t stripsize = TIFFStripSize(tif);
|
|
|
|
if (maxMalloc != 0 && stripsize > maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
stripsize, maxMalloc);
|
|
return;
|
|
}
|
|
buf = (unsigned char *)_TIFFmalloc(stripsize);
|
|
if (buf)
|
|
{
|
|
uint32_t row, h = 0;
|
|
uint32_t rowsperstrip = (uint32_t)-1;
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
|
|
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
for (row = 0; row < h; row += rowsperstrip)
|
|
{
|
|
uint32_t nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
|
|
tstrip_t strip = TIFFComputeStrip(tif, row, 0);
|
|
if (TIFFReadEncodedStrip(tif, strip, buf, nrow * scanline) < 0)
|
|
{
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
ShowStrip(strip, buf, nrow, scanline);
|
|
}
|
|
_TIFFfree(buf);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Cannot allocate %" TIFF_SSIZE_FORMAT " bytes.\n",
|
|
stripsize);
|
|
}
|
|
}
|
|
|
|
void TIFFReadSeparateStripData(TIFF *tif)
|
|
{
|
|
unsigned char *buf;
|
|
tsize_t scanline = TIFFScanlineSize(tif);
|
|
tmsize_t stripsize = TIFFStripSize(tif);
|
|
|
|
if (maxMalloc != 0 && stripsize > maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
stripsize, maxMalloc);
|
|
return;
|
|
}
|
|
buf = (unsigned char *)_TIFFmalloc(stripsize);
|
|
if (buf)
|
|
{
|
|
uint32_t row, h = 0;
|
|
uint32_t rowsperstrip = (uint32_t)-1;
|
|
tsample_t s, samplesperpixel = 0;
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
|
|
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
|
|
for (row = 0; row < h; row += rowsperstrip)
|
|
{
|
|
for (s = 0; s < samplesperpixel; s++)
|
|
{
|
|
uint32_t nrow =
|
|
(row + rowsperstrip > h ? h - row : rowsperstrip);
|
|
tstrip_t strip = TIFFComputeStrip(tif, row, s);
|
|
if (TIFFReadEncodedStrip(tif, strip, buf, nrow * scanline) < 0)
|
|
{
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
ShowStrip(strip, buf, nrow, scanline);
|
|
}
|
|
}
|
|
_TIFFfree(buf);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Cannot allocate %" TIFF_SSIZE_FORMAT " bytes.\n",
|
|
stripsize);
|
|
}
|
|
}
|
|
|
|
static void ShowTile(uint32_t row, uint32_t col, tsample_t sample,
|
|
unsigned char *pp, uint32_t nrow, tsize_t rowsize)
|
|
{
|
|
uint32_t cc;
|
|
|
|
printf("Tile (%" PRIu32 ",%" PRIu32 "", row, col);
|
|
if (sample != (tsample_t)-1)
|
|
printf(",%" PRIu16, sample);
|
|
printf("):\n");
|
|
while (nrow-- > 0)
|
|
{
|
|
for (cc = 0; cc < (uint32_t)rowsize; cc++)
|
|
{
|
|
printf(" %02x", *pp++);
|
|
if (((cc + 1) % 24) == 0)
|
|
putchar('\n');
|
|
}
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
void TIFFReadContigTileData(TIFF *tif)
|
|
{
|
|
unsigned char *buf;
|
|
tmsize_t rowsize = TIFFTileRowSize(tif);
|
|
tmsize_t tilesize = TIFFTileSize(tif);
|
|
|
|
if (maxMalloc != 0 && tilesize > maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
tilesize, maxMalloc);
|
|
return;
|
|
}
|
|
buf = (unsigned char *)_TIFFmalloc(tilesize);
|
|
if (buf)
|
|
{
|
|
uint32_t tw = 0, th = 0, w = 0, h = 0;
|
|
uint32_t row, col;
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
|
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
|
|
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
|
|
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
|
|
if (rowsize == 0 || th > (size_t)(tilesize / rowsize))
|
|
{
|
|
fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n");
|
|
_TIFFfree(buf);
|
|
return;
|
|
}
|
|
for (row = 0; row < h; row += th)
|
|
{
|
|
for (col = 0; col < w; col += tw)
|
|
{
|
|
if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0)
|
|
{
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
ShowTile(row, col, (tsample_t)-1, buf, th, rowsize);
|
|
}
|
|
}
|
|
_TIFFfree(buf);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Cannot allocate %" TIFF_SSIZE_FORMAT " bytes.\n",
|
|
tilesize);
|
|
}
|
|
}
|
|
|
|
void TIFFReadSeparateTileData(TIFF *tif)
|
|
{
|
|
unsigned char *buf;
|
|
tmsize_t rowsize = TIFFTileRowSize(tif);
|
|
tmsize_t tilesize = TIFFTileSize(tif);
|
|
|
|
if (maxMalloc != 0 && tilesize > maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
tilesize, maxMalloc);
|
|
return;
|
|
}
|
|
buf = (unsigned char *)_TIFFmalloc(tilesize);
|
|
if (buf)
|
|
{
|
|
uint32_t tw = 0, th = 0, w = 0, h = 0;
|
|
uint32_t row, col;
|
|
tsample_t s, samplesperpixel = 0;
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
|
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
|
|
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
|
|
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
|
|
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
|
|
if (rowsize == 0 || th > (size_t)(tilesize / rowsize))
|
|
{
|
|
fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n");
|
|
_TIFFfree(buf);
|
|
return;
|
|
}
|
|
for (row = 0; row < h; row += th)
|
|
{
|
|
for (col = 0; col < w; col += tw)
|
|
{
|
|
for (s = 0; s < samplesperpixel; s++)
|
|
{
|
|
if (TIFFReadTile(tif, buf, col, row, 0, s) < 0)
|
|
{
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
ShowTile(row, col, s, buf, th, rowsize);
|
|
}
|
|
}
|
|
}
|
|
_TIFFfree(buf);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Cannot allocate %" TIFF_SSIZE_FORMAT " bytes.\n",
|
|
tilesize);
|
|
}
|
|
}
|
|
|
|
void TIFFReadData(TIFF *tif)
|
|
{
|
|
uint16_t config = PLANARCONFIG_CONTIG;
|
|
|
|
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
|
|
if (TIFFIsTiled(tif))
|
|
{
|
|
if (config == PLANARCONFIG_CONTIG)
|
|
TIFFReadContigTileData(tif);
|
|
else
|
|
TIFFReadSeparateTileData(tif);
|
|
}
|
|
else
|
|
{
|
|
if (config == PLANARCONFIG_CONTIG)
|
|
TIFFReadContigStripData(tif);
|
|
else
|
|
TIFFReadSeparateStripData(tif);
|
|
}
|
|
}
|
|
|
|
static void ShowRawBytes(unsigned char *pp, uint32_t n)
|
|
{
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
printf(" %02x", *pp++);
|
|
if (((i + 1) % 24) == 0)
|
|
printf("\n ");
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
static void ShowRawWords(uint16_t *pp, uint32_t n)
|
|
{
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
printf(" %04" PRIx16, *pp++);
|
|
if (((i + 1) % 15) == 0)
|
|
printf("\n ");
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
static void TIFFReadRawDataStriped(TIFF *tif, int bitrev)
|
|
{
|
|
tstrip_t nstrips = TIFFNumberOfStrips(tif);
|
|
const char *what = "Strip";
|
|
uint64_t *stripbc = NULL;
|
|
|
|
TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
|
|
if (stripbc != NULL && nstrips > 0)
|
|
{
|
|
uint32_t bufsize = 0;
|
|
tdata_t buf = NULL;
|
|
tstrip_t s;
|
|
|
|
for (s = 0; s < nstrips; s++)
|
|
{
|
|
if (stripbc[s] > bufsize || buf == NULL)
|
|
{
|
|
tdata_t newbuf;
|
|
if (maxMalloc != 0 && stripbc[s] > (uint64_t)maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
(tmsize_t)stripbc[s], maxMalloc);
|
|
break;
|
|
}
|
|
newbuf = _TIFFrealloc(buf, (tmsize_t)stripbc[s]);
|
|
if (newbuf == NULL)
|
|
{
|
|
fprintf(stderr,
|
|
"Cannot allocate buffer to read strip %" PRIu32
|
|
"\n",
|
|
s);
|
|
break;
|
|
}
|
|
bufsize = (uint32_t)stripbc[s];
|
|
buf = newbuf;
|
|
}
|
|
if (TIFFReadRawStrip(tif, s, buf, (tmsize_t)stripbc[s]) < 0)
|
|
{
|
|
fprintf(stderr, "Error reading strip %" PRIu32 "\n", s);
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
{
|
|
if (bitrev)
|
|
{
|
|
TIFFReverseBits(buf, (tmsize_t)stripbc[s]);
|
|
printf("%s %" PRIu32 ": (bit reversed)\n ", what, s);
|
|
}
|
|
else
|
|
printf("%s %" PRIu32 ":\n ", what, s);
|
|
if (showwords)
|
|
ShowRawWords((uint16_t *)buf, (uint32_t)stripbc[s] >> 1);
|
|
else
|
|
ShowRawBytes((unsigned char *)buf, (uint32_t)stripbc[s]);
|
|
}
|
|
}
|
|
if (buf != NULL)
|
|
_TIFFfree(buf);
|
|
}
|
|
}
|
|
|
|
static void TIFFReadRawDataTiled(TIFF *tif, int bitrev)
|
|
{
|
|
const char *what = "Tile";
|
|
uint32_t ntiles = TIFFNumberOfTiles(tif);
|
|
uint64_t *tilebc = NULL;
|
|
|
|
TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &tilebc);
|
|
if (tilebc != NULL && ntiles > 0)
|
|
{
|
|
uint64_t bufsize = 0;
|
|
tdata_t buf = NULL;
|
|
uint32_t t;
|
|
|
|
for (t = 0; t < ntiles; t++)
|
|
{
|
|
if (tilebc[t] > bufsize || buf == NULL)
|
|
{
|
|
tdata_t newbuf;
|
|
if (maxMalloc != 0 && tilebc[t] > (uint64_t)maxMalloc)
|
|
{
|
|
fprintf(stderr,
|
|
"Memory allocation attempt %" TIFF_SSIZE_FORMAT
|
|
" over memory limit (%" TIFF_SSIZE_FORMAT ")\n",
|
|
(tmsize_t)tilebc[t], maxMalloc);
|
|
break;
|
|
}
|
|
newbuf = _TIFFrealloc(buf, (tmsize_t)tilebc[t]);
|
|
if (newbuf == NULL)
|
|
{
|
|
fprintf(stderr,
|
|
"Cannot allocate buffer to read tile %" PRIu32 "\n",
|
|
t);
|
|
break;
|
|
}
|
|
bufsize = (uint32_t)tilebc[t];
|
|
buf = newbuf;
|
|
}
|
|
if (TIFFReadRawTile(tif, t, buf, (tmsize_t)tilebc[t]) < 0)
|
|
{
|
|
fprintf(stderr, "Error reading tile %" PRIu32 "\n", t);
|
|
if (stoponerr)
|
|
break;
|
|
}
|
|
else if (showdata)
|
|
{
|
|
if (bitrev)
|
|
{
|
|
TIFFReverseBits(buf, (tmsize_t)tilebc[t]);
|
|
printf("%s %" PRIu32 ": (bit reversed)\n ", what, t);
|
|
}
|
|
else
|
|
{
|
|
printf("%s %" PRIu32 ":\n ", what, t);
|
|
}
|
|
if (showwords)
|
|
{
|
|
ShowRawWords((uint16_t *)buf, (uint32_t)(tilebc[t] >> 1));
|
|
}
|
|
else
|
|
{
|
|
ShowRawBytes((unsigned char *)buf, (uint32_t)tilebc[t]);
|
|
}
|
|
}
|
|
}
|
|
if (buf != NULL)
|
|
_TIFFfree(buf);
|
|
}
|
|
}
|
|
|
|
void TIFFReadRawData(TIFF *tif, int bitrev)
|
|
{
|
|
if (TIFFIsTiled(tif))
|
|
{
|
|
TIFFReadRawDataTiled(tif, bitrev);
|
|
}
|
|
else
|
|
{
|
|
TIFFReadRawDataStriped(tif, bitrev);
|
|
}
|
|
}
|
|
|
|
static void tiffinfo(TIFF *tif, uint16_t order, long flags, int is_image)
|
|
{
|
|
TIFFPrintDirectory(tif, stdout, flags);
|
|
if (!readdata || !is_image)
|
|
return;
|
|
if (rawdata)
|
|
{
|
|
if (order)
|
|
{
|
|
uint16_t o;
|
|
TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &o);
|
|
TIFFReadRawData(tif, o != order);
|
|
}
|
|
else
|
|
TIFFReadRawData(tif, 0);
|
|
}
|
|
else
|
|
{
|
|
if (order)
|
|
TIFFSetField(tif, TIFFTAG_FILLORDER, order);
|
|
TIFFReadData(tif);
|
|
}
|
|
}
|