Reformatting in all other directories using 'pre-commit run'

This commit is contained in:
pre-commit run by Even Rouault
2022-12-08 19:19:36 +01:00
committed by Even Rouault
parent dee020782c
commit aee0113f5e
38 changed files with 8115 additions and 7682 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,30 +2,30 @@
* Copyright (c) 1990-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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
* 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.
*/
/*
* convert a GIF file into a TIFF file.
* based on Paul Haeberli's fromgif program which in turn is
* based on a GIF file reader by Marcel J.E. Mol March 23 1989
* based on a GIF file reader by Marcel J.E. Mol March 23 1989
*
* if input is 320 by 200 pixel aspect is probably 1.2
* if input is 640 350 pixel aspect is probably 1.37
@@ -33,67 +33,65 @@
*/
#include "tif_config.h"
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#include "libport.h"
#endif
#include "tiffio.h"
#define GIFGAMMA (1.5) /* smaller makes output img brighter */
#define IMAX 0xffff /* max intensity value */
#define EXTRAFUDGE 128 /* some people write BAD .gif files */
#define GIFGAMMA (1.5) /* smaller makes output img brighter */
#define IMAX 0xffff /* max intensity value */
#define EXTRAFUDGE 128 /* some people write BAD .gif files */
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
unsigned short gamtab[256];
void
makegamtab(float gam)
void makegamtab(float gam)
{
int i;
for(i=0; i<256; i++)
gamtab[i] = (unsigned short) (IMAX*pow(i/255.0,gam)+0.5);
for (i = 0; i < 256; i++)
gamtab[i] = (unsigned short)(IMAX * pow(i / 255.0, gam) + 0.5);
}
char* stuff[] = {
"usage: gif2tiff [options] input.gif output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
char *stuff[] = {
"usage: gif2tiff [options] input.gif output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal "
"differencing",
NULL};
static void
usage(void)
static void usage(void)
{
char buf[BUFSIZ];
int i;
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
#define COLSIZE 256
@@ -102,38 +100,37 @@ unsigned char *stackp;
unsigned int prefix[4096];
unsigned char suffix[4096];
unsigned char stack[4096];
int datasize,codesize,codemask; /* Decoder working variables */
int clear,eoi; /* Special code values */
int datasize, codesize, codemask; /* Decoder working variables */
int clear, eoi; /* Special code values */
int avail, oldcode;
FILE *infile;
int global; /* Is there a global color map? */
int globalbits; /* Number of bits of global colors */
unsigned char globalmap[COLSIZE][3];/* RGB values for global color map */
unsigned char *raster; /* Decoded image data */
int global; /* Is there a global color map? */
int globalbits; /* Number of bits of global colors */
unsigned char globalmap[COLSIZE][3]; /* RGB values for global color map */
unsigned char *raster; /* Decoded image data */
unsigned long width, height;
unsigned short red[COLSIZE];
unsigned short green[COLSIZE];
unsigned short blue[COLSIZE];
char *filename, *imagename;
static uint16_t compression = COMPRESSION_PACKBITS;
static uint16_t predictor = 0;
static uint32_t rowsperstrip = (uint32_t) -1;
static int processCompressOptions(char*);
static uint16_t compression = COMPRESSION_PACKBITS;
static uint16_t predictor = 0;
static uint32_t rowsperstrip = (uint32_t)-1;
static int processCompressOptions(char *);
int convert(void);
int checksignature(void);
int readscreen(void);
int readgifimage(char*);
int readextension(void);
int readraster(void);
int process(int, unsigned char**);
void initcolors(unsigned char [COLSIZE][3], int);
void rasterize(int, char*);
int convert(void);
int checksignature(void);
int readscreen(void);
int readgifimage(char *);
int readextension(void);
int readraster(void);
int process(int, unsigned char **);
void initcolors(unsigned char[COLSIZE][3], int);
void rasterize(int, char *);
int
main(int argc, char* argv[])
int main(int argc, char *argv[])
{
#if !HAVE_DECL_OPTARG
extern int optind;
@@ -143,105 +140,119 @@ main(int argc, char* argv[])
int c, status;
while ((c = getopt(argc, argv, "c:r:")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
switch (c)
{
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
usage();
makegamtab(GIFGAMMA);
filename = argv[optind];
imagename = argv[optind+1];
if ((infile = fopen(imagename, "rb")) != NULL) {
int c;
fclose(infile);
printf("overwrite %s? ", imagename); fflush(stdout);
c = getc(stdin);
if (c != 'y' && c != 'Y')
return (1);
imagename = argv[optind + 1];
if ((infile = fopen(imagename, "rb")) != NULL)
{
int c;
fclose(infile);
printf("overwrite %s? ", imagename);
fflush(stdout);
c = getc(stdin);
if (c != 'y' && c != 'Y')
return (1);
}
if ((infile = fopen(filename, "rb")) == NULL) {
perror(filename);
return (1);
if ((infile = fopen(filename, "rb")) == NULL)
{
perror(filename);
return (1);
}
status = convert();
fclose(infile);
return (status);
}
static int
processCompressOptions(char* opt)
static int processCompressOptions(char *opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_ADOBE_DEFLATE;
} else
return (0);
return (1);
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "lzw", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_LZW;
}
else if (strneq(opt, "zip", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_ADOBE_DEFLATE;
}
else
return (0);
return (1);
}
int
convert(void)
int convert(void)
{
int ch;
char* mode = "w";
char *mode = "w";
if (!checksignature())
return (-1);
if (!readscreen())
return (-1);
while ((ch = getc(infile)) != ';' && ch != EOF) {
switch (ch) {
case '\0': break; /* this kludge for non-standard files */
case ',': if (!readgifimage(mode))
return (-1);
mode = "a"; /* subsequent images append */
break;
case '!': if (!readextension())
return (-1);
break;
default: fprintf(stderr, "illegal GIF block type\n");
return (-1);
while ((ch = getc(infile)) != ';' && ch != EOF)
{
switch (ch)
{
case '\0':
break; /* this kludge for non-standard files */
case ',':
if (!readgifimage(mode))
return (-1);
mode = "a"; /* subsequent images append */
break;
case '!':
if (!readextension())
return (-1);
break;
default:
fprintf(stderr, "illegal GIF block type\n");
return (-1);
}
}
return (0);
}
int
checksignature(void)
int checksignature(void)
{
char buf[6];
if (fread(buf,1,6,infile) != 6) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
if (fread(buf, 1, 6, infile) != 6)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return 0;
}
if (strncmp(buf,"GIF",3)) {
if (strncmp(buf, "GIF", 3))
{
fprintf(stderr, "file is not a GIF file\n");
return 0;
}
if (strncmp(&buf[3],"87a",3)) {
if (strncmp(&buf[3], "87a", 3))
{
fprintf(stderr, "unknown GIF version number\n");
return 0;
}
@@ -249,35 +260,36 @@ checksignature(void)
}
/*
* readscreen -
* Get information which is global to all the images stored
* readscreen -
* Get information which is global to all the images stored
* in the file
*/
int
readscreen(void)
int readscreen(void)
{
unsigned char buf[7];
if (fread(buf,1,7,infile) != 7) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
if (fread(buf, 1, 7, infile) != 7)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return 0;
}
global = buf[4] & 0x80;
if (global) {
if (global)
{
globalbits = (buf[4] & 0x07) + 1;
if (fread(globalmap,3,((size_t)1)<<globalbits,infile) !=
((size_t)1)<<globalbits) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
if (fread(globalmap, 3, ((size_t)1) << globalbits, infile) !=
((size_t)1) << globalbits)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return 0;
}
}
return 1;
}
int
readgifimage(char* mode)
int readgifimage(char *mode)
{
unsigned char buf[9];
int local, interleaved;
@@ -286,50 +298,61 @@ readgifimage(char* mode)
int status;
size_t raster_size;
if (fread(buf, 1, 9, infile) != 9) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
return (0);
if (fread(buf, 1, 9, infile) != 9)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return (0);
}
width = (buf[4] + (buf[5] << 8)) & 0xffff; /* 16 bit */
height = (buf[6] + (buf[7] << 8)) & 0xffff; /* 16 bit */
width = (buf[4] + (buf[5] << 8)) & 0xffff; /* 16 bit */
height = (buf[6] + (buf[7] << 8)) & 0xffff; /* 16 bit */
local = buf[8] & 0x80;
interleaved = buf[8] & 0x40;
if (width == 0UL || height == 0UL || (width > 2000000000UL / height)) {
if (width == 0UL || height == 0UL || (width > 2000000000UL / height))
{
fprintf(stderr, "Invalid value of width or height\n");
return(0);
return (0);
}
if (local == 0 && global == 0) {
if (local == 0 && global == 0)
{
fprintf(stderr, "no colormap present for image\n");
return (0);
}
raster_size=width*height;
if ((raster_size/width) == height) {
raster_size += EXTRAFUDGE; /* Add elbow room */
} else {
raster_size=0;
raster_size = width * height;
if ((raster_size / width) == height)
{
raster_size += EXTRAFUDGE; /* Add elbow room */
}
if ((raster = (unsigned char*) _TIFFmalloc(raster_size)) == NULL) {
else
{
raster_size = 0;
}
if ((raster = (unsigned char *)_TIFFmalloc(raster_size)) == NULL)
{
fprintf(stderr, "not enough memory for image\n");
return (0);
}
if (local) {
if (local)
{
localbits = (buf[8] & 0x7) + 1;
fprintf(stderr, " local colors: %d\n", 1<<localbits);
fprintf(stderr, " local colors: %d\n", 1 << localbits);
if (fread(localmap, 3, ((size_t)1)<<localbits, infile) !=
((size_t)1)<<localbits) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
if (fread(localmap, 3, ((size_t)1) << localbits, infile) !=
((size_t)1) << localbits)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return (0);
}
initcolors(localmap, 1<<localbits);
} else if (global) {
initcolors(globalmap, 1<<globalbits);
initcolors(localmap, 1 << localbits);
}
else if (global)
{
initcolors(globalmap, 1 << globalbits);
}
if ((status = readraster()))
rasterize(interleaved, mode);
rasterize(interleaved, mode);
_TIFFfree(raster);
return status;
}
@@ -339,18 +362,18 @@ readgifimage(char* mode)
* Read a GIF extension block (and do nothing with it).
*
*/
int
readextension(void)
int readextension(void)
{
int count;
char buf[255];
int status = 1;
(void) getc(infile);
(void)getc(infile);
while ((count = getc(infile)) && count <= 255)
if (fread(buf, 1, count, infile) != (size_t) count) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
if (fread(buf, 1, count, infile) != (size_t)count)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
status = 0;
break;
}
@@ -362,114 +385,129 @@ readextension(void)
* Decode a raster image
*
*/
int
readraster(void)
int readraster(void)
{
unsigned char *fill = raster;
unsigned char buf[255];
register int bits=0;
register unsigned long datum=0;
register int bits = 0;
register unsigned long datum = 0;
register unsigned char *ch;
register int count, code;
int status = 1;
datasize = getc(infile);
if (datasize > 12)
return 0;
return 0;
clear = 1 << datasize;
eoi = clear + 1;
avail = clear + 2;
oldcode = -1;
codesize = datasize + 1;
codemask = (1 << codesize) - 1;
for (code = 0; code < clear; code++) {
prefix[code] = 0;
suffix[code] = code;
for (code = 0; code < clear; code++)
{
prefix[code] = 0;
suffix[code] = code;
}
stackp = stack;
for (count = getc(infile); count > 0 && count <= 255; count = getc(infile)) {
if (fread(buf,1,count,infile) != (size_t)count) {
fprintf(stderr, "short read from file %s (%s)\n",
filename, strerror(errno));
for (count = getc(infile); count > 0 && count <= 255; count = getc(infile))
{
if (fread(buf, 1, count, infile) != (size_t)count)
{
fprintf(stderr, "short read from file %s (%s)\n", filename,
strerror(errno));
return 0;
}
for (ch=buf; count-- > 0; ch++) {
datum += (unsigned long) *ch << bits;
bits += 8;
while (bits >= codesize) {
code = datum & codemask;
datum >>= codesize;
bits -= codesize;
if (code == eoi) { /* This kludge put in */
goto exitloop; /* because some GIF files*/
} /* aren't standard */
if (!process(code, &fill)) {
status = 0;
goto exitloop;
}
}
}
if (fill >= raster + width*height) {
fprintf(stderr, "raster full before eoi code\n");
break;
}
for (ch = buf; count-- > 0; ch++)
{
datum += (unsigned long)*ch << bits;
bits += 8;
while (bits >= codesize)
{
code = datum & codemask;
datum >>= codesize;
bits -= codesize;
if (code == eoi)
{ /* This kludge put in */
goto exitloop; /* because some GIF files*/
} /* aren't standard */
if (!process(code, &fill))
{
status = 0;
goto exitloop;
}
}
}
if (fill >= raster + width * height)
{
fprintf(stderr, "raster full before eoi code\n");
break;
}
}
exitloop:
if (fill != raster + width*height) {
fprintf(stderr, "warning: wrong rastersize: %ld bytes\n",
(long) (fill-raster));
fprintf(stderr, " instead of %ld bytes\n",
(long) width*height);
if (fill != raster + width * height)
{
fprintf(stderr, "warning: wrong rastersize: %ld bytes\n",
(long)(fill - raster));
fprintf(stderr, " instead of %ld bytes\n",
(long)width * height);
}
return status;
}
/*
* process -
* Process a compression code. "clear" resets the code table.
* Otherwise make a new code table entry, and output the bytes
* process -
* Process a compression code. "clear" resets the code table.
* Otherwise make a new code table entry, and output the bytes
* associated with the code.
*/
int
process(register int code, unsigned char** fill)
int process(register int code, unsigned char **fill)
{
int incode;
static unsigned char firstchar;
if (code == clear) {
codesize = datasize + 1;
codemask = (1 << codesize) - 1;
avail = clear + 2;
oldcode = -1;
return 1;
if (code == clear)
{
codesize = datasize + 1;
codemask = (1 << codesize) - 1;
avail = clear + 2;
oldcode = -1;
return 1;
}
if (oldcode == -1) {
if (code >= clear) {
fprintf(stderr, "bad input: code=%d is larger than clear=%d\n",code, clear);
if (oldcode == -1)
{
if (code >= clear)
{
fprintf(stderr, "bad input: code=%d is larger than clear=%d\n",
code, clear);
return 0;
}
if (*fill >= raster + width*height) {
if (*fill >= raster + width * height)
{
fprintf(stderr, "raster full before eoi code\n");
return 0;
}
*(*fill)++ = suffix[code];
firstchar = oldcode = code;
return 1;
*(*fill)++ = suffix[code];
firstchar = oldcode = code;
return 1;
}
if (code > avail) {
fprintf(stderr, "code %d too large for %d\n", code, avail);
return 0;
if (code > avail)
{
fprintf(stderr, "code %d too large for %d\n", code, avail);
return 0;
}
incode = code;
if (code == avail) { /* the first code is always < avail */
*stackp++ = firstchar;
code = oldcode;
if (code == avail)
{ /* the first code is always < avail */
*stackp++ = firstchar;
code = oldcode;
}
while (code > clear) {
*stackp++ = suffix[code];
code = prefix[code];
while (code > clear)
{
*stackp++ = suffix[code];
code = prefix[code];
}
*stackp++ = firstchar = suffix[code];
@@ -477,17 +515,20 @@ process(register int code, unsigned char** fill)
suffix[avail] = firstchar;
avail++;
if (((avail & codemask) == 0) && (avail < 4096)) {
codesize++;
codemask += avail;
if (((avail & codemask) == 0) && (avail < 4096))
{
codesize++;
codemask += avail;
}
oldcode = incode;
do {
if (*fill >= raster + width*height) {
do
{
if (*fill >= raster + width * height)
{
fprintf(stderr, "raster full before eoi code\n");
return 0;
}
*(*fill)++ = *--stackp;
*(*fill)++ = *--stackp;
} while (stackp > stack);
return 1;
}
@@ -495,23 +536,22 @@ process(register int code, unsigned char** fill)
/*
* initcolors -
* Convert a color map (local or global) to arrays with R, G and B
* values.
* values.
*
*/
void
initcolors(unsigned char colormap[COLSIZE][3], int ncolors)
void initcolors(unsigned char colormap[COLSIZE][3], int ncolors)
{
register int i;
for (i = 0; i < ncolors; i++) {
red[i] = gamtab[colormap[i][0]];
for (i = 0; i < ncolors; i++)
{
red[i] = gamtab[colormap[i][0]];
green[i] = gamtab[colormap[i][1]];
blue[i] = gamtab[colormap[i][2]];
blue[i] = gamtab[colormap[i][2]];
}
}
void
rasterize(int interleaved, char* mode)
void rasterize(int interleaved, char *mode)
{
register unsigned long row;
unsigned char *newras;
@@ -520,60 +560,71 @@ rasterize(int interleaved, char* mode)
tstrip_t strip;
tsize_t stripsize;
if ((newras = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) {
if ((newras = (unsigned char *)_TIFFmalloc(width * height + EXTRAFUDGE)) ==
NULL)
{
fprintf(stderr, "not enough memory for image\n");
return;
}
#define DRAWSEGMENT(offset, step) { \
for (row = offset; row < height; row += step) { \
_TIFFmemcpy(newras + row*width, ras, width);\
ras += width; \
} \
#define DRAWSEGMENT(offset, step) \
{ \
for (row = offset; row < height; row += step) \
{ \
_TIFFmemcpy(newras + row * width, ras, width); \
ras += width; \
} \
}
ras = raster;
if (interleaved) {
if (interleaved)
{
DRAWSEGMENT(0, 8);
DRAWSEGMENT(4, 8);
DRAWSEGMENT(2, 4);
DRAWSEGMENT(1, 2);
} else
}
else
DRAWSEGMENT(0, 1);
#undef DRAWSEGMENT
tif = TIFFOpen(imagename, mode);
if (!tif) {
TIFFError(imagename,"Can not open output image");
exit(-1);
if (!tif)
{
TIFFError(imagename, "Can not open output image");
exit(-1);
}
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32_t) width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32_t) height);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32_t)width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32_t)height);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip));
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip));
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
break;
switch (compression)
{
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
strip = 0;
stripsize = TIFFStripSize(tif);
for (row=0; row<height; row += rowsperstrip) {
if (rowsperstrip > height-row) {
rowsperstrip = height-row;
stripsize = TIFFVStripSize(tif, rowsperstrip);
}
if (TIFFWriteEncodedStrip(tif, strip, newras+row*width, stripsize) < 0)
break;
strip++;
for (row = 0; row < height; row += rowsperstrip)
{
if (rowsperstrip > height - row)
{
rowsperstrip = height - row;
stripsize = TIFFVStripSize(tif, rowsperstrip);
}
if (TIFFWriteEncodedStrip(tif, strip, newras + row * width, stripsize) <
0)
break;
strip++;
}
TIFFClose(tif);

View File

@@ -2,335 +2,366 @@
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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
* 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 "tif_config.h"
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#include "libport.h"
#endif
#include "rasterfile.h"
#include "tiffio.h"
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#define howmany(x, y) (((x) + ((y)-1)) / (y))
#endif
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
static uint16_t compression = (uint16_t) -1;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static uint16_t predictor = 0;
static uint16_t compression = (uint16_t)-1;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static uint16_t predictor = 0;
static void usage(void);
static int processCompressOptions(char*);
static int processCompressOptions(char *);
int
main(int argc, char* argv[])
int main(int argc, char *argv[])
{
unsigned char* buf;
long row;
tsize_t linebytes, scanline;
TIFF *out;
FILE *in;
struct rasterfile h;
uint16_t photometric;
uint16_t config = PLANARCONFIG_CONTIG;
uint32_t rowsperstrip = (uint32_t) -1;
int c;
unsigned char *buf;
long row;
tsize_t linebytes, scanline;
TIFF *out;
FILE *in;
struct rasterfile h;
uint16_t photometric;
uint16_t config = PLANARCONFIG_CONTIG;
uint32_t rowsperstrip = (uint32_t)-1;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:r:h")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 'h':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = fopen(argv[optind], "rb");
if (in == NULL) {
fprintf(stderr, "%s: Can not open.\n", argv[optind]);
return (-1);
}
if (fread(&h, sizeof (h), 1, in) != 1) {
fprintf(stderr, "%s: Can not read header.\n", argv[optind]);
fclose(in);
return (-2);
}
if (strcmp(h.ras_magic, RAS_MAGIC) == 0) {
while ((c = getopt(argc, argv, "c:r:h")) != -1)
switch (c)
{
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 'h':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = fopen(argv[optind], "rb");
if (in == NULL)
{
fprintf(stderr, "%s: Can not open.\n", argv[optind]);
return (-1);
}
if (fread(&h, sizeof(h), 1, in) != 1)
{
fprintf(stderr, "%s: Can not read header.\n", argv[optind]);
fclose(in);
return (-2);
}
if (strcmp(h.ras_magic, RAS_MAGIC) == 0)
{
#ifndef WORDS_BIGENDIAN
TIFFSwabLong((uint32_t *)&h.ras_width);
TIFFSwabLong((uint32_t *)&h.ras_height);
TIFFSwabLong((uint32_t *)&h.ras_depth);
TIFFSwabLong((uint32_t *)&h.ras_length);
TIFFSwabLong((uint32_t *)&h.ras_type);
TIFFSwabLong((uint32_t *)&h.ras_maptype);
TIFFSwabLong((uint32_t *)&h.ras_maplength);
TIFFSwabLong((uint32_t *)&h.ras_width);
TIFFSwabLong((uint32_t *)&h.ras_height);
TIFFSwabLong((uint32_t *)&h.ras_depth);
TIFFSwabLong((uint32_t *)&h.ras_length);
TIFFSwabLong((uint32_t *)&h.ras_type);
TIFFSwabLong((uint32_t *)&h.ras_maptype);
TIFFSwabLong((uint32_t *)&h.ras_maplength);
#endif
} else if (strcmp(h.ras_magic, RAS_MAGIC_INV) == 0) {
}
else if (strcmp(h.ras_magic, RAS_MAGIC_INV) == 0)
{
#ifdef WORDS_BIGENDIAN
TIFFSwabLong((uint32_t *)&h.ras_width);
TIFFSwabLong((uint32_t *)&h.ras_height);
TIFFSwabLong((uint32_t *)&h.ras_depth);
TIFFSwabLong((uint32_t *)&h.ras_length);
TIFFSwabLong((uint32_t *)&h.ras_type);
TIFFSwabLong((uint32_t *)&h.ras_maptype);
TIFFSwabLong((uint32_t *)&h.ras_maplength);
TIFFSwabLong((uint32_t *)&h.ras_width);
TIFFSwabLong((uint32_t *)&h.ras_height);
TIFFSwabLong((uint32_t *)&h.ras_depth);
TIFFSwabLong((uint32_t *)&h.ras_length);
TIFFSwabLong((uint32_t *)&h.ras_type);
TIFFSwabLong((uint32_t *)&h.ras_maptype);
TIFFSwabLong((uint32_t *)&h.ras_maplength);
#endif
} else {
fprintf(stderr, "%s: Not a rasterfile.\n", argv[optind]);
fclose(in);
return (-3);
}
if ((h.ras_width <= 0) || (h.ras_width >= INT_MAX) ||
(h.ras_height <= 0) || (h.ras_height >= INT_MAX) ||
(h.ras_depth <= 0) || (h.ras_depth >= INT_MAX) ||
(h.ras_length <= 0) || (h.ras_length >= INT_MAX) ||
(h.ras_type <= 0) ||
(h.ras_maptype <= 0) ||
(h.ras_maplength <= 0) || (h.ras_maplength >= INT_MAX)) {
fprintf(stderr, "%s: Improper image header.\n", argv[optind]);
fclose(in);
return (-2);
}
else
{
fprintf(stderr, "%s: Not a rasterfile.\n", argv[optind]);
fclose(in);
return (-3);
}
if ((h.ras_width <= 0) || (h.ras_width >= INT_MAX) || (h.ras_height <= 0) ||
(h.ras_height >= INT_MAX) || (h.ras_depth <= 0) ||
(h.ras_depth >= INT_MAX) || (h.ras_length <= 0) ||
(h.ras_length >= INT_MAX) || (h.ras_type <= 0) ||
(h.ras_maptype <= 0) || (h.ras_maplength <= 0) ||
(h.ras_maplength >= INT_MAX))
{
fprintf(stderr, "%s: Improper image header.\n", argv[optind]);
fclose(in);
return (-2);
}
if ((h.ras_depth != 1) && (h.ras_depth != 8) && (h.ras_depth != 24))
{
fprintf(stderr, "%s: Improper image depth (%d).\n", argv[optind],
h.ras_depth);
fclose(in);
return (-2);
}
out = TIFFOpen(argv[optind + 1], "w");
if (out == NULL)
{
fclose(in);
return (-4);
}
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32_t)h.ras_width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32_t)h.ras_height);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, h.ras_depth > 8 ? 3 : 1);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, h.ras_depth > 1 ? 8 : 1);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
if (h.ras_maptype != RMT_NONE)
{
uint16_t *red;
register uint16_t *map;
register int i, j;
int mapsize;
buf = (unsigned char *)_TIFFmalloc(h.ras_maplength);
if (buf == NULL)
{
fprintf(stderr, "No space to read in colormap.\n");
fclose(in);
(void)TIFFClose(out);
return (-5);
}
if ((h.ras_depth != 1) &&
(h.ras_depth != 8) &&
(h.ras_depth != 24)) {
fprintf(stderr, "%s: Improper image depth (%d).\n",
argv[optind], h.ras_depth);
fclose(in);
return (-2);
if (fread(buf, h.ras_maplength, 1, in) != 1)
{
fprintf(stderr, "%s: Read error on colormap.\n", argv[optind]);
fclose(in);
(void)TIFFClose(out);
return (-6);
}
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
{
fclose(in);
return (-4);
}
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32_t) h.ras_width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32_t) h.ras_height);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, h.ras_depth > 8 ? 3 : 1);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, h.ras_depth > 1 ? 8 : 1);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
if (h.ras_maptype != RMT_NONE) {
uint16_t* red;
register uint16_t* map;
register int i, j;
int mapsize;
buf = (unsigned char *)_TIFFmalloc(h.ras_maplength);
if (buf == NULL) {
fprintf(stderr, "No space to read in colormap.\n");
fclose(in);
(void) TIFFClose(out);
return (-5);
}
if (fread(buf, h.ras_maplength, 1, in) != 1) {
fprintf(stderr, "%s: Read error on colormap.\n",
argv[optind]);
fclose(in);
(void) TIFFClose(out);
return (-6);
}
mapsize = 1<<h.ras_depth;
if (h.ras_maplength > mapsize*3) {
fprintf(stderr,
"%s: Huh, %d colormap entries, should be %d?\n",
argv[optind], h.ras_maplength, mapsize*3);
fclose(in);
(void) TIFFClose(out);
return (-7);
}
red = (uint16_t*)_TIFFmalloc(mapsize * 3 * sizeof (uint16_t));
if (red == NULL) {
fprintf(stderr, "No space for colormap.\n");
fclose(in);
(void) TIFFClose(out);
return (-8);
}
map = red;
for (j = 0; j < 3; j++) {
#define SCALE(x) (((x)*((1L<<16)-1))/255)
for (i = h.ras_maplength/3; i-- > 0;)
*map++ = SCALE(*buf++);
if ((i = h.ras_maplength/3) < mapsize) {
i = mapsize - i;
_TIFFmemset(map, 0, i*sizeof (uint16_t));
map += i;
}
}
TIFFSetField(out, TIFFTAG_COLORMAP,
red, red + mapsize, red + 2*mapsize);
photometric = PHOTOMETRIC_PALETTE;
if (compression == (uint16_t) -1)
compression = COMPRESSION_PACKBITS;
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
} else {
/* XXX this is bogus... */
photometric = h.ras_depth == 24 ?
PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
if (compression == (uint16_t) -1)
compression = COMPRESSION_LZW;
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
}
switch (compression) {
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
linebytes = ((h.ras_depth*h.ras_width+15) >> 3) &~ 1;
scanline = TIFFScanlineSize(out);
if (scanline > linebytes) {
buf = (unsigned char *)_TIFFmalloc(scanline);
_TIFFmemset(buf+linebytes, 0, scanline-linebytes);
} else
buf = (unsigned char *)_TIFFmalloc(linebytes);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
for (row = 0; row < h.ras_height; row++) {
if (fread(buf, linebytes, 1, in) != 1) {
fprintf(stderr, "%s: scanline %ld: Read error.\n",
argv[optind], row);
break;
}
if (h.ras_type == RT_STANDARD && h.ras_depth == 24) {
tsize_t cc = h.ras_width;
unsigned char* cp = buf;
#define SWAP(a,b) { unsigned char t = (a); (a) = (b); (b) = t; }
do {
SWAP(cp[0], cp[2]);
cp += 3;
} while (--cc);
}
if (TIFFWriteScanline(out, buf, row, 0) < 0)
break;
}
(void) TIFFClose(out);
fclose(in);
return (0);
mapsize = 1 << h.ras_depth;
if (h.ras_maplength > mapsize * 3)
{
fprintf(stderr, "%s: Huh, %d colormap entries, should be %d?\n",
argv[optind], h.ras_maplength, mapsize * 3);
fclose(in);
(void)TIFFClose(out);
return (-7);
}
red = (uint16_t *)_TIFFmalloc(mapsize * 3 * sizeof(uint16_t));
if (red == NULL)
{
fprintf(stderr, "No space for colormap.\n");
fclose(in);
(void)TIFFClose(out);
return (-8);
}
map = red;
for (j = 0; j < 3; j++)
{
#define SCALE(x) (((x) * ((1L << 16) - 1)) / 255)
for (i = h.ras_maplength / 3; i-- > 0;)
*map++ = SCALE(*buf++);
if ((i = h.ras_maplength / 3) < mapsize)
{
i = mapsize - i;
_TIFFmemset(map, 0, i * sizeof(uint16_t));
map += i;
}
}
TIFFSetField(out, TIFFTAG_COLORMAP, red, red + mapsize,
red + 2 * mapsize);
photometric = PHOTOMETRIC_PALETTE;
if (compression == (uint16_t)-1)
compression = COMPRESSION_PACKBITS;
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
}
else
{
/* XXX this is bogus... */
photometric =
h.ras_depth == 24 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
if (compression == (uint16_t)-1)
compression = COMPRESSION_LZW;
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
}
switch (compression)
{
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB &&
jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
linebytes = ((h.ras_depth * h.ras_width + 15) >> 3) & ~1;
scanline = TIFFScanlineSize(out);
if (scanline > linebytes)
{
buf = (unsigned char *)_TIFFmalloc(scanline);
_TIFFmemset(buf + linebytes, 0, scanline - linebytes);
}
else
buf = (unsigned char *)_TIFFmalloc(linebytes);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
for (row = 0; row < h.ras_height; row++)
{
if (fread(buf, linebytes, 1, in) != 1)
{
fprintf(stderr, "%s: scanline %ld: Read error.\n", argv[optind],
row);
break;
}
if (h.ras_type == RT_STANDARD && h.ras_depth == 24)
{
tsize_t cc = h.ras_width;
unsigned char *cp = buf;
#define SWAP(a, b) \
{ \
unsigned char t = (a); \
(a) = (b); \
(b) = t; \
}
do
{
SWAP(cp[0], cp[2]);
cp += 3;
} while (--cc);
}
if (TIFFWriteScanline(out, buf, row, 0) < 0)
break;
}
(void)TIFFClose(out);
fclose(in);
return (0);
}
static int
processCompressOptions(char* opt)
static int processCompressOptions(char *opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4)) {
char* cp = strchr(opt, ':');
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4))
{
char *cp = strchr(opt, ':');
compression = COMPRESSION_JPEG;
while( cp )
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
compression = COMPRESSION_JPEG;
while (cp)
{
if (isdigit((int)cp[1]))
quality = atoi(cp + 1);
else if (cp[1] == 'r')
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_ADOBE_DEFLATE;
} else
return (0);
return (1);
cp = strchr(cp + 1, ':');
}
}
else if (strneq(opt, "lzw", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_LZW;
}
else if (strneq(opt, "zip", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_ADOBE_DEFLATE;
}
else
return (0);
return (1);
}
char* stuff[] = {
"usage: ras2tiff [options] input.ras output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c jpeg[:opts] compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
" -h this help message",
NULL
};
char *stuff[] = {
"usage: ras2tiff [options] input.ras output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c jpeg[:opts] compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. "
"quality",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal "
"differencing",
" -h this help message",
NULL};
static void
usage(void)
static void usage(void)
{
char buf[BUFSIZ];
int i;
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}

View File

@@ -3,31 +3,32 @@
/*
* Description of header for files containing raster images
*/
struct rasterfile {
char ras_magic[4]; /* magic number */
int32_t ras_width; /* width (pixels) of image */
int32_t ras_height; /* height (pixels) of image */
int32_t ras_depth; /* depth (1, 8, or 24 bits) of pixel */
int32_t ras_length; /* length (bytes) of image */
int32_t ras_type; /* type of file; see RT_* below */
int32_t ras_maptype; /* type of colormap; see RMT_* below */
int32_t ras_maplength; /* length (bytes) of following map */
/* color map follows for ras_maplength bytes, followed by image */
struct rasterfile
{
char ras_magic[4]; /* magic number */
int32_t ras_width; /* width (pixels) of image */
int32_t ras_height; /* height (pixels) of image */
int32_t ras_depth; /* depth (1, 8, or 24 bits) of pixel */
int32_t ras_length; /* length (bytes) of image */
int32_t ras_type; /* type of file; see RT_* below */
int32_t ras_maptype; /* type of colormap; see RMT_* below */
int32_t ras_maplength; /* length (bytes) of following map */
/* color map follows for ras_maplength bytes, followed by image */
};
#define RAS_MAGIC "\x59\xa6\x6a\x95"
#define RAS_MAGIC_INV "\x95\x6a\xa6\x59"
#define RAS_MAGIC "\x59\xa6\x6a\x95"
#define RAS_MAGIC_INV "\x95\x6a\xa6\x59"
/* Sun supported ras_type's */
#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */
#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */
#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */
/* Sun supported ras_type's */
#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */
#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */
#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */
/* Sun registered ras_maptype's */
#define RMT_RAW 2
/* Sun supported ras_maptype's */
#define RMT_NONE 0 /* ras_maplength is expected to be 0 */
#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
/* Sun registered ras_maptype's */
#define RMT_RAW 2
/* Sun supported ras_maptype's */
#define RMT_NONE 0 /* ras_maplength is expected to be 0 */
#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
/*
* NOTES:

View File

@@ -2,328 +2,345 @@
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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
* 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 <ctype.h>
#include <gl/image.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gl/image.h>
#include <ctype.h>
#include "tiffio.h"
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
static short config = PLANARCONFIG_CONTIG;
static uint16_t compression = COMPRESSION_PACKBITS;
static uint16_t predictor = 0;
static uint16_t fillorder = 0;
static uint32_t rowsperstrip = (uint32_t) -1;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static uint16_t photometric;
static short config = PLANARCONFIG_CONTIG;
static uint16_t compression = COMPRESSION_PACKBITS;
static uint16_t predictor = 0;
static uint16_t fillorder = 0;
static uint32_t rowsperstrip = (uint32_t)-1;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static uint16_t photometric;
static void usage(void);
static int cpContig(IMAGE*, TIFF*);
static int cpSeparate(IMAGE*, TIFF*);
static int processCompressOptions(char*);
static void usage(void);
static int cpContig(IMAGE *, TIFF *);
static int cpSeparate(IMAGE *, TIFF *);
static int processCompressOptions(char *);
/* XXX image library has no prototypes */
extern IMAGE* iopen(const char*, const char*);
extern void iclose(IMAGE*);
extern void getrow(IMAGE*, short*, int, int);
extern IMAGE *iopen(const char *, const char *);
extern void iclose(IMAGE *);
extern void getrow(IMAGE *, short *, int, int);
int
main(int argc, char* argv[])
int main(int argc, char *argv[])
{
IMAGE *in;
TIFF *out;
int c;
IMAGE *in;
TIFF *out;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:p:r:")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'f': /* fill order */
if (streq(optarg, "lsb2msb"))
fillorder = FILLORDER_LSB2MSB;
else if (streq(optarg, "msb2lsb"))
fillorder = FILLORDER_MSB2LSB;
else
usage();
break;
case 'p': /* planar configuration */
if (streq(optarg, "separate"))
config = PLANARCONFIG_SEPARATE;
else if (streq(optarg, "contig"))
config = PLANARCONFIG_CONTIG;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = iopen(argv[optind], "r");
if (in == NULL)
return (-1);
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
return (-2);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32_t) in->xsize);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32_t) in->ysize);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
if (in->zsize == 1)
photometric = PHOTOMETRIC_MINISBLACK;
else
photometric = PHOTOMETRIC_RGB;
switch (compression) {
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
if (fillorder != 0)
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize);
if (in->zsize > 3) {
uint16_t v[1];
v[0] = EXTRASAMPLE_UNASSALPHA;
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
}
TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16_t) in->min);
TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16_t) in->max);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
if (config != PLANARCONFIG_SEPARATE)
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
else /* force 1 row/strip for library limitation */
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L);
if (in->name[0] != '\0')
TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name);
if (config == PLANARCONFIG_CONTIG)
cpContig(in, out);
else
cpSeparate(in, out);
(void) iclose(in);
(void) TIFFClose(out);
return (0);
while ((c = getopt(argc, argv, "c:p:r:")) != -1)
switch (c)
{
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'f': /* fill order */
if (streq(optarg, "lsb2msb"))
fillorder = FILLORDER_LSB2MSB;
else if (streq(optarg, "msb2lsb"))
fillorder = FILLORDER_MSB2LSB;
else
usage();
break;
case 'p': /* planar configuration */
if (streq(optarg, "separate"))
config = PLANARCONFIG_SEPARATE;
else if (streq(optarg, "contig"))
config = PLANARCONFIG_CONTIG;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = iopen(argv[optind], "r");
if (in == NULL)
return (-1);
out = TIFFOpen(argv[optind + 1], "w");
if (out == NULL)
return (-2);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32_t)in->xsize);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32_t)in->ysize);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
if (in->zsize == 1)
photometric = PHOTOMETRIC_MINISBLACK;
else
photometric = PHOTOMETRIC_RGB;
switch (compression)
{
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB &&
jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_ADOBE_DEFLATE:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
if (fillorder != 0)
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize);
if (in->zsize > 3)
{
uint16_t v[1];
v[0] = EXTRASAMPLE_UNASSALPHA;
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
}
TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16_t)in->min);
TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16_t)in->max);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
if (config != PLANARCONFIG_SEPARATE)
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
else /* force 1 row/strip for library limitation */
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L);
if (in->name[0] != '\0')
TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name);
if (config == PLANARCONFIG_CONTIG)
cpContig(in, out);
else
cpSeparate(in, out);
(void)iclose(in);
(void)TIFFClose(out);
return (0);
}
static int
processCompressOptions(char* opt)
static int processCompressOptions(char *opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4)) {
char* cp = strchr(opt, ':');
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4))
{
char *cp = strchr(opt, ':');
defcompression = COMPRESSION_JPEG;
while( cp )
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
defcompression = COMPRESSION_JPEG;
while (cp)
{
if (isdigit((int)cp[1]))
quality = atoi(cp + 1);
else if (cp[1] == 'r')
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_ADOBE_DEFLATE;
} else
return (0);
return (1);
cp = strchr(cp + 1, ':');
}
}
else if (strneq(opt, "lzw", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_LZW;
}
else if (strneq(opt, "zip", 3))
{
char *cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_ADOBE_DEFLATE;
}
else
return (0);
return (1);
}
static int
cpContig(IMAGE* in, TIFF* out)
static int cpContig(IMAGE *in, TIFF *out)
{
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
short *r = NULL;
int x, y;
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
short *r = NULL;
int x, y;
if (in->zsize == 3) {
short *g, *b;
if (in->zsize == 3)
{
short *g, *b;
r = (short *)_TIFFmalloc(3 * in->xsize * sizeof (short));
g = r + in->xsize;
b = g + in->xsize;
for (y = in->ysize-1; y >= 0; y--) {
uint8_t* pp = (uint8_t*) buf;
r = (short *)_TIFFmalloc(3 * in->xsize * sizeof(short));
g = r + in->xsize;
b = g + in->xsize;
for (y = in->ysize - 1; y >= 0; y--)
{
uint8_t *pp = (uint8_t *)buf;
getrow(in, r, y, 0);
getrow(in, g, y, 1);
getrow(in, b, y, 2);
for (x = 0; x < in->xsize; x++) {
pp[0] = r[x];
pp[1] = g[x];
pp[2] = b[x];
pp += 3;
}
if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
goto bad;
}
} else if (in->zsize == 4) {
short *g, *b, *a;
getrow(in, r, y, 0);
getrow(in, g, y, 1);
getrow(in, b, y, 2);
for (x = 0; x < in->xsize; x++)
{
pp[0] = r[x];
pp[1] = g[x];
pp[2] = b[x];
pp += 3;
}
if (TIFFWriteScanline(out, buf, in->ysize - y - 1, 0) < 0)
goto bad;
}
}
else if (in->zsize == 4)
{
short *g, *b, *a;
r = (short *)_TIFFmalloc(4 * in->xsize * sizeof (short));
g = r + in->xsize;
b = g + in->xsize;
a = b + in->xsize;
for (y = in->ysize-1; y >= 0; y--) {
uint8_t* pp = (uint8_t*) buf;
r = (short *)_TIFFmalloc(4 * in->xsize * sizeof(short));
g = r + in->xsize;
b = g + in->xsize;
a = b + in->xsize;
for (y = in->ysize - 1; y >= 0; y--)
{
uint8_t *pp = (uint8_t *)buf;
getrow(in, r, y, 0);
getrow(in, g, y, 1);
getrow(in, b, y, 2);
getrow(in, a, y, 3);
for (x = 0; x < in->xsize; x++) {
pp[0] = r[x];
pp[1] = g[x];
pp[2] = b[x];
pp[3] = a[x];
pp += 4;
}
if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
goto bad;
}
} else {
uint8_t* pp = (uint8_t*) buf;
getrow(in, r, y, 0);
getrow(in, g, y, 1);
getrow(in, b, y, 2);
getrow(in, a, y, 3);
for (x = 0; x < in->xsize; x++)
{
pp[0] = r[x];
pp[1] = g[x];
pp[2] = b[x];
pp[3] = a[x];
pp += 4;
}
if (TIFFWriteScanline(out, buf, in->ysize - y - 1, 0) < 0)
goto bad;
}
}
else
{
uint8_t *pp = (uint8_t *)buf;
r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
for (y = in->ysize-1; y >= 0; y--) {
getrow(in, r, y, 0);
for (x = in->xsize-1; x >= 0; x--)
pp[x] = r[x];
if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
goto bad;
}
}
if (r)
_TIFFfree(r);
_TIFFfree(buf);
return (1);
r = (short *)_TIFFmalloc(in->xsize * sizeof(short));
for (y = in->ysize - 1; y >= 0; y--)
{
getrow(in, r, y, 0);
for (x = in->xsize - 1; x >= 0; x--)
pp[x] = r[x];
if (TIFFWriteScanline(out, buf, in->ysize - y - 1, 0) < 0)
goto bad;
}
}
if (r)
_TIFFfree(r);
_TIFFfree(buf);
return (1);
bad:
if (r)
_TIFFfree(r);
_TIFFfree(buf);
return (0);
if (r)
_TIFFfree(r);
_TIFFfree(buf);
return (0);
}
static int
cpSeparate(IMAGE* in, TIFF* out)
static int cpSeparate(IMAGE *in, TIFF *out)
{
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
short *r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
uint8_t* pp = (uint8_t*) buf;
int x, y, z;
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
short *r = (short *)_TIFFmalloc(in->xsize * sizeof(short));
uint8_t *pp = (uint8_t *)buf;
int x, y, z;
for (z = 0; z < in->zsize; z++) {
for (y = in->ysize-1; y >= 0; y--) {
getrow(in, r, y, z);
for (x = 0; x < in->xsize; x++)
pp[x] = r[x];
if (TIFFWriteScanline(out, buf, in->ysize-y-1, z) < 0)
goto bad;
}
}
_TIFFfree(r);
_TIFFfree(buf);
return (1);
for (z = 0; z < in->zsize; z++)
{
for (y = in->ysize - 1; y >= 0; y--)
{
getrow(in, r, y, z);
for (x = 0; x < in->xsize; x++)
pp[x] = r[x];
if (TIFFWriteScanline(out, buf, in->ysize - y - 1, z) < 0)
goto bad;
}
}
_TIFFfree(r);
_TIFFfree(buf);
return (1);
bad:
_TIFFfree(r);
_TIFFfree(buf);
return (0);
_TIFFfree(r);
_TIFFfree(buf);
return (0);
}
char* stuff[] = {
"usage: sgi2tiff [options] input.rgb output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -p contig pack samples contiguously (e.g. RGBRGB...)",
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
"",
" -f lsb2msb force lsb-to-msb FillOrder for output",
" -f msb2lsb force msb-to-lsb FillOrder for output",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c jpeg[:opts]compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
char *stuff[] = {
"usage: sgi2tiff [options] input.rgb output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",
" -p contig pack samples contiguously (e.g. RGBRGB...)",
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
"",
" -f lsb2msb force lsb-to-msb FillOrder for output",
" -f msb2lsb force msb-to-lsb FillOrder for output",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c jpeg[:opts]compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal "
"differencing",
NULL};
static void
usage(void)
static void usage(void)
{
char buf[BUFSIZ];
int i;
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
setbuf(stderr, buf);
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}

View File

@@ -2,23 +2,23 @@
* Copyright (c) 1990-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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
* 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.
*/
@@ -26,284 +26,297 @@
#include <stdlib.h>
#include <string.h>
#include <gl.h>
#include <ctype.h>
#include <gl.h>
#include "tiffio.h"
typedef unsigned char unsigned char;
typedef unsigned long uint32_t;
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
uint32_t rowsperstrip = (uint32_t) -1;
uint16_t compression = COMPRESSION_PACKBITS;
uint16_t config = PLANARCONFIG_CONTIG;
uint16_t predictor = 0;
int xmaxscreen;
int ymaxscreen;
uint16_t photometric = PHOTOMETRIC_RGB;
int jpegcolormode = JPEGCOLORMODE_RGB;
int quality = 75; /* JPEG quality */
uint32_t rowsperstrip = (uint32_t)-1;
uint16_t compression = COMPRESSION_PACKBITS;
uint16_t config = PLANARCONFIG_CONTIG;
uint16_t predictor = 0;
int xmaxscreen;
int ymaxscreen;
uint16_t photometric = PHOTOMETRIC_RGB;
int jpegcolormode = JPEGCOLORMODE_RGB;
int quality = 75; /* JPEG quality */
static void usage(void);
static void tiffsv(char*, int, int, int, int);
static void usage(void);
static void tiffsv(char *, int, int, int, int);
int
main(int argc, char* argv[])
int main(int argc, char *argv[])
{
int c;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:p:r:")) != -1)
switch (c) {
case 'b': /* save as b&w */
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 'c': /* compression scheme */
if (streq(optarg, "none"))
compression = COMPRESSION_NONE;
else if (streq(optarg, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(optarg, "jpeg", 4)) {
char* cp = strchr(optarg, ':');
if (cp && isdigit(cp[1]))
quality = atoi(cp+1);
if (cp && strchr(cp, 'r'))
jpegcolormode = JPEGCOLORMODE_RAW;
compression = COMPRESSION_JPEG;
} else if (strneq(optarg, "lzw", 3)) {
char* cp = strchr(optarg, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else
usage();
break;
case 'p': /* planar configuration */
if (streq(optarg, "separate"))
config = PLANARCONFIG_SEPARATE;
else if (streq(optarg, "contig"))
config = PLANARCONFIG_CONTIG;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 1 && argc - optind != 5)
usage();
xmaxscreen = getgdesc(GD_XPMAX)-1;
ymaxscreen = getgdesc(GD_YPMAX)-1;
foreground();
noport();
winopen("tiffsv");
if (argc - optind == 5)
tiffsv(argv[optind],
atoi(argv[optind+1]), atoi(argv[optind+2]),
atoi(argv[optind+3]), atoi(argv[optind+4]));
else
tiffsv(argv[optind], 0, xmaxscreen, 0, ymaxscreen);
return (0);
while ((c = getopt(argc, argv, "c:p:r:")) != -1)
switch (c)
{
case 'b': /* save as b&w */
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 'c': /* compression scheme */
if (streq(optarg, "none"))
compression = COMPRESSION_NONE;
else if (streq(optarg, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(optarg, "jpeg", 4))
{
char *cp = strchr(optarg, ':');
if (cp && isdigit(cp[1]))
quality = atoi(cp + 1);
if (cp && strchr(cp, 'r'))
jpegcolormode = JPEGCOLORMODE_RAW;
compression = COMPRESSION_JPEG;
}
else if (strneq(optarg, "lzw", 3))
{
char *cp = strchr(optarg, ':');
if (cp)
predictor = atoi(cp + 1);
compression = COMPRESSION_LZW;
}
else
usage();
break;
case 'p': /* planar configuration */
if (streq(optarg, "separate"))
config = PLANARCONFIG_SEPARATE;
else if (streq(optarg, "contig"))
config = PLANARCONFIG_CONTIG;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 1 && argc - optind != 5)
usage();
xmaxscreen = getgdesc(GD_XPMAX) - 1;
ymaxscreen = getgdesc(GD_YPMAX) - 1;
foreground();
noport();
winopen("tiffsv");
if (argc - optind == 5)
tiffsv(argv[optind], atoi(argv[optind + 1]), atoi(argv[optind + 2]),
atoi(argv[optind + 3]), atoi(argv[optind + 4]));
else
tiffsv(argv[optind], 0, xmaxscreen, 0, ymaxscreen);
return (0);
}
char* stuff[] = {
"usage: tiffsv [options] outimage.tif [x1 x2 y1 y2] [-b]",
"where options are:",
" -p contig pack samples contiguously (e.g. RGBRGB...)",
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
"",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c jpeg[:opts]compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"",
"LZW options:",
" # set predictor value for Lempel-Ziv & Welch encoding",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
char *stuff[] = {
"usage: tiffsv [options] outimage.tif [x1 x2 y1 y2] [-b]",
"where options are:",
" -p contig pack samples contiguously (e.g. RGBRGB...)",
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
"",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c jpeg[:opts]compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"",
"LZW options:",
" # set predictor value for Lempel-Ziv & Welch encoding",
"For example, -c lzw:2 to get LZW-encoded data with horizontal "
"differencing",
NULL};
static void
usage(void)
static void usage(void)
{
char buf[BUFSIZ];
int i;
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
setbuf(stderr, buf);
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
static void
svRGBSeparate(TIFF* tif, uint32_t* ss, int xsize, int ysize)
static void svRGBSeparate(TIFF *tif, uint32_t *ss, int xsize, int ysize)
{
tsize_t stripsize = TIFFStripSize(tif);
unsigned char *rbuf = (unsigned char *)_TIFFmalloc(3*stripsize);
unsigned char *gbuf = rbuf + stripsize;
unsigned char *bbuf = gbuf + stripsize;
register int y;
tsize_t stripsize = TIFFStripSize(tif);
unsigned char *rbuf = (unsigned char *)_TIFFmalloc(3 * stripsize);
unsigned char *gbuf = rbuf + stripsize;
unsigned char *bbuf = gbuf + stripsize;
register int y;
for (y = 0; y <= ysize; y += rowsperstrip) {
unsigned char *rp, *gp, *bp;
register int x;
register uint32_t n;
for (y = 0; y <= ysize; y += rowsperstrip)
{
unsigned char *rp, *gp, *bp;
register int x;
register uint32_t n;
n = rowsperstrip;
if (n > ysize-y+1)
n = ysize-y+1;
rp = rbuf; gp = gbuf; bp = bbuf;
do {
for (x = 0; x <= xsize; x++) {
uint32_t v = ss[x];
rp[x] = v;
gp[x] = v >> 8;
bp[x] = v >> 16;
}
rp += xsize+1, gp += xsize+1, bp += xsize+1;
ss += xsize+1;
} while (--n);
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
rbuf, stripsize) < 0)
break;
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,1),
gbuf, stripsize) < 0)
break;
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,2),
bbuf, stripsize) < 0)
break;
}
_TIFFfree(rbuf);
n = rowsperstrip;
if (n > ysize - y + 1)
n = ysize - y + 1;
rp = rbuf;
gp = gbuf;
bp = bbuf;
do
{
for (x = 0; x <= xsize; x++)
{
uint32_t v = ss[x];
rp[x] = v;
gp[x] = v >> 8;
bp[x] = v >> 16;
}
rp += xsize + 1, gp += xsize + 1, bp += xsize + 1;
ss += xsize + 1;
} while (--n);
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), rbuf,
stripsize) < 0)
break;
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), gbuf,
stripsize) < 0)
break;
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif, y, 2), bbuf,
stripsize) < 0)
break;
}
_TIFFfree(rbuf);
}
static void
svRGBContig(TIFF* tif, uint32_t* ss, int xsize, int ysize)
static void svRGBContig(TIFF *tif, uint32_t *ss, int xsize, int ysize)
{
register int x, y;
tsize_t stripsize = TIFFStripSize(tif);
unsigned char *strip = (unsigned char *)_TIFFmalloc(stripsize);
register int x, y;
tsize_t stripsize = TIFFStripSize(tif);
unsigned char *strip = (unsigned char *)_TIFFmalloc(stripsize);
for (y = 0; y <= ysize; y += rowsperstrip) {
register unsigned char *pp = strip;
register uint32_t n;
for (y = 0; y <= ysize; y += rowsperstrip)
{
register unsigned char *pp = strip;
register uint32_t n;
n = rowsperstrip;
if (n > ysize-y+1)
n = ysize-y+1;
do {
for (x = 0; x <= xsize; x++) {
uint32_t v = ss[x];
pp[0] = v;
pp[1] = v >> 8;
pp[2] = v >> 16;
pp += 3;
}
ss += xsize+1;
} while (--n);
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
strip, stripsize) < 0)
break;
}
_TIFFfree(strip);
n = rowsperstrip;
if (n > ysize - y + 1)
n = ysize - y + 1;
do
{
for (x = 0; x <= xsize; x++)
{
uint32_t v = ss[x];
pp[0] = v;
pp[1] = v >> 8;
pp[2] = v >> 16;
pp += 3;
}
ss += xsize + 1;
} while (--n);
if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), strip,
stripsize) < 0)
break;
}
_TIFFfree(strip);
}
#undef RED
#undef GREEN
#undef BLUE
#define CVT(x) (((x)*255)/100)
#define RED CVT(28) /* 28% */
#define GREEN CVT(59) /* 59% */
#define BLUE CVT(11) /* 11% */
#define CVT(x) (((x)*255) / 100)
#define RED CVT(28) /* 28% */
#define GREEN CVT(59) /* 59% */
#define BLUE CVT(11) /* 11% */
static void
svGrey(TIFF* tif, uint32_t* ss, int xsize, int ysize)
static void svGrey(TIFF *tif, uint32_t *ss, int xsize, int ysize)
{
register int x, y;
unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
register int x, y;
unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
for (y = 0; y <= ysize; y++) {
for (x = 0; x <= xsize; x++) {
unsigned char *cp = (unsigned char *)&ss[x];
buf[x] = (RED*cp[3] + GREEN*cp[2] + BLUE*cp[1]) >> 8;
}
if (TIFFWriteScanline(tif, buf, (uint32_t) y, 0) < 0)
break;
ss += xsize+1;
}
_TIFFfree(buf);
for (y = 0; y <= ysize; y++)
{
for (x = 0; x <= xsize; x++)
{
unsigned char *cp = (unsigned char *)&ss[x];
buf[x] = (RED * cp[3] + GREEN * cp[2] + BLUE * cp[1]) >> 8;
}
if (TIFFWriteScanline(tif, buf, (uint32_t)y, 0) < 0)
break;
ss += xsize + 1;
}
_TIFFfree(buf);
}
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(x) ((x)<0?-(x):(x))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(x) ((x) < 0 ? -(x) : (x))
static void
tiffsv(char* name, int x1, int x2, int y1, int y2)
static void tiffsv(char *name, int x1, int x2, int y1, int y2)
{
TIFF *tif;
int xsize, ysize;
int xorg, yorg;
uint32_t *scrbuf;
TIFF *tif;
int xsize, ysize;
int xorg, yorg;
uint32_t *scrbuf;
xorg = MIN(x1,x2);
yorg = MIN(y1,y2);
if (xorg<0)
xorg = 0;
if (yorg<0)
yorg = 0;
xsize = ABS(x2-x1);
ysize = ABS(y2-y1);
if (xorg+xsize > xmaxscreen)
xsize = xmaxscreen-xorg;
if (yorg+ysize > ymaxscreen)
ysize = ymaxscreen-yorg;
tif = TIFFOpen(name, "w");
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32_t) (xsize+1));
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32_t) (ysize+1));
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,
photometric == PHOTOMETRIC_RGB ? 3 : 1);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, config);
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(tif, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
if (predictor != 0)
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
scrbuf = (uint32_t *)_TIFFmalloc((xsize+1)*(ysize+1)*sizeof (uint32_t));
readdisplay(xorg, yorg, xorg+xsize, yorg+ysize, scrbuf, RD_FREEZE);
if (photometric == PHOTOMETRIC_RGB) {
if (config == PLANARCONFIG_SEPARATE)
svRGBSeparate(tif, scrbuf, xsize, ysize);
else
svRGBContig(tif, scrbuf, xsize, ysize);
} else
svGrey(tif, scrbuf, xsize, ysize);
(void) TIFFClose(tif);
_TIFFfree((char *)scrbuf);
xorg = MIN(x1, x2);
yorg = MIN(y1, y2);
if (xorg < 0)
xorg = 0;
if (yorg < 0)
yorg = 0;
xsize = ABS(x2 - x1);
ysize = ABS(y2 - y1);
if (xorg + xsize > xmaxscreen)
xsize = xmaxscreen - xorg;
if (yorg + ysize > ymaxscreen)
ysize = ymaxscreen - yorg;
tif = TIFFOpen(name, "w");
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32_t)(xsize + 1));
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32_t)(ysize + 1));
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,
photometric == PHOTOMETRIC_RGB ? 3 : 1);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, config);
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
switch (compression)
{
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB &&
jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(tif, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
if (predictor != 0)
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
scrbuf =
(uint32_t *)_TIFFmalloc((xsize + 1) * (ysize + 1) * sizeof(uint32_t));
readdisplay(xorg, yorg, xorg + xsize, yorg + ysize, scrbuf, RD_FREEZE);
if (photometric == PHOTOMETRIC_RGB)
{
if (config == PLANARCONFIG_SEPARATE)
svRGBSeparate(tif, scrbuf, xsize, ysize);
else
svRGBContig(tif, scrbuf, xsize, ysize);
}
else
svGrey(tif, scrbuf, xsize, ysize);
(void)TIFFClose(tif);
_TIFFfree((char *)scrbuf);
}

View File

@@ -1,17 +1,17 @@
float ycbcrCoeffs[3] = { .299, .587, .114 };
float ycbcrCoeffs[3] = {.299, .587, .114};
/* default coding range is CCIR Rec 601-1 with no headroom/footroom */
unsigned long refBlackWhite[6] = { 0, 255, 128, 255, 128, 255 };
unsigned long refBlackWhite[6] = {0, 255, 128, 255, 128, 255};
#define LumaRed ycbcrCoeffs[0]
#define LumaGreen ycbcrCoeffs[1]
#define LumaBlue ycbcrCoeffs[2]
#define LumaRed ycbcrCoeffs[0]
#define LumaGreen ycbcrCoeffs[1]
#define LumaBlue ycbcrCoeffs[2]
long eRtotal = 0;
long eGtotal = 0;
long eBtotal = 0;
long preveRtotal = 0;
long preveGtotal = 0;
long preveBtotal = 0;
long eRtotal = 0;
long eGtotal = 0;
long eBtotal = 0;
long preveRtotal = 0;
long preveGtotal = 0;
long preveBtotal = 0;
unsigned long AbseRtotal = 0;
unsigned long AbseGtotal = 0;
unsigned long AbseBtotal = 0;
@@ -20,101 +20,90 @@ unsigned long preveCodes = 0;
unsigned long eBits = 0;
unsigned long preveBits = 0;
static void setupLumaTables();
static void setupLumaTables();
static int abs(int v) { return (v < 0 ? -v : v); }
static double pct(int v,double range) { return (v*100. / range); }
static double pct(int v, double range) { return (v * 100. / range); }
static void check(int R, int G, int B);
float D1, D2;
float D3, D4;
float D5, D6;
float D1, D2;
float D3, D4;
float D5, D6;
int
main(int argc, char** argv)
int main(int argc, char **argv)
{
int R, G, B;
if (argc > 1) {
refBlackWhite[0] = 16;
refBlackWhite[1] = 235;
refBlackWhite[2] = 128;
refBlackWhite[3] = 240;
refBlackWhite[4] = 128;
refBlackWhite[5] = 240;
if (argc > 1)
{
refBlackWhite[0] = 16;
refBlackWhite[1] = 235;
refBlackWhite[2] = 128;
refBlackWhite[3] = 240;
refBlackWhite[4] = 128;
refBlackWhite[5] = 240;
}
D3 = 2 - 2*LumaRed;
D4 = 2 - 2*LumaBlue;
D3 = 2 - 2 * LumaRed;
D4 = 2 - 2 * LumaBlue;
D1 = 1. / D3;
D2 = 1. / D4;
D5 = D3*LumaRed / LumaGreen;
D6 = D4*LumaBlue / LumaGreen;
D5 = D3 * LumaRed / LumaGreen;
D6 = D4 * LumaBlue / LumaGreen;
setupLumaTables();
for (R = 0; R < 256; R++) {
for (G = 0; G < 256; G++)
for (B = 0; B < 256; B++)
check(R, G, B);
printf("[%3u] c %u/%u b %u/%u (R %u/%d/%u G %u/%d/%u B %u/%d/%u)\n"
, R
, eCodes - preveCodes, eCodes
, eBits - preveBits, eBits
, abs(AbseRtotal - preveRtotal), eRtotal , AbseRtotal
, abs(AbseGtotal - preveGtotal), eGtotal , AbseGtotal
, abs(AbseBtotal - preveBtotal), eBtotal , AbseBtotal
);
preveRtotal = AbseRtotal;
preveGtotal = AbseGtotal;
preveBtotal = AbseBtotal;
preveCodes = eCodes;
preveBits = eBits;
for (R = 0; R < 256; R++)
{
for (G = 0; G < 256; G++)
for (B = 0; B < 256; B++)
check(R, G, B);
printf("[%3u] c %u/%u b %u/%u (R %u/%d/%u G %u/%d/%u B %u/%d/%u)\n", R,
eCodes - preveCodes, eCodes, eBits - preveBits, eBits,
abs(AbseRtotal - preveRtotal), eRtotal, AbseRtotal,
abs(AbseGtotal - preveGtotal), eGtotal, AbseGtotal,
abs(AbseBtotal - preveBtotal), eBtotal, AbseBtotal);
preveRtotal = AbseRtotal;
preveGtotal = AbseGtotal;
preveBtotal = AbseBtotal;
preveCodes = eCodes;
preveBits = eBits;
}
printf("%u total codes\n", 256*256*256);
printf("total error: %u codes %u bits (R %d/%u G %d/%u B %d/%u)\n"
, eCodes
, eBits
, eRtotal , AbseRtotal
, eGtotal , AbseGtotal
, eBtotal , AbseBtotal
);
printf("%u total codes\n", 256 * 256 * 256);
printf("total error: %u codes %u bits (R %d/%u G %d/%u B %d/%u)\n", eCodes,
eBits, eRtotal, AbseRtotal, eGtotal, AbseGtotal, eBtotal,
AbseBtotal);
return (0);
}
float *lumaRed;
float *lumaGreen;
float *lumaBlue;
float *lumaRed;
float *lumaGreen;
float *lumaBlue;
static float*
setupLuma(float c)
static float *setupLuma(float c)
{
float *v = (float *)_TIFFmalloc(256 * sizeof (float));
float *v = (float *)_TIFFmalloc(256 * sizeof(float));
int i;
for (i = 0; i < 256; i++)
v[i] = c * i;
v[i] = c * i;
return (v);
}
static void
setupLumaTables(void)
static void setupLumaTables(void)
{
lumaRed = setupLuma(LumaRed);
lumaGreen = setupLuma(LumaGreen);
lumaBlue = setupLuma(LumaBlue);
}
static unsigned
V2Code(float f, unsigned long RB, unsigned long RW, int CR)
static unsigned V2Code(float f, unsigned long RB, unsigned long RW, int CR)
{
unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5);
unsigned int c = (unsigned int)((((f) * (RW - RB) / CR) + RB) + .5);
return (c > 255 ? 255 : c);
}
#define Code2V(c, RB, RW, CR) ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))
#define Code2V(c, RB, RW, CR) ((((c) - (int)RB) * (float)CR) / (float)(RW - RB))
#define CLAMP(f,min,max) \
(int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
#define CLAMP(f, min, max) \
(int)((f) + .5 < (min) ? (min) : (f) + .5 > (max) ? (max) : (f) + .5)
static
void
check(int R, int G, int B)
static void check(int R, int G, int B)
{
float Y, Cb, Cr;
int iY, iCb, iCr;
@@ -123,31 +112,29 @@ check(int R, int G, int B)
int eR, eG, eB;
Y = lumaRed[R] + lumaGreen[G] + lumaBlue[B];
Cb = (B - Y)*D2;
Cr = (R - Y)*D1;
Cb = (B - Y) * D2;
Cr = (R - Y) * D1;
iY = V2Code(Y, refBlackWhite[0], refBlackWhite[1], 255);
iCb = V2Code(Cb, refBlackWhite[2], refBlackWhite[3], 127);
iCr = V2Code(Cr, refBlackWhite[4], refBlackWhite[5], 127);
rCb = Code2V(iCb, refBlackWhite[2], refBlackWhite[3], 127);
rCr = Code2V(iCr, refBlackWhite[4], refBlackWhite[5], 127);
rY = Code2V(iY, refBlackWhite[0], refBlackWhite[1], 255);
rR = rY + rCr*D3;
rB = rY + rCb*D4;
rG = rY - rCb*D6 - rCr*D5;
eR = R - CLAMP(rR,0,255);
eG = G - CLAMP(rG,0,255);
eB = B - CLAMP(rB,0,255);
if (abs(eR) > 1 || abs(eG) > 1 || abs(eB) > 1) {
printf("R %u G %u B %u", R, G, B);
printf(" Y %g Cb %g Cr %g", Y, Cb, Cr);
printf(" iY %u iCb %u iCr %u", iY, iCb, iCr);
printf("\n -> Y %g Cb %g Cr %g", rY, rCb, rCr);
printf(" R %g (%u) G %g (%u) B %g (%u) E=[%d %d %d])\n"
, rR, CLAMP(rR,0,255)
, rG, CLAMP(rG,0,255)
, rB, CLAMP(rB,0,255)
, eR, eG, eB
);
rR = rY + rCr * D3;
rB = rY + rCb * D4;
rG = rY - rCb * D6 - rCr * D5;
eR = R - CLAMP(rR, 0, 255);
eG = G - CLAMP(rG, 0, 255);
eB = B - CLAMP(rB, 0, 255);
if (abs(eR) > 1 || abs(eG) > 1 || abs(eB) > 1)
{
printf("R %u G %u B %u", R, G, B);
printf(" Y %g Cb %g Cr %g", Y, Cb, Cr);
printf(" iY %u iCb %u iCr %u", iY, iCb, iCr);
printf("\n -> Y %g Cb %g Cr %g", rY, rCb, rCr);
printf(" R %g (%u) G %g (%u) B %g (%u) E=[%d %d %d])\n", rR,
CLAMP(rR, 0, 255), rG, CLAMP(rG, 0, 255), rB, CLAMP(rB, 0, 255),
eR, eG, eB);
}
eRtotal += eR;
eGtotal += eG;
@@ -156,6 +143,6 @@ check(int R, int G, int B)
AbseGtotal += abs(eG);
AbseBtotal += abs(eB);
if (eR | eG | eB)
eCodes++;
eCodes++;
eBits += abs(eR) + abs(eG) + abs(eB);
}

View File

@@ -59,49 +59,50 @@
* New
*/
#include "tiffio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tiffio.h"
void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
int (*)(double,void*), void * );
void TIFFBuildOverviews(TIFF *, int, int *, int, const char *,
int (*)(double, void *), void *);
/************************************************************************/
/* main() */
/************************************************************************/
int main( int argc, char ** argv )
int main(int argc, char **argv)
{
int anOverviews[100]; /* TODO: un-hardwire array length, flexible allocate */
int nOverviewCount = 0;
int bUseSubIFD = 0;
TIFF *hTIFF;
const char *pszResampling = "nearest";
int anOverviews[100]; /* TODO: un-hardwire array length, flexible allocate
*/
int nOverviewCount = 0;
int bUseSubIFD = 0;
TIFF *hTIFF;
const char *pszResampling = "nearest";
/* -------------------------------------------------------------------- */
/* Usage: */
/* -------------------------------------------------------------------- */
if( argc < 2 )
/* -------------------------------------------------------------------- */
/* Usage: */
/* -------------------------------------------------------------------- */
if (argc < 2)
{
printf( "Usage: addtiffo [-r {nearest,average,mode}]\n"
" tiff_filename [resolution_reductions]\n"
"\n"
"Example:\n"
" %% addtiffo abc.tif 2 4 8 16\n" );
return( 1 );
printf("Usage: addtiffo [-r {nearest,average,mode}]\n"
" tiff_filename [resolution_reductions]\n"
"\n"
"Example:\n"
" %% addtiffo abc.tif 2 4 8 16\n");
return (1);
}
while( argv[1][0] == '-' )
while (argv[1][0] == '-')
{
if( strcmp(argv[1],"-subifd") == 0 )
if (strcmp(argv[1], "-subifd") == 0)
{
bUseSubIFD = 1;
argv++;
argc--;
}
else if( strcmp(argv[1],"-r") == 0 )
else if (strcmp(argv[1], "-r") == 0)
{
argv += 2;
argc -= 2;
@@ -109,34 +110,35 @@ int main( int argc, char ** argv )
}
else
{
fprintf( stderr, "Incorrect parameters\n" );
return( 1 );
fprintf(stderr, "Incorrect parameters\n");
return (1);
}
}
/* TODO: resampling mode parameter needs to be encoded in an integer from this point on */
/* TODO: resampling mode parameter needs to be encoded in an integer from
* this point on */
/* -------------------------------------------------------------------- */
/* Collect the user requested reduction factors. */
/* -------------------------------------------------------------------- */
while( nOverviewCount < argc - 2 && nOverviewCount < 100 )
/* -------------------------------------------------------------------- */
/* Collect the user requested reduction factors. */
/* -------------------------------------------------------------------- */
while (nOverviewCount < argc - 2 && nOverviewCount < 100)
{
anOverviews[nOverviewCount] = atoi(argv[nOverviewCount+2]);
if( (anOverviews[nOverviewCount] <= 0) ||
anOverviews[nOverviewCount] = atoi(argv[nOverviewCount + 2]);
if ((anOverviews[nOverviewCount] <= 0) ||
((anOverviews[nOverviewCount] > 1024)))
{
fprintf( stderr, "Incorrect parameters\n" );
return(1);
fprintf(stderr, "Incorrect parameters\n");
return (1);
}
nOverviewCount++;
}
/* -------------------------------------------------------------------- */
/* Default to four overview levels. It would be nicer if it */
/* defaulted based on the size of the source image. */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* Default to four overview levels. It would be nicer if it */
/* defaulted based on the size of the source image. */
/* -------------------------------------------------------------------- */
/* TODO: make it default based on the size of the source image */
if( nOverviewCount == 0 )
if (nOverviewCount == 0)
{
nOverviewCount = 4;
@@ -146,20 +148,20 @@ int main( int argc, char ** argv )
anOverviews[3] = 16;
}
/* -------------------------------------------------------------------- */
/* Build the overview. */
/* -------------------------------------------------------------------- */
hTIFF = TIFFOpen( argv[1], "r+" );
if( hTIFF == NULL )
/* -------------------------------------------------------------------- */
/* Build the overview. */
/* -------------------------------------------------------------------- */
hTIFF = TIFFOpen(argv[1], "r+");
if (hTIFF == NULL)
{
fprintf( stderr, "TIFFOpen(%s) failed.\n", argv[1] );
return( 1 );
fprintf(stderr, "TIFFOpen(%s) failed.\n", argv[1]);
return (1);
}
TIFFBuildOverviews( hTIFF, nOverviewCount, anOverviews, bUseSubIFD,
pszResampling, NULL, NULL );
TIFFBuildOverviews(hTIFF, nOverviewCount, anOverviews, bUseSubIFD,
pszResampling, NULL, NULL);
TIFFClose( hTIFF );
TIFFClose(hTIFF);
/* -------------------------------------------------------------------- */
/* Optionally test for memory leaks. */
@@ -168,5 +170,5 @@ int main( int argc, char ** argv )
malloc_dump(1);
#endif
return( 0 );
return (0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/******************************************************************************
* Project: TIFF Overview Builder
* Purpose: Library functions to maintain two rows of tiles or two strips
* of data for output overviews as an output cache.
* of data for output overviews as an output cache.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
@@ -27,8 +27,8 @@
******************************************************************************
*/
#include "tiffiop.h"
#include "tif_ovrcache.h"
#include "tiffiop.h"
#include <assert.h>
/************************************************************************/
@@ -38,89 +38,90 @@
/* existing TIFF directory. */
/************************************************************************/
TIFFOvrCache *TIFFCreateOvrCache( TIFF *hTIFF, toff_t nDirOffset )
TIFFOvrCache *TIFFCreateOvrCache(TIFF *hTIFF, toff_t nDirOffset)
{
TIFFOvrCache *psCache;
toff_t nBaseDirOffset;
TIFFOvrCache *psCache;
toff_t nBaseDirOffset;
psCache = (TIFFOvrCache *) _TIFFmalloc(sizeof(TIFFOvrCache));
psCache = (TIFFOvrCache *)_TIFFmalloc(sizeof(TIFFOvrCache));
psCache->nDirOffset = nDirOffset;
psCache->hTIFF = hTIFF;
/* -------------------------------------------------------------------- */
/* Get definition of this raster from the TIFF file itself. */
/* -------------------------------------------------------------------- */
nBaseDirOffset = TIFFCurrentDirOffset( psCache->hTIFF );
TIFFSetSubDirectory( hTIFF, nDirOffset );
TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &(psCache->nXSize) );
TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &(psCache->nYSize) );
TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &(psCache->nBitsPerPixel) );
TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &(psCache->nSamples) );
TIFFGetField( hTIFF, TIFFTAG_PLANARCONFIG, &(psCache->nPlanarConfig) );
/* -------------------------------------------------------------------- */
/* Get definition of this raster from the TIFF file itself. */
/* -------------------------------------------------------------------- */
nBaseDirOffset = TIFFCurrentDirOffset(psCache->hTIFF);
TIFFSetSubDirectory(hTIFF, nDirOffset);
if( !TIFFIsTiled( hTIFF ) )
TIFFGetField(hTIFF, TIFFTAG_IMAGEWIDTH, &(psCache->nXSize));
TIFFGetField(hTIFF, TIFFTAG_IMAGELENGTH, &(psCache->nYSize));
TIFFGetField(hTIFF, TIFFTAG_BITSPERSAMPLE, &(psCache->nBitsPerPixel));
TIFFGetField(hTIFF, TIFFTAG_SAMPLESPERPIXEL, &(psCache->nSamples));
TIFFGetField(hTIFF, TIFFTAG_PLANARCONFIG, &(psCache->nPlanarConfig));
if (!TIFFIsTiled(hTIFF))
{
TIFFGetField( hTIFF, TIFFTAG_ROWSPERSTRIP, &(psCache->nBlockYSize) );
TIFFGetField(hTIFF, TIFFTAG_ROWSPERSTRIP, &(psCache->nBlockYSize));
psCache->nBlockXSize = psCache->nXSize;
psCache->nBytesPerBlock = TIFFStripSize(hTIFF);
psCache->bTiled = FALSE;
}
else
{
TIFFGetField( hTIFF, TIFFTAG_TILEWIDTH, &(psCache->nBlockXSize) );
TIFFGetField( hTIFF, TIFFTAG_TILELENGTH, &(psCache->nBlockYSize) );
TIFFGetField(hTIFF, TIFFTAG_TILEWIDTH, &(psCache->nBlockXSize));
TIFFGetField(hTIFF, TIFFTAG_TILELENGTH, &(psCache->nBlockYSize));
psCache->nBytesPerBlock = TIFFTileSize(hTIFF);
psCache->bTiled = TRUE;
}
/* -------------------------------------------------------------------- */
/* Compute some values from this. */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* Compute some values from this. */
/* -------------------------------------------------------------------- */
psCache->nBlocksPerRow = (psCache->nXSize + psCache->nBlockXSize - 1)
/ psCache->nBlockXSize;
psCache->nBlocksPerColumn = (psCache->nYSize + psCache->nBlockYSize - 1)
/ psCache->nBlockYSize;
psCache->nBlocksPerRow =
(psCache->nXSize + psCache->nBlockXSize - 1) / psCache->nBlockXSize;
psCache->nBlocksPerColumn =
(psCache->nYSize + psCache->nBlockYSize - 1) / psCache->nBlockYSize;
if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)
psCache->nBytesPerRow = psCache->nBytesPerBlock
* psCache->nBlocksPerRow * psCache->nSamples;
psCache->nBytesPerRow = psCache->nBytesPerBlock *
psCache->nBlocksPerRow * psCache->nSamples;
else
psCache->nBytesPerRow =
psCache->nBytesPerBlock * psCache->nBlocksPerRow;
/* -------------------------------------------------------------------- */
/* Allocate and initialize the data buffers. */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* Allocate and initialize the data buffers. */
/* -------------------------------------------------------------------- */
psCache->pabyRow1Blocks =
(unsigned char *) _TIFFmalloc(psCache->nBytesPerRow);
(unsigned char *)_TIFFmalloc(psCache->nBytesPerRow);
psCache->pabyRow2Blocks =
(unsigned char *) _TIFFmalloc(psCache->nBytesPerRow);
(unsigned char *)_TIFFmalloc(psCache->nBytesPerRow);
if ( psCache->pabyRow1Blocks == NULL
|| psCache->pabyRow2Blocks == NULL )
if (psCache->pabyRow1Blocks == NULL || psCache->pabyRow2Blocks == NULL)
{
TIFFErrorExt( hTIFF->tif_clientdata, hTIFF->tif_name,
"Can't allocate memory for overview cache." );
/* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */
if (psCache->pabyRow1Blocks) _TIFFfree(psCache->pabyRow1Blocks);
if (psCache->pabyRow2Blocks) _TIFFfree(psCache->pabyRow2Blocks);
_TIFFfree( psCache );
TIFFErrorExt(hTIFF->tif_clientdata, hTIFF->tif_name,
"Can't allocate memory for overview cache.");
/* TODO: use of TIFFError is inconsistent with use of fprintf in
* addtiffo.c, sort out */
if (psCache->pabyRow1Blocks)
_TIFFfree(psCache->pabyRow1Blocks);
if (psCache->pabyRow2Blocks)
_TIFFfree(psCache->pabyRow2Blocks);
_TIFFfree(psCache);
return NULL;
}
_TIFFmemset( psCache->pabyRow1Blocks, 0, psCache->nBytesPerRow );
_TIFFmemset( psCache->pabyRow2Blocks, 0, psCache->nBytesPerRow );
_TIFFmemset(psCache->pabyRow1Blocks, 0, psCache->nBytesPerRow);
_TIFFmemset(psCache->pabyRow2Blocks, 0, psCache->nBytesPerRow);
psCache->nBlockOffset = 0;
TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );
TIFFSetSubDirectory(psCache->hTIFF, nBaseDirOffset);
return psCache;
}
@@ -132,130 +133,130 @@ TIFFOvrCache *TIFFCreateOvrCache( TIFF *hTIFF, toff_t nDirOffset )
/* down by one block. */
/************************************************************************/
static void TIFFWriteOvrRow( TIFFOvrCache * psCache )
static void TIFFWriteOvrRow(TIFFOvrCache *psCache)
{
int nRet, iTileX, iTileY = psCache->nBlockOffset;
int nRet, iTileX, iTileY = psCache->nBlockOffset;
unsigned char *pabyData;
toff_t nBaseDirOffset;
uint32_t RowsInStrip;
toff_t nBaseDirOffset;
uint32_t RowsInStrip;
/* -------------------------------------------------------------------- */
/* If the output cache is multi-byte per sample, and the file */
/* being written to is of a different byte order than the current */
/* platform, we will need to byte swap the data. */
/* -------------------------------------------------------------------- */
if( TIFFIsByteSwapped(psCache->hTIFF) )
/* -------------------------------------------------------------------- */
/* If the output cache is multi-byte per sample, and the file */
/* being written to is of a different byte order than the current */
/* platform, we will need to byte swap the data. */
/* -------------------------------------------------------------------- */
if (TIFFIsByteSwapped(psCache->hTIFF))
{
if( psCache->nBitsPerPixel == 16 )
TIFFSwabArrayOfShort( (uint16_t *) psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) / 2 );
if (psCache->nBitsPerPixel == 16)
TIFFSwabArrayOfShort((uint16_t *)psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) /
2);
else if( psCache->nBitsPerPixel == 32 )
TIFFSwabArrayOfLong( (uint32_t *) psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) / 4 );
else if (psCache->nBitsPerPixel == 32)
TIFFSwabArrayOfLong((uint32_t *)psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) /
4);
else if( psCache->nBitsPerPixel == 64 )
TIFFSwabArrayOfDouble( (double *) psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) / 8 );
else if (psCache->nBitsPerPixel == 64)
TIFFSwabArrayOfDouble(
(double *)psCache->pabyRow1Blocks,
(psCache->nBytesPerBlock * psCache->nSamples) / 8);
}
/* -------------------------------------------------------------------- */
/* Record original directory position, so we can restore it at */
/* end. */
/* -------------------------------------------------------------------- */
nBaseDirOffset = TIFFCurrentDirOffset( psCache->hTIFF );
nRet = TIFFSetSubDirectory( psCache->hTIFF, psCache->nDirOffset );
(void) nRet;
assert( nRet == 1 );
/* -------------------------------------------------------------------- */
/* Record original directory position, so we can restore it at */
/* end. */
/* -------------------------------------------------------------------- */
nBaseDirOffset = TIFFCurrentDirOffset(psCache->hTIFF);
nRet = TIFFSetSubDirectory(psCache->hTIFF, psCache->nDirOffset);
(void)nRet;
assert(nRet == 1);
/* -------------------------------------------------------------------- */
/* Write blocks to TIFF file. */
/* -------------------------------------------------------------------- */
for( iTileX = 0; iTileX < psCache->nBlocksPerRow; iTileX++ )
{
int nTileID;
/* -------------------------------------------------------------------- */
/* Write blocks to TIFF file. */
/* -------------------------------------------------------------------- */
for (iTileX = 0; iTileX < psCache->nBlocksPerRow; iTileX++)
{
int nTileID;
if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)
{
int iSample;
if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)
{
int iSample;
for( iSample = 0; iSample < psCache->nSamples; iSample++ )
{
pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, iSample );
for (iSample = 0; iSample < psCache->nSamples; iSample++)
{
pabyData = TIFFGetOvrBlock(psCache, iTileX, iTileY, iSample);
if( psCache->bTiled )
{
nTileID = TIFFComputeTile( psCache->hTIFF,
iTileX * psCache->nBlockXSize,
iTileY * psCache->nBlockYSize,
0, (tsample_t) iSample );
TIFFWriteEncodedTile( psCache->hTIFF, nTileID,
pabyData,
TIFFTileSize(psCache->hTIFF) );
}
else
{
nTileID = TIFFComputeStrip( psCache->hTIFF,
iTileY * psCache->nBlockYSize,
(tsample_t) iSample );
RowsInStrip=psCache->nBlockYSize;
if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
pabyData,
TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
}
}
if (psCache->bTiled)
{
nTileID = TIFFComputeTile(
psCache->hTIFF, iTileX * psCache->nBlockXSize,
iTileY * psCache->nBlockYSize, 0, (tsample_t)iSample);
TIFFWriteEncodedTile(psCache->hTIFF, nTileID, pabyData,
TIFFTileSize(psCache->hTIFF));
}
else
{
nTileID = TIFFComputeStrip(psCache->hTIFF,
iTileY * psCache->nBlockYSize,
(tsample_t)iSample);
RowsInStrip = psCache->nBlockYSize;
if ((iTileY + 1) * psCache->nBlockYSize > psCache->nYSize)
RowsInStrip =
psCache->nYSize - iTileY * psCache->nBlockYSize;
TIFFWriteEncodedStrip(
psCache->hTIFF, nTileID, pabyData,
TIFFVStripSize(psCache->hTIFF, RowsInStrip));
}
}
}
else
{
pabyData = TIFFGetOvrBlock(psCache, iTileX, iTileY, 0);
}
else
{
pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, 0 );
if (psCache->bTiled)
{
nTileID = TIFFComputeTile(psCache->hTIFF,
iTileX * psCache->nBlockXSize,
iTileY * psCache->nBlockYSize, 0, 0);
TIFFWriteEncodedTile(psCache->hTIFF, nTileID, pabyData,
TIFFTileSize(psCache->hTIFF));
}
else
{
nTileID = TIFFComputeStrip(psCache->hTIFF,
iTileY * psCache->nBlockYSize, 0);
RowsInStrip = psCache->nBlockYSize;
if ((iTileY + 1) * psCache->nBlockYSize > psCache->nYSize)
RowsInStrip =
psCache->nYSize - iTileY * psCache->nBlockYSize;
TIFFWriteEncodedStrip(
psCache->hTIFF, nTileID, pabyData,
TIFFVStripSize(psCache->hTIFF, RowsInStrip));
}
}
}
/* TODO: add checks on error status return of TIFFWriteEncodedTile and
* TIFFWriteEncodedStrip */
if( psCache->bTiled )
{
nTileID = TIFFComputeTile( psCache->hTIFF,
iTileX * psCache->nBlockXSize,
iTileY * psCache->nBlockYSize,
0, 0 );
TIFFWriteEncodedTile( psCache->hTIFF, nTileID,
pabyData,
TIFFTileSize(psCache->hTIFF) );
}
else
{
nTileID = TIFFComputeStrip( psCache->hTIFF,
iTileY * psCache->nBlockYSize,
0 );
RowsInStrip=psCache->nBlockYSize;
if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
pabyData,
TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
}
}
}
/* TODO: add checks on error status return of TIFFWriteEncodedTile and TIFFWriteEncodedStrip */
/* -------------------------------------------------------------------- */
/* Rotate buffers. */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* Rotate buffers. */
/* -------------------------------------------------------------------- */
pabyData = psCache->pabyRow1Blocks;
psCache->pabyRow1Blocks = psCache->pabyRow2Blocks;
psCache->pabyRow2Blocks = pabyData;
_TIFFmemset( pabyData, 0, psCache->nBytesPerRow );
_TIFFmemset(pabyData, 0, psCache->nBytesPerRow);
psCache->nBlockOffset++;
/* -------------------------------------------------------------------- */
/* Restore access to original directory. */
/* -------------------------------------------------------------------- */
TIFFFlush( psCache->hTIFF );
/* -------------------------------------------------------------------- */
/* Restore access to original directory. */
/* -------------------------------------------------------------------- */
TIFFFlush(psCache->hTIFF);
/* TODO: add checks on error status return of TIFFFlush */
TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );
TIFFSetSubDirectory(psCache->hTIFF, nBaseDirOffset);
/* TODO: add checks on error status return of TIFFSetSubDirectory */
}
@@ -264,30 +265,31 @@ static void TIFFWriteOvrRow( TIFFOvrCache * psCache )
/************************************************************************/
/* TODO: make TIFF_Downsample handle iSample offset, so that we can
* do with a single TIFFGetOvrBlock and no longer need TIFFGetOvrBlock_Subsampled */
unsigned char *TIFFGetOvrBlock( TIFFOvrCache *psCache, int iTileX, int iTileY,
int iSample )
* do with a single TIFFGetOvrBlock and no longer need
* TIFFGetOvrBlock_Subsampled */
unsigned char *TIFFGetOvrBlock(TIFFOvrCache *psCache, int iTileX, int iTileY,
int iSample)
{
long nRowOffset;
long nRowOffset;
if ( iTileY > psCache->nBlockOffset + 1 )
TIFFWriteOvrRow( psCache );
if (iTileY > psCache->nBlockOffset + 1)
TIFFWriteOvrRow(psCache);
assert( iTileX >= 0 && iTileX < psCache->nBlocksPerRow );
assert( iTileY >= 0 && iTileY < psCache->nBlocksPerColumn );
assert( iTileY >= psCache->nBlockOffset
&& iTileY < psCache->nBlockOffset+2 );
assert( iSample >= 0 && iSample < psCache->nSamples );
assert(iTileX >= 0 && iTileX < psCache->nBlocksPerRow);
assert(iTileY >= 0 && iTileY < psCache->nBlocksPerColumn);
assert(iTileY >= psCache->nBlockOffset &&
iTileY < psCache->nBlockOffset + 2);
assert(iSample >= 0 && iSample < psCache->nSamples);
if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)
nRowOffset = ((((toff_t) iTileX * psCache->nSamples) + iSample)
* psCache->nBytesPerBlock);
nRowOffset = ((((toff_t)iTileX * psCache->nSamples) + iSample) *
psCache->nBytesPerBlock);
else
nRowOffset = iTileX * psCache->nBytesPerBlock +
(psCache->nBitsPerPixel + 7) / 8 * iSample;
(psCache->nBitsPerPixel + 7) / 8 * iSample;
if ( iTileY == psCache->nBlockOffset )
if (iTileY == psCache->nBlockOffset)
return psCache->pabyRow1Blocks + nRowOffset;
else
return psCache->pabyRow2Blocks + nRowOffset;
@@ -297,24 +299,24 @@ unsigned char *TIFFGetOvrBlock( TIFFOvrCache *psCache, int iTileX, int iTileY,
/* TIFFGetOvrBlock_Subsampled() */
/************************************************************************/
unsigned char *TIFFGetOvrBlock_Subsampled( TIFFOvrCache *psCache,
int iTileX, int iTileY )
unsigned char *TIFFGetOvrBlock_Subsampled(TIFFOvrCache *psCache, int iTileX,
int iTileY)
{
int nRowOffset;
int nRowOffset;
if( iTileY > psCache->nBlockOffset + 1 )
TIFFWriteOvrRow( psCache );
if (iTileY > psCache->nBlockOffset + 1)
TIFFWriteOvrRow(psCache);
assert( iTileX >= 0 && iTileX < psCache->nBlocksPerRow );
assert( iTileY >= 0 && iTileY < psCache->nBlocksPerColumn );
assert( iTileY >= psCache->nBlockOffset
&& iTileY < psCache->nBlockOffset+2 );
assert( psCache->nPlanarConfig != PLANARCONFIG_SEPARATE );
assert(iTileX >= 0 && iTileX < psCache->nBlocksPerRow);
assert(iTileY >= 0 && iTileY < psCache->nBlocksPerColumn);
assert(iTileY >= psCache->nBlockOffset &&
iTileY < psCache->nBlockOffset + 2);
assert(psCache->nPlanarConfig != PLANARCONFIG_SEPARATE);
nRowOffset = iTileX * psCache->nBytesPerBlock;
if( iTileY == psCache->nBlockOffset )
if (iTileY == psCache->nBlockOffset)
return psCache->pabyRow1Blocks + nRowOffset;
else
return psCache->pabyRow2Blocks + nRowOffset;
@@ -324,13 +326,13 @@ unsigned char *TIFFGetOvrBlock_Subsampled( TIFFOvrCache *psCache,
/* TIFFDestroyOvrCache() */
/************************************************************************/
void TIFFDestroyOvrCache( TIFFOvrCache * psCache )
void TIFFDestroyOvrCache(TIFFOvrCache *psCache)
{
while( psCache->nBlockOffset < psCache->nBlocksPerColumn )
TIFFWriteOvrRow( psCache );
while (psCache->nBlockOffset < psCache->nBlocksPerColumn)
TIFFWriteOvrRow(psCache);
_TIFFfree( psCache->pabyRow1Blocks );
_TIFFfree( psCache->pabyRow2Blocks );
_TIFFfree( psCache );
_TIFFfree(psCache->pabyRow1Blocks);
_TIFFfree(psCache->pabyRow2Blocks);
_TIFFfree(psCache);
}

View File

@@ -3,11 +3,11 @@
*
* Project: TIFF Overview Builder
* Purpose: Library functions to maintain two rows of tiles or two strips
* of data for output overviews as an output cache.
* of data for output overviews as an output cache.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
* This code could potentially be used by other applications wanting to
* manage a once-through write cache.
* manage a once-through write cache.
*
******************************************************************************
* Copyright (c) 2000, Frank Warmerdam
@@ -38,58 +38,58 @@
#include "tiffio.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct
extern "C"
{
uint32_t nXSize;
uint32_t nYSize;
#endif
uint16_t nBitsPerPixel;
uint16_t nSamples;
uint16_t nPlanarConfig;
uint32_t nBlockXSize;
uint32_t nBlockYSize;
toff_t nBytesPerBlock;
toff_t nBytesPerRow;
typedef struct
{
uint32_t nXSize;
uint32_t nYSize;
int nBlocksPerRow;
int nBlocksPerColumn;
uint16_t nBitsPerPixel;
uint16_t nSamples;
uint16_t nPlanarConfig;
uint32_t nBlockXSize;
uint32_t nBlockYSize;
toff_t nBytesPerBlock;
toff_t nBytesPerRow;
int nBlockOffset; /* what block is the first in papabyBlocks? */
unsigned char *pabyRow1Blocks;
unsigned char *pabyRow2Blocks;
int nBlocksPerRow;
int nBlocksPerColumn;
toff_t nDirOffset;
TIFF *hTIFF;
int bTiled;
} TIFFOvrCache;
int nBlockOffset; /* what block is the first in papabyBlocks? */
unsigned char *pabyRow1Blocks;
unsigned char *pabyRow2Blocks;
TIFFOvrCache *TIFFCreateOvrCache( TIFF *hTIFF, toff_t nDirOffset );
unsigned char *TIFFGetOvrBlock( TIFFOvrCache *psCache, int iTileX, int iTileY,
int iSample );
unsigned char *TIFFGetOvrBlock_Subsampled( TIFFOvrCache *psCache, int iTileX, int iTileY );
void TIFFDestroyOvrCache( TIFFOvrCache * );
toff_t nDirOffset;
TIFF *hTIFF;
int bTiled;
void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
int (*)(double,void*), void * );
} TIFFOvrCache;
void TIFF_ProcessFullResBlock( TIFF *, int, int, int, int, int, int *, int,
int, TIFFOvrCache **, uint32_t, uint32_t,
unsigned char *, uint32_t, uint32_t,
int, const char * );
TIFFOvrCache *TIFFCreateOvrCache(TIFF *hTIFF, toff_t nDirOffset);
unsigned char *TIFFGetOvrBlock(TIFFOvrCache *psCache, int iTileX,
int iTileY, int iSample);
unsigned char *TIFFGetOvrBlock_Subsampled(TIFFOvrCache *psCache, int iTileX,
int iTileY);
void TIFFDestroyOvrCache(TIFFOvrCache *);
uint32_t TIFF_WriteOverview( TIFF *, uint32_t, uint32_t, int, int, int, int, int,
int, int, int, int, unsigned short *,
unsigned short *, unsigned short *, int,
int, int);
void TIFFBuildOverviews(TIFF *, int, int *, int, const char *,
int (*)(double, void *), void *);
void TIFF_ProcessFullResBlock(TIFF *, int, int, int, int, int, int *, int,
int, TIFFOvrCache **, uint32_t, uint32_t,
unsigned char *, uint32_t, uint32_t, int,
const char *);
uint32_t TIFF_WriteOverview(TIFF *, uint32_t, uint32_t, int, int, int, int,
int, int, int, int, int, unsigned short *,
unsigned short *, unsigned short *, int, int,
int);
#if defined(__cplusplus)
}
#endif
#endif /* ndef TIF_OVRCACHE_H_INCLUDED */

View File

@@ -27,21 +27,23 @@
#include "tiffio.h"
#define WIDTH 512
#define HEIGHT WIDTH
#define WIDTH 512
#define HEIGHT WIDTH
int main(int argc, char **argv)
{
int i;
unsigned char * scan_line;
TIFF * tif;
int i;
unsigned char *scan_line;
TIFF *tif;
if (argc != 2) {
if (argc != 2)
{
fprintf(stderr, "Usage: %s tiff-image\n", argv[0]);
return 0;
}
if ((tif = TIFFOpen(argv[1], "w")) == NULL) {
if ((tif = TIFFOpen(argv[1], "w")) == NULL)
{
fprintf(stderr, "can't open %s as a TIFF file\n", argv[1]);
return 0;
}
@@ -56,7 +58,7 @@ int main(int argc, char **argv)
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
scan_line = (unsigned char *) malloc(WIDTH / 8);
scan_line = (unsigned char *)malloc(WIDTH / 8);
for (i = 0; i < (WIDTH / 8) / 2; i++)
scan_line[i] = 0;

View File

@@ -30,20 +30,20 @@
#include "tiffio.h"
#define WIDTH 512
#define HEIGHT WIDTH
#define WIDTH 512
#define HEIGHT WIDTH
char * programName;
void Usage();
char *programName;
void Usage();
int main(int argc, char **argv)
{
int bits_per_pixel = 8, cmsize, i, j, k,
gray_index, chunk_size = 32, nchunks = 16;
unsigned char * scan_line;
uint16_t * gray;
float refblackwhite[2*1];
TIFF * tif;
int bits_per_pixel = 8, cmsize, i, j, k, gray_index, chunk_size = 32,
nchunks = 16;
unsigned char *scan_line;
uint16_t *gray;
float refblackwhite[2 * 1];
TIFF *tif;
programName = argv[0];
@@ -51,11 +51,12 @@ int main(int argc, char **argv)
Usage();
if (!strcmp(argv[1], "-depth"))
bits_per_pixel = atoi(argv[2]);
bits_per_pixel = atoi(argv[2]);
else
Usage();
Usage();
switch (bits_per_pixel) {
switch (bits_per_pixel)
{
case 8:
nchunks = 16;
chunk_size = 32;
@@ -73,18 +74,19 @@ int main(int argc, char **argv)
}
cmsize = nchunks * nchunks;
gray = (uint16_t *) malloc(cmsize * sizeof(uint16_t));
gray = (uint16_t *)malloc(cmsize * sizeof(uint16_t));
gray[0] = 3000;
for (i = 1; i < cmsize; i++)
gray[i] = (uint16_t) (-log10((double) i / (cmsize - 1)) * 1000);
gray[i] = (uint16_t)(-log10((double)i / (cmsize - 1)) * 1000);
refblackwhite[0] = 0.0;
refblackwhite[1] = (float)((1L<<bits_per_pixel) - 1);
refblackwhite[1] = (float)((1L << bits_per_pixel) - 1);
if ((tif = TIFFOpen(argv[3], "w")) == NULL) {
if ((tif = TIFFOpen(argv[3], "w")) == NULL)
{
fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]);
free(gray);
free(gray);
return 0;
}
@@ -100,26 +102,29 @@ int main(int argc, char **argv)
TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, gray);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
scan_line = (unsigned char *) malloc(WIDTH / (8 / bits_per_pixel));
scan_line = (unsigned char *)malloc(WIDTH / (8 / bits_per_pixel));
for (i = 0; i < HEIGHT; i++) {
for (j = 0, k = 0; j < WIDTH;) {
for (i = 0; i < HEIGHT; i++)
{
for (j = 0, k = 0; j < WIDTH;)
{
gray_index = (j / chunk_size) + ((i / chunk_size) * nchunks);
switch (bits_per_pixel) {
case 8:
scan_line[k++] = gray_index;
j++;
break;
case 4:
scan_line[k++] = (gray_index << 4) + gray_index;
j += 2;
break;
case 2:
scan_line[k++] = (gray_index << 6) + (gray_index << 4)
+ (gray_index << 2) + gray_index;
j += 4;
break;
switch (bits_per_pixel)
{
case 8:
scan_line[k++] = gray_index;
j++;
break;
case 4:
scan_line[k++] = (gray_index << 4) + gray_index;
j += 2;
break;
case 2:
scan_line[k++] = (gray_index << 6) + (gray_index << 4) +
(gray_index << 2) + gray_index;
j += 4;
break;
}
}
TIFFWriteScanline(tif, scan_line, i, 0);
@@ -130,8 +135,7 @@ int main(int argc, char **argv)
return 0;
}
void
Usage()
void Usage()
{
fprintf(stderr, "Usage: %s -depth (8 | 4 | 2) tiff-image\n", programName);
exit(0);

View File

@@ -28,20 +28,20 @@
#include "tiffio.h"
#define WIDTH 512
#define HEIGHT WIDTH
#define SCALE(x) ((x) * 257L)
#define WIDTH 512
#define HEIGHT WIDTH
#define SCALE(x) ((x)*257L)
char * programName;
void Usage();
char *programName;
void Usage();
int main(int argc, char **argv)
{
int bits_per_pixel = 8, cmsize, i, j, k,
cmap_index, chunk_size = 32, nchunks = 16;
unsigned char * scan_line;
uint16_t *red, *green, *blue;
TIFF * tif;
int bits_per_pixel = 8, cmsize, i, j, k, cmap_index, chunk_size = 32,
nchunks = 16;
unsigned char *scan_line;
uint16_t *red, *green, *blue;
TIFF *tif;
programName = argv[0];
@@ -49,11 +49,12 @@ int main(int argc, char **argv)
Usage();
if (!strcmp(argv[1], "-depth"))
bits_per_pixel = atoi(argv[2]);
bits_per_pixel = atoi(argv[2]);
else
Usage();
Usage();
switch (bits_per_pixel) {
switch (bits_per_pixel)
{
case 8:
nchunks = 16;
chunk_size = 32;
@@ -66,158 +67,166 @@ int main(int argc, char **argv)
nchunks = 2;
chunk_size = 256;
break;
case 1:
nchunks = 2;
chunk_size = 256;
break;
case 1:
nchunks = 2;
chunk_size = 256;
break;
default:
Usage();
}
if (bits_per_pixel != 1) {
cmsize = nchunks * nchunks;
} else {
cmsize = 2;
if (bits_per_pixel != 1)
{
cmsize = nchunks * nchunks;
}
red = (uint16_t *) malloc(cmsize * sizeof(uint16_t));
green = (uint16_t *) malloc(cmsize * sizeof(uint16_t));
blue = (uint16_t *) malloc(cmsize * sizeof(uint16_t));
else
{
cmsize = 2;
}
red = (uint16_t *)malloc(cmsize * sizeof(uint16_t));
green = (uint16_t *)malloc(cmsize * sizeof(uint16_t));
blue = (uint16_t *)malloc(cmsize * sizeof(uint16_t));
switch (bits_per_pixel) {
case 8:
for (i = 0; i < cmsize; i++) {
if (i < 32)
red[i] = 0;
else if (i < 64)
red[i] = SCALE(36);
else if (i < 96)
red[i] = SCALE(73);
else if (i < 128)
red[i] = SCALE(109);
else if (i < 160)
red[i] = SCALE(146);
else if (i < 192)
red[i] = SCALE(182);
else if (i < 224)
red[i] = SCALE(219);
else if (i < 256)
red[i] = SCALE(255);
switch (bits_per_pixel)
{
case 8:
for (i = 0; i < cmsize; i++)
{
if (i < 32)
red[i] = 0;
else if (i < 64)
red[i] = SCALE(36);
else if (i < 96)
red[i] = SCALE(73);
else if (i < 128)
red[i] = SCALE(109);
else if (i < 160)
red[i] = SCALE(146);
else if (i < 192)
red[i] = SCALE(182);
else if (i < 224)
red[i] = SCALE(219);
else if (i < 256)
red[i] = SCALE(255);
if ((i % 32) < 4)
green[i] = 0;
else if (i < 8)
green[i] = SCALE(36);
else if ((i % 32) < 12)
green[i] = SCALE(73);
else if ((i % 32) < 16)
green[i] = SCALE(109);
else if ((i % 32) < 20)
green[i] = SCALE(146);
else if ((i % 32) < 24)
green[i] = SCALE(182);
else if ((i % 32) < 28)
green[i] = SCALE(219);
else if ((i % 32) < 32)
green[i] = SCALE(255);
if ((i % 32) < 4)
green[i] = 0;
else if (i < 8)
green[i] = SCALE(36);
else if ((i % 32) < 12)
green[i] = SCALE(73);
else if ((i % 32) < 16)
green[i] = SCALE(109);
else if ((i % 32) < 20)
green[i] = SCALE(146);
else if ((i % 32) < 24)
green[i] = SCALE(182);
else if ((i % 32) < 28)
green[i] = SCALE(219);
else if ((i % 32) < 32)
green[i] = SCALE(255);
if ((i % 4) == 0)
blue[i] = SCALE(0);
else if ((i % 4) == 1)
blue[i] = SCALE(85);
else if ((i % 4) == 2)
blue[i] = SCALE(170);
else if ((i % 4) == 3)
blue[i] = SCALE(255);
}
break;
case 4:
red[0] = SCALE(255);
green[0] = 0;
blue[0] = 0;
if ((i % 4) == 0)
blue[i] = SCALE(0);
else if ((i % 4) == 1)
blue[i] = SCALE(85);
else if ((i % 4) == 2)
blue[i] = SCALE(170);
else if ((i % 4) == 3)
blue[i] = SCALE(255);
}
break;
case 4:
red[0] = SCALE(255);
green[0] = 0;
blue[0] = 0;
red[1] = 0;
green[1] = SCALE(255);
blue[1] = 0;
red[1] = 0;
green[1] = SCALE(255);
blue[1] = 0;
red[2] = 0;
green[2] = 0;
blue[2] = SCALE(255);
red[2] = 0;
green[2] = 0;
blue[2] = SCALE(255);
red[3] = SCALE(255);
green[3] = SCALE(255);
blue[3] = SCALE(255);
red[3] = SCALE(255);
green[3] = SCALE(255);
blue[3] = SCALE(255);
red[4] = 0;
green[4] = SCALE(255);
blue[4] = SCALE(255);
red[4] = 0;
green[4] = SCALE(255);
blue[4] = SCALE(255);
red[5] = SCALE(255);
green[5] = 0;
blue[5] = SCALE(255);
red[5] = SCALE(255);
green[5] = 0;
blue[5] = SCALE(255);
red[6] = SCALE(255);
green[6] = SCALE(255);
blue[6] = 0;
red[6] = SCALE(255);
green[6] = SCALE(255);
blue[6] = 0;
red[7] = 0;
green[7] = 0;
blue[7] = 0;
red[7] = 0;
green[7] = 0;
blue[7] = 0;
red[8] = SCALE(176);
green[8] = SCALE(224);
blue[8] = SCALE(230);
red[9] = SCALE(100);
green[9] = SCALE(149);
blue[9] = SCALE(237);
red[10] = SCALE(46);
green[10] = SCALE(139);
blue[10] = SCALE(87);
red[11] = SCALE(160);
green[11] = SCALE(82);
blue[11] = SCALE(45);
red[12] = SCALE(238);
green[12] = SCALE(130);
blue[12] = SCALE(238);
red[13] = SCALE(176);
green[13] = SCALE(48);
blue[13] = SCALE(96);
red[14] = SCALE(50);
green[14] = SCALE(205);
blue[14] = SCALE(50);
red[15] = SCALE(240);
green[15] = SCALE(152);
blue[15] = SCALE(35);
break;
case 2:
red[0] = SCALE(255);
green[0] = 0;
blue[0] = 0;
red[8] = SCALE(176);
green[8] = SCALE(224);
blue[8] = SCALE(230);
red[9] = SCALE(100);
green[9] = SCALE(149);
blue[9] = SCALE(237);
red[10] = SCALE(46);
green[10] = SCALE(139);
blue[10] = SCALE(87);
red[11] = SCALE(160);
green[11] = SCALE(82);
blue[11] = SCALE(45);
red[12] = SCALE(238);
green[12] = SCALE(130);
blue[12] = SCALE(238);
red[13] = SCALE(176);
green[13] = SCALE(48);
blue[13] = SCALE(96);
red[14] = SCALE(50);
green[14] = SCALE(205);
blue[14] = SCALE(50);
red[15] = SCALE(240);
green[15] = SCALE(152);
blue[15] = SCALE(35);
break;
case 2:
red[0] = SCALE(255);
green[0] = 0;
blue[0] = 0;
red[1] = 0;
green[1] = SCALE(255);
blue[1] = 0;
red[1] = 0;
green[1] = SCALE(255);
blue[1] = 0;
red[2] = 0;
green[2] = 0;
blue[2] = SCALE(255);
red[3] = SCALE(255);
green[3] = SCALE(255);
blue[3] = SCALE(255);
break;
case 1:
red[0] = 0;
green[0] = 0;
blue[0] = 0;
red[2] = 0;
green[2] = 0;
blue[2] = SCALE(255);
red[3] = SCALE(255);
green[3] = SCALE(255);
blue[3] = SCALE(255);
break;
case 1:
red[0] = 0;
green[0] = 0;
blue[0] = 0;
red[1] = SCALE(255);
green[1] = SCALE(255);
blue[1] = SCALE(255);
break;
red[1] = SCALE(255);
green[1] = SCALE(255);
blue[1] = SCALE(255);
break;
}
if ((tif = TIFFOpen(argv[3], "w")) == NULL) {
if ((tif = TIFFOpen(argv[3], "w")) == NULL)
{
fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]);
free(red);free(green);free(blue);
free(red);
free(green);
free(blue);
return 0;
}
@@ -232,31 +241,34 @@ int main(int argc, char **argv)
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
scan_line = (unsigned char *) malloc(WIDTH / (8 / bits_per_pixel));
scan_line = (unsigned char *)malloc(WIDTH / (8 / bits_per_pixel));
for (i = 0; i < HEIGHT; i++) {
for (j = 0, k = 0; j < WIDTH;) {
for (i = 0; i < HEIGHT; i++)
{
for (j = 0, k = 0; j < WIDTH;)
{
cmap_index = (j / chunk_size) + ((i / chunk_size) * nchunks);
switch (bits_per_pixel) {
case 8:
scan_line[k++] = cmap_index;
j++;
break;
case 4:
scan_line[k++] = (cmap_index << 4) + cmap_index;
j += 2;
break;
case 2:
scan_line[k++] = (cmap_index << 6) + (cmap_index << 4)
+ (cmap_index << 2) + cmap_index;
j += 4;
break;
case 1:
scan_line[k++] =
((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff;
j += 8;
break;
switch (bits_per_pixel)
{
case 8:
scan_line[k++] = cmap_index;
j++;
break;
case 4:
scan_line[k++] = (cmap_index << 4) + cmap_index;
j += 2;
break;
case 2:
scan_line[k++] = (cmap_index << 6) + (cmap_index << 4) +
(cmap_index << 2) + cmap_index;
j += 4;
break;
case 1:
scan_line[k++] =
((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff;
j += 8;
break;
}
}
TIFFWriteScanline(tif, scan_line, i, 0);
@@ -267,9 +279,9 @@ int main(int argc, char **argv)
return 0;
}
void
Usage()
void Usage()
{
fprintf(stderr, "Usage: %s -depth (8 | 4 | 2 | 1) tiff-image\n", programName);
fprintf(stderr, "Usage: %s -depth (8 | 4 | 2 | 1) tiff-image\n",
programName);
exit(0);
}

View File

@@ -29,57 +29,66 @@
#include "tiffio.h"
#define ROUND(x) (uint16_t) ((x) + 0.5)
#define CMSIZE 256
#define WIDTH 525
#define HEIGHT 512
#define TIFF_GAMMA 2.2
#define ROUND(x) (uint16_t)((x) + 0.5)
#define CMSIZE 256
#define WIDTH 525
#define HEIGHT 512
#define TIFF_GAMMA 2.2
void Usage();
char * programName;
void Usage();
char *programName;
int main(int argc, char **argv)
{
char * input_file = NULL;
double image_gamma = TIFF_GAMMA;
int i, j;
TIFF * tif;
unsigned char * scan_line;
uint16_t red[CMSIZE], green[CMSIZE], blue[CMSIZE];
float refblackwhite[2*3];
char *input_file = NULL;
double image_gamma = TIFF_GAMMA;
int i, j;
TIFF *tif;
unsigned char *scan_line;
uint16_t red[CMSIZE], green[CMSIZE], blue[CMSIZE];
float refblackwhite[2 * 3];
programName = argv[0];
switch (argc) {
case 2:
image_gamma = TIFF_GAMMA;
input_file = argv[1];
break;
case 4:
if (!strcmp(argv[1], "-gamma")) {
image_gamma = atof(argv[2]);
input_file = argv[3];
} else
switch (argc)
{
case 2:
image_gamma = TIFF_GAMMA;
input_file = argv[1];
break;
case 4:
if (!strcmp(argv[1], "-gamma"))
{
image_gamma = atof(argv[2]);
input_file = argv[3];
}
else
Usage();
break;
default:
Usage();
break;
default:
Usage();
}
for (i = 0; i < CMSIZE; i++) {
for (i = 0; i < CMSIZE; i++)
{
if (i == 0)
red[i] = green[i] = blue[i] = 0;
else {
else
{
red[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
green[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
blue[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
}
}
refblackwhite[0] = 0.0; refblackwhite[1] = 255.0;
refblackwhite[2] = 0.0; refblackwhite[3] = 255.0;
refblackwhite[4] = 0.0; refblackwhite[5] = 255.0;
refblackwhite[0] = 0.0;
refblackwhite[1] = 255.0;
refblackwhite[2] = 0.0;
refblackwhite[3] = 255.0;
refblackwhite[4] = 0.0;
refblackwhite[5] = 255.0;
if ((tif = TIFFOpen(input_file, "w")) == NULL) {
if ((tif = TIFFOpen(input_file, "w")) == NULL)
{
fprintf(stderr, "can't open %s as a TIFF file\n", input_file);
exit(0);
}
@@ -100,81 +109,97 @@ int main(int argc, char **argv)
TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refblackwhite);
TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, red, green, blue);
scan_line = (unsigned char *) malloc(WIDTH * 3);
scan_line = (unsigned char *)malloc(WIDTH * 3);
for (i = 0; i < 255; i++) {
for (j = 0; j < 75; j++) {
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255 - i;
for (i = 0; i < 255; i++)
{
for (j = 0; j < 75; j++)
{
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255 - i;
}
for (j = 75; j < 150; j++) {
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255 - i;
for (j = 75; j < 150; j++)
{
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255 - i;
}
for (j = 150; j < 225; j++) {
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255;
for (j = 150; j < 225; j++)
{
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255;
}
for (j = 225; j < 300; j++) {
scan_line[j * 3] = (i - 1) / 2;
scan_line[(j * 3) + 1] = (i - 1) / 2;
scan_line[(j * 3) + 2] = (i - 1) / 2;
for (j = 225; j < 300; j++)
{
scan_line[j * 3] = (i - 1) / 2;
scan_line[(j * 3) + 1] = (i - 1) / 2;
scan_line[(j * 3) + 2] = (i - 1) / 2;
}
for (j = 300; j < 375; j++) {
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255;
for (j = 300; j < 375; j++)
{
scan_line[j * 3] = 255 - i;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255;
}
for (j = 375; j < 450; j++) {
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255;
for (j = 375; j < 450; j++)
{
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255 - i;
scan_line[(j * 3) + 2] = 255;
}
for (j = 450; j < 525; j++) {
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255 - i;
for (j = 450; j < 525; j++)
{
scan_line[j * 3] = 255;
scan_line[(j * 3) + 1] = 255;
scan_line[(j * 3) + 2] = 255 - i;
}
TIFFWriteScanline(tif, scan_line, i, 0);
}
for (i = 255; i < 512; i++) {
for (j = 0; j < 75; j++) {
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = 0;
for (i = 255; i < 512; i++)
{
for (j = 0; j < 75; j++)
{
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = 0;
}
for (j = 75; j < 150; j++) {
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = 0;
for (j = 75; j < 150; j++)
{
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = 0;
}
for (j = 150; j < 225; j++) {
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = i;
for (j = 150; j < 225; j++)
{
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = i;
}
for (j = 225; j < 300; j++) {
scan_line[j * 3] = (i - 1) / 2;
scan_line[(j * 3) + 1] = (i - 1) / 2;
scan_line[(j * 3) + 2] = (i - 1) / 2;
for (j = 225; j < 300; j++)
{
scan_line[j * 3] = (i - 1) / 2;
scan_line[(j * 3) + 1] = (i - 1) / 2;
scan_line[(j * 3) + 2] = (i - 1) / 2;
}
for (j = 300; j < 375; j++) {
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = i;
for (j = 300; j < 375; j++)
{
scan_line[j * 3] = 0;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = i;
}
for (j = 375; j < 450; j++) {
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = i;
for (j = 375; j < 450; j++)
{
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = 0;
scan_line[(j * 3) + 2] = i;
}
for (j = 450; j < 525; j++) {
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = 0;
for (j = 450; j < 525; j++)
{
scan_line[j * 3] = i;
scan_line[(j * 3) + 1] = i;
scan_line[(j * 3) + 2] = 0;
}
TIFFWriteScanline(tif, scan_line, i, 0);
}
@@ -184,8 +209,7 @@ int main(int argc, char **argv)
exit(0);
}
void
Usage()
void Usage()
{
fprintf(stderr, "Usage: %s -gamma gamma tiff-image\n", programName);
exit(0);

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
#define xtifficon_width 32
#define xtifficon_height 32
static char xtifficon_bits[] = {
0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x7e, 0xc0, 0xfc, 0x03, 0x7e, 0x60,
0xf8, 0x07, 0x06, 0x30, 0xf8, 0x07, 0x1e, 0x18, 0xf0, 0x0f, 0x1e, 0x0c,
0xe0, 0x1f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x03,
0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00,
0x00, 0xfe, 0x31, 0x7e, 0x7e, 0xfc, 0x33, 0x7e, 0x7e, 0xf8, 0x1b, 0x06,
0x18, 0xf0, 0x0d, 0x1e, 0x18, 0xf0, 0x0e, 0x1e, 0x18, 0x60, 0x1f, 0x06,
0x18, 0xb0, 0x3f, 0x06, 0x18, 0x98, 0x7f, 0x06, 0x18, 0x98, 0x7f, 0x00,
0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x63, 0xfc, 0x03,
0x80, 0x61, 0xfc, 0x03, 0xc0, 0x60, 0xf8, 0x07, 0xc0, 0x60, 0xf0, 0x0f,
0x60, 0x60, 0xe0, 0x1f, 0x30, 0x60, 0xe0, 0x1f, 0x18, 0x60, 0xc0, 0x3f,
0x0c, 0x60, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff};
0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x7e, 0xc0, 0xfc, 0x03, 0x7e, 0x60,
0xf8, 0x07, 0x06, 0x30, 0xf8, 0x07, 0x1e, 0x18, 0xf0, 0x0f, 0x1e, 0x0c,
0xe0, 0x1f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x03,
0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00,
0x00, 0xfe, 0x31, 0x7e, 0x7e, 0xfc, 0x33, 0x7e, 0x7e, 0xf8, 0x1b, 0x06,
0x18, 0xf0, 0x0d, 0x1e, 0x18, 0xf0, 0x0e, 0x1e, 0x18, 0x60, 0x1f, 0x06,
0x18, 0xb0, 0x3f, 0x06, 0x18, 0x98, 0x7f, 0x06, 0x18, 0x98, 0x7f, 0x00,
0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x63, 0xfc, 0x03,
0x80, 0x61, 0xfc, 0x03, 0xc0, 0x60, 0xf8, 0x07, 0xc0, 0x60, 0xf0, 0x0f,
0x60, 0x60, 0xe0, 0x1f, 0x30, 0x60, 0xe0, 0x1f, 0x18, 0x60, 0xc0, 0x3f,
0x0c, 0x60, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff};

File diff suppressed because it is too large Load Diff

View File

@@ -5,11 +5,11 @@
- as if it were a file.
- mfs_ stands for memory file system.
- Author : Mike Johnson - Banctec AB 03/07/96
-
-
--------------------------------------------------------------------------------
*/
/*
/*
Copyright (c) 1996 Mike Johnson
Copyright (c) 1996 BancTec AB
@@ -21,29 +21,28 @@ all copies of the software and related documentation, and (ii) the names of
Mike Johnson and BancTec may not be used in any advertising or
publicity relating to the software.
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.
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 MIKE JOHNSON OR BANCTEC 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
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.
*/
/*
--------------------------------------------------------------------------------
- Includes
--------------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
--------------------------------------------------------------------------------
@@ -51,9 +50,9 @@ OF THIS SOFTWARE.
--------------------------------------------------------------------------------
*/
#define MAX_BUFFS 20
#define FALSE 0
#define TRUE 1
#define MAX_BUFFS 20
#define FALSE 0
#define TRUE 1
/*
--------------------------------------------------------------------------------
@@ -61,31 +60,30 @@ OF THIS SOFTWARE.
--------------------------------------------------------------------------------
*/
static char *buf[MAX_BUFFS]; /* Memory for each open buf */
static long buf_off[MAX_BUFFS]; /* File pointer for each buf */
static long buf_size[MAX_BUFFS]; /* Count of bytes allocated for each buf */
static long fds[MAX_BUFFS]; /* File descriptor status */
static int buf_mode[MAX_BUFFS]; /* Mode of buffer (r, w, a) */
static char *buf[MAX_BUFFS]; /* Memory for each open buf */
static long buf_off[MAX_BUFFS]; /* File pointer for each buf */
static long buf_size[MAX_BUFFS]; /* Count of bytes allocated for each buf */
static long fds[MAX_BUFFS]; /* File descriptor status */
static int buf_mode[MAX_BUFFS]; /* Mode of buffer (r, w, a) */
static int library_init_done = FALSE;
/*
--------------------------------------------------------------------------------
- Function prototypes
--------------------------------------------------------------------------------
*/
int mfs_open (void *ptr, int size, char *mode);
int mfs_lseek (int fd, int offset, int whence);
int mfs_read (int fd, void *buf, int size);
int mfs_write (int fd, void *buf, int size);
int mfs_size (int fd);
int mfs_map (int fd, char **addr, size_t *len);
int mfs_unmap (int fd);
int mfs_close (int fd);
static int extend_mem_file (int fd, int size);
static void mem_init ();
int mfs_open(void *ptr, int size, char *mode);
int mfs_lseek(int fd, int offset, int whence);
int mfs_read(int fd, void *buf, int size);
int mfs_write(int fd, void *buf, int size);
int mfs_size(int fd);
int mfs_map(int fd, char **addr, size_t *len);
int mfs_unmap(int fd);
int mfs_close(int fd);
static int extend_mem_file(int fd, int size);
static void mem_init();
/*
--------------------------------------------------------------------------------
@@ -97,7 +95,7 @@ static void mem_init ();
--------------------------------------------------------------------------------
- Function : mfs_open ()
-
- Arguments : Pointer to allocated buffer, initial size of buffer,
- Arguments : Pointer to allocated buffer, initial size of buffer,
- mode spec (r, w, a)
-
- Returns : File descriptor or -1 if error.
@@ -108,22 +106,22 @@ static void mem_init ();
- back to TIFFClientOpen and used as if it was a disk
- based fd.
- If the call is for mode 'w' then pass (void *)NULL as
- the buffer and zero size and the library will
- the buffer and zero size and the library will
- allocate memory for you.
- If the mode is append then pass (void *)NULL and size
- zero or with a valid address.
-
-
--------------------------------------------------------------------------------
*/
int mfs_open (void *buffer, int size, char *mode)
int mfs_open(void *buffer, int size, char *mode)
{
int ret, i;
void *tmp;
if (library_init_done == FALSE)
{
mem_init ();
mem_init();
library_init_done = TRUE;
}
@@ -140,7 +138,7 @@ int mfs_open (void *buffer, int size, char *mode)
}
}
if (i == MAX_BUFFS) /* No more free descriptors */
if (i == MAX_BUFFS) /* No more free descriptors */
{
ret = -1;
errno = EMFILE;
@@ -171,7 +169,7 @@ int mfs_open (void *buffer, int size, char *mode)
else
{
tmp = malloc (0); /* Get a pointer */
tmp = malloc(0); /* Get a pointer */
if (tmp == (void *)NULL)
{
ret = -1;
@@ -187,9 +185,9 @@ int mfs_open (void *buffer, int size, char *mode)
}
else if (ret >= 0 && *mode == 'a')
{
if (buffer == (void *) NULL) /* Create space for client */
if (buffer == (void *)NULL) /* Create space for client */
{
tmp = malloc (0); /* Get a pointer */
tmp = malloc(0); /* Get a pointer */
if (tmp == (void *)NULL)
{
ret = -1;
@@ -202,14 +200,14 @@ int mfs_open (void *buffer, int size, char *mode)
buf_off[ret] = 0;
}
}
else /* Client has file read in already */
else /* Client has file read in already */
{
buf[ret] = (char *)buffer;
buf_size[ret] = size;
buf_off[ret] = 0;
}
}
else /* Some other invalid combination of parameters */
else /* Some other invalid combination of parameters */
{
ret = -1;
errno = EINVAL;
@@ -235,16 +233,16 @@ int mfs_open (void *buffer, int size, char *mode)
- Description : Does the same as lseek (2) except on a memory based file.
- Note: the memory area will be extended if the caller
- attempts to seek past the current end of file (memory).
-
-
--------------------------------------------------------------------------------
*/
int mfs_lseek (int fd, int offset, int whence)
int mfs_lseek(int fd, int offset, int whence)
{
int ret;
long test_off;
if (fds[fd] == -1) /* Not open */
if (fds[fd] == -1) /* Not open */
{
ret = -1;
errno = EBADF;
@@ -260,7 +258,7 @@ int mfs_lseek (int fd, int offset, int whence)
{
case SEEK_SET:
if (offset > buf_size[fd])
extend_mem_file (fd, offset);
extend_mem_file(fd, offset);
buf_off[fd] = offset;
ret = offset;
break;
@@ -276,7 +274,7 @@ int mfs_lseek (int fd, int offset, int whence)
else
{
if (test_off > buf_size[fd])
extend_mem_file (fd, test_off);
extend_mem_file(fd, test_off);
buf_off[fd] = test_off;
ret = test_off;
}
@@ -293,7 +291,7 @@ int mfs_lseek (int fd, int offset, int whence)
else
{
if (test_off > buf_size[fd])
extend_mem_file (fd, test_off);
extend_mem_file(fd, test_off);
buf_off[fd] = test_off;
ret = test_off;
}
@@ -307,7 +305,7 @@ int mfs_lseek (int fd, int offset, int whence)
}
return (ret);
}
}
/*
--------------------------------------------------------------------------------
@@ -320,11 +318,11 @@ int mfs_lseek (int fd, int offset, int whence)
- Description : Does the same as read (2) except on a memory based file.
- Note: An attempt to read past the end of memory currently
- allocated to the file will return 0 (End Of File)
-
-
--------------------------------------------------------------------------------
*/
int mfs_read (int fd, void *clnt_buf, int size)
int mfs_read(int fd, void *clnt_buf, int size)
{
int ret;
@@ -337,11 +335,11 @@ int mfs_read (int fd, void *clnt_buf, int size)
}
else if (buf_off[fd] + size > buf_size[fd])
{
ret = 0; /* EOF */
ret = 0; /* EOF */
}
else
{
memcpy (clnt_buf, (void *) (buf[fd] + buf_off[fd]), size);
memcpy(clnt_buf, (void *)(buf[fd] + buf_off[fd]), size);
buf_off[fd] = buf_off[fd] + size;
ret = size;
}
@@ -360,11 +358,11 @@ int mfs_read (int fd, void *clnt_buf, int size)
- Description : Does the same as write (2) except on a memory based file.
- Note: the memory area will be extended if the caller
- attempts to write past the current end of file (memory).
-
-
--------------------------------------------------------------------------------
*/
int mfs_write (int fd, void *clnt_buf, int size)
int mfs_write(int fd, void *clnt_buf, int size)
{
int ret;
@@ -380,12 +378,12 @@ int mfs_write (int fd, void *clnt_buf, int size)
/* Write */
if (buf_off[fd] + size > buf_size[fd])
{
extend_mem_file (fd, buf_off[fd] + size);
{
extend_mem_file(fd, buf_off[fd] + size);
buf_size[fd] = (buf_off[fd] + size);
}
memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size);
memcpy((buf[fd] + buf_off[fd]), clnt_buf, size);
buf_off[fd] = buf_off[fd] + size;
ret = size;
@@ -397,10 +395,10 @@ int mfs_write (int fd, void *clnt_buf, int size)
if (buf_off[fd] != buf_size[fd])
buf_off[fd] = buf_size[fd];
extend_mem_file (fd, buf_off[fd] + size);
extend_mem_file(fd, buf_off[fd] + size);
buf_size[fd] += size;
memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size);
memcpy((buf[fd] + buf_off[fd]), clnt_buf, size);
buf_off[fd] = buf_off[fd] + size;
ret = size;
@@ -418,15 +416,15 @@ int mfs_write (int fd, void *clnt_buf, int size)
- Returns : integer file size
-
- Description : This function returns the current size of the file in bytes.
-
-
--------------------------------------------------------------------------------
*/
int mfs_size (int fd)
int mfs_size(int fd)
{
int ret;
if (fds[fd] == -1) /* Not open */
if (fds[fd] == -1) /* Not open */
{
ret = -1;
errno = EBADF;
@@ -449,15 +447,15 @@ int mfs_size (int fd)
- in memory and what size the mapped area is. It is provided
- to satisfy the MapProc function in libtiff. It pretends
- that the file has been mmap (2)ped.
-
-
--------------------------------------------------------------------------------
*/
int mfs_map (int fd, char **addr, size_t *len)
int mfs_map(int fd, char **addr, size_t *len)
{
int ret;
int ret;
if (fds[fd] == -1) /* Not open */
if (fds[fd] == -1) /* Not open */
{
ret = -1;
errno = EBADF;
@@ -482,14 +480,11 @@ int mfs_map (int fd, char **addr, size_t *len)
-
- Description : This function does nothing as the file is always
- in memory.
-
-
--------------------------------------------------------------------------------
*/
int mfs_unmap (int fd)
{
return (0);
}
int mfs_unmap(int fd) { return (0); }
/*
--------------------------------------------------------------------------------
@@ -500,15 +495,15 @@ int mfs_unmap (int fd)
- Returns : close status (succeeded or otherwise)
-
- Description : Close the open memory file. (Make fd available again.)
-
-
--------------------------------------------------------------------------------
*/
int mfs_close (int fd)
int mfs_close(int fd)
{
int ret;
int ret;
if (fds[fd] == -1) /* Not open */
if (fds[fd] == -1) /* Not open */
{
ret = -1;
errno = EBADF;
@@ -531,20 +526,20 @@ int mfs_close (int fd)
- Returns : 0 - All OK, -1 - realloc () failed.
-
- Description : Increase the amount of memory allocated to a file.
-
-
--------------------------------------------------------------------------------
*/
static int extend_mem_file (int fd, int size)
static int extend_mem_file(int fd, int size)
{
void *new_mem;
int ret;
if ((new_mem = realloc (buf[fd], size)) == (void *) NULL)
if ((new_mem = realloc(buf[fd], size)) == (void *)NULL)
ret = -1;
else
{
buf[fd] = (char *) new_mem;
buf[fd] = (char *)new_mem;
ret = 0;
}
@@ -560,11 +555,11 @@ static int extend_mem_file (int fd, int size)
- Returns : void
-
- Description : Initialise the library.
-
-
--------------------------------------------------------------------------------
*/
static void mem_init ()
static void mem_init()
{
int i;

View File

@@ -28,112 +28,126 @@
#include <tiffio.h>
#include <tiffio.hxx>
/* stolen from tiffiop.h, which is a private header so we can't just include it */
/* stolen from tiffiop.h, which is a private header so we can't just include it
*/
/* safe multiply returns either the multiplied value or 0 if it overflowed */
#define __TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
#define __TIFFSafeMultiply(t, v, m) \
((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \
? (t)((v) * (m)) \
: (t)0)
const uint64_t MAX_SIZE = 500000000;
extern "C" void handle_error(const char *unused, const char *unused2, va_list unused3) {
extern "C" void handle_error(const char *unused, const char *unused2,
va_list unused3)
{
return;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
#ifndef STANDALONE
TIFFSetErrorHandler(handle_error);
TIFFSetWarningHandler(handle_error);
TIFFSetErrorHandler(handle_error);
TIFFSetWarningHandler(handle_error);
#endif
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
// libjpeg-turbo has issues with MSAN and SIMD code
// See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7547
// and https://github.com/libjpeg-turbo/libjpeg-turbo/pull/365
setenv("JSIMD_FORCENONE" ,"1", 1);
# endif
#if __has_feature(memory_sanitizer)
// libjpeg-turbo has issues with MSAN and SIMD code
// See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7547
// and https://github.com/libjpeg-turbo/libjpeg-turbo/pull/365
setenv("JSIMD_FORCENONE", "1", 1);
#endif
std::istringstream s(std::string(Data,Data+Size));
TIFF* tif = TIFFStreamOpen("MemTIFF", &s);
if (!tif) {
return 0;
}
uint32_t w, h;
uint32_t* raster;
#endif
std::istringstream s(std::string(Data, Data + Size));
TIFF *tif = TIFFStreamOpen("MemTIFF", &s);
if (!tif)
{
return 0;
}
uint32_t w, h;
uint32_t *raster;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
/* don't continue if file size is ludicrous */
if (TIFFTileSize64(tif) > MAX_SIZE) {
TIFFClose(tif);
return 0;
}
uint64_t bufsize = TIFFTileSize64(tif);
/* don't continue if the buffer size greater than the max allowed by the fuzzer */
if (bufsize > MAX_SIZE || bufsize == 0) {
TIFFClose(tif);
return 0;
}
/* another hack to work around an OOM in tif_fax3.c */
uint32_t tilewidth = 0;
uint32_t imagewidth = 0;
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tilewidth);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
tilewidth = __TIFFSafeMultiply(uint32_t, tilewidth, 2);
imagewidth = __TIFFSafeMultiply(uint32_t, imagewidth, 2);
if (tilewidth * 2 > MAX_SIZE || imagewidth * 2 > MAX_SIZE || tilewidth == 0 || imagewidth == 0) {
TIFFClose(tif);
return 0;
}
uint32_t size = __TIFFSafeMultiply(uint32_t, w, h);
if (size > MAX_SIZE || size == 0) {
TIFFClose(tif);
return 0;
}
raster = (uint32_t*) _TIFFmalloc(size * sizeof (uint32_t));
if (raster != NULL) {
TIFFReadRGBAImage(tif, w, h, raster, 0);
_TIFFfree(raster);
}
TIFFClose(tif);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
/* don't continue if file size is ludicrous */
if (TIFFTileSize64(tif) > MAX_SIZE)
{
TIFFClose(tif);
return 0;
}
uint64_t bufsize = TIFFTileSize64(tif);
/* don't continue if the buffer size greater than the max allowed by the
* fuzzer */
if (bufsize > MAX_SIZE || bufsize == 0)
{
TIFFClose(tif);
return 0;
}
/* another hack to work around an OOM in tif_fax3.c */
uint32_t tilewidth = 0;
uint32_t imagewidth = 0;
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tilewidth);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
tilewidth = __TIFFSafeMultiply(uint32_t, tilewidth, 2);
imagewidth = __TIFFSafeMultiply(uint32_t, imagewidth, 2);
if (tilewidth * 2 > MAX_SIZE || imagewidth * 2 > MAX_SIZE ||
tilewidth == 0 || imagewidth == 0)
{
TIFFClose(tif);
return 0;
}
uint32_t size = __TIFFSafeMultiply(uint32_t, w, h);
if (size > MAX_SIZE || size == 0)
{
TIFFClose(tif);
return 0;
}
raster = (uint32_t *)_TIFFmalloc(size * sizeof(uint32_t));
if (raster != NULL)
{
TIFFReadRGBAImage(tif, w, h, raster, 0);
_TIFFfree(raster);
}
TIFFClose(tif);
return 0;
return 0;
}
#ifdef STANDALONE
template<class T> static void CPL_IGNORE_RET_VAL(T) {}
template <class T> static void CPL_IGNORE_RET_VAL(T) {}
static void Usage(int, char* argv[])
static void Usage(int, char *argv[])
{
fprintf(stderr, "%s [--help] [-repeat N] filename.\n", argv[0]);
exit(1);
}
int main(int argc, char* argv[])
int main(int argc, char *argv[])
{
int nRet = 0;
void* buf = NULL;
void *buf = NULL;
int nLen = 0;
int nLoops = 1;
const char* pszFilename = NULL;
const char *pszFilename = NULL;
for(int i = 1; i < argc; i++ )
for (int i = 1; i < argc; i++)
{
if( i + 1 < argc && strcmp(argv[i], "-repeat") == 0 )
if (i + 1 < argc && strcmp(argv[i], "-repeat") == 0)
{
nLoops = atoi(argv[i+1]);
nLoops = atoi(argv[i + 1]);
i++;
}
else if( strcmp(argv[i], "-dummy") == 0 )
else if (strcmp(argv[i], "-dummy") == 0)
{
uint8_t dummy = ' ';
return LLVMFuzzerTestOneInput(&dummy, 1);
}
else if( strcmp(argv[i], "--help") == 0 )
else if (strcmp(argv[i], "--help") == 0)
{
Usage(argc, argv);
}
else if( argv[i][0] == '-' )
else if (argv[i][0] == '-')
{
fprintf(stderr, "Unrecognized option: %s", argv[i]);
Usage(argc, argv);
@@ -143,13 +157,13 @@ int main(int argc, char* argv[])
pszFilename = argv[i];
}
}
if( pszFilename == nullptr )
if (pszFilename == nullptr)
{
fprintf(stderr, "No filename specified\n");
Usage(argc, argv);
}
FILE* f = fopen(pszFilename, "rb");
if( !f )
FILE *f = fopen(pszFilename, "rb");
if (!f)
{
fprintf(stderr, "%s does not exist.\n", pszFilename);
exit(1);
@@ -158,7 +172,7 @@ int main(int argc, char* argv[])
nLen = (int)ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(nLen);
if( !buf )
if (!buf)
{
fprintf(stderr, "malloc failed.\n");
fclose(f);
@@ -166,10 +180,10 @@ int main(int argc, char* argv[])
}
CPL_IGNORE_RET_VAL(fread(buf, nLen, 1, f));
fclose(f);
for( int i = 0; i < nLoops; i++ )
for (int i = 0; i < nLoops; i++)
{
nRet = LLVMFuzzerTestOneInput(static_cast<const uint8_t*>(buf), nLen);
if( nRet != 0 )
nRet = LLVMFuzzerTestOneInput(static_cast<const uint8_t *>(buf), nLen);
if (nRet != 0)
break;
}
free(buf);

View File

@@ -2,23 +2,23 @@
* Copyright (c) 1991-1996 Sam Leffler
* Copyright (c) 1991-1996 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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
* 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.
*/
@@ -34,43 +34,41 @@
* ignore those details. The calling program does, however, need to be
* conscious of the type of the pixel data that it is receiving.
*
* For reasons of efficiency, the callback function actually gets called for
* For reasons of efficiency, the callback function actually gets called for
* "blocks" of pixels rather than for individual pixels. The format of the
* callback arguments is given below.
*
* This code was taken from TIFFReadRGBAImage() in tif_getimage.c of the original
* TIFF distribution, and simplified and generalized to provide this general
* iteration capability. Those routines could certainly be re-implemented in terms
* of a TIFFImageIter if desired.
* This code was taken from TIFFReadRGBAImage() in tif_getimage.c of the
* original TIFF distribution, and simplified and generalized to provide this
* general iteration capability. Those routines could certainly be
* re-implemented in terms of a TIFFImageIter if desired.
*
*/
#include "tiffiop.h"
#include "tif_imageiter.h"
#include "tiffiop.h"
#include <assert.h>
#include <stdio.h>
static int gtTileContig(TIFFImageIter*, void *udata, uint32_t, uint32_t);
static int gtTileSeparate(TIFFImageIter*, void *udata, uint32_t, uint32_t);
static int gtStripContig(TIFFImageIter*, void *udata, uint32_t, uint32_t);
static int gtStripSeparate(TIFFImageIter*, void *udata, uint32_t, uint32_t);
static int gtTileContig(TIFFImageIter *, void *udata, uint32_t, uint32_t);
static int gtTileSeparate(TIFFImageIter *, void *udata, uint32_t, uint32_t);
static int gtStripContig(TIFFImageIter *, void *udata, uint32_t, uint32_t);
static int gtStripSeparate(TIFFImageIter *, void *udata, uint32_t, uint32_t);
static const char photoTag[] = "PhotometricInterpretation";
static const char photoTag[] = "PhotometricInterpretation";
static int
isCCITTCompression(TIFF* tif)
static int isCCITTCompression(TIFF *tif)
{
uint16_t compress;
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
return (compress == COMPRESSION_CCITTFAX3 ||
compress == COMPRESSION_CCITTFAX4 ||
compress == COMPRESSION_CCITTRLE ||
compress == COMPRESSION_CCITTRLEW);
compress == COMPRESSION_CCITTFAX4 ||
compress == COMPRESSION_CCITTRLE ||
compress == COMPRESSION_CCITTRLEW);
}
int
TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024])
int TIFFImageIterBegin(TIFFImageIter *img, TIFF *tif, int stop, char emsg[1024])
{
uint16_t* sampleinfo;
uint16_t *sampleinfo;
uint16_t extrasamples;
uint16_t planarconfig;
int colorchannels;
@@ -80,217 +78,244 @@ TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024])
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
img->alpha = 0;
TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
&extrasamples, &sampleinfo);
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples,
&sampleinfo);
if (extrasamples == 1)
switch (sampleinfo[0]) {
case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
img->alpha = sampleinfo[0];
break;
}
switch (sampleinfo[0])
{
case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
img->alpha = sampleinfo[0];
break;
}
colorchannels = img->samplesperpixel - extrasamples;
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
switch (colorchannels) {
case 1:
if (isCCITTCompression(tif))
img->photometric = PHOTOMETRIC_MINISWHITE;
else
img->photometric = PHOTOMETRIC_MINISBLACK;
break;
case 3:
img->photometric = PHOTOMETRIC_RGB;
break;
default:
sprintf(emsg, "Missing needed %s tag", photoTag);
return (0);
}
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
{
switch (colorchannels)
{
case 1:
if (isCCITTCompression(tif))
img->photometric = PHOTOMETRIC_MINISWHITE;
else
img->photometric = PHOTOMETRIC_MINISBLACK;
break;
case 3:
img->photometric = PHOTOMETRIC_RGB;
break;
default:
sprintf(emsg, "Missing needed %s tag", photoTag);
return (0);
}
}
switch (img->photometric) {
case PHOTOMETRIC_PALETTE:
if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
&img->redcmap, &img->greencmap, &img->bluecmap)) {
TIFFErrorExtR(tif, TIFFFileName(tif), "Missing required \"Colormap\" tag");
return (0);
}
/* fall through... */
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
/* This should work now so skip the check - BSR
if (planarconfig == PLANARCONFIG_CONTIG && img->samplesperpixel != 1) {
sprintf(emsg,
"Sorry, can not handle contiguous data with %s=%d, and %s=%d",
photoTag, img->photometric,
"Samples/pixel", img->samplesperpixel);
return (0);
}
*/
break;
case PHOTOMETRIC_YCBCR:
if (planarconfig != PLANARCONFIG_CONTIG) {
sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
"Planarconfiguration", planarconfig);
return (0);
}
/* It would probably be nice to have a reality check here. */
{ uint16_t compress;
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
if (compress == COMPRESSION_JPEG && planarconfig == PLANARCONFIG_CONTIG) {
/* can rely on libjpeg to convert to RGB */
/* XXX should restore current state on exit */
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
img->photometric = PHOTOMETRIC_RGB;
}
}
break;
case PHOTOMETRIC_RGB:
if (colorchannels < 3) {
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
"Color channels", colorchannels);
return (0);
}
break;
case PHOTOMETRIC_SEPARATED: {
uint16_t inkset;
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
if (inkset != INKSET_CMYK) {
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
"InkSet", inkset);
return (0);
}
if (img->samplesperpixel != 4) {
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
"Samples/pixel", img->samplesperpixel);
return (0);
}
break;
}
default:
sprintf(emsg, "Sorry, can not handle image with %s=%d",
photoTag, img->photometric);
return (0);
switch (img->photometric)
{
case PHOTOMETRIC_PALETTE:
if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &img->redcmap,
&img->greencmap, &img->bluecmap))
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Missing required \"Colormap\" tag");
return (0);
}
/* fall through... */
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
/* This should work now so skip the check - BSR
if (planarconfig == PLANARCONFIG_CONTIG &&
img->samplesperpixel != 1) { sprintf(emsg, "Sorry, can not handle
contiguous data with %s=%d, and %s=%d", photoTag,
img->photometric, "Samples/pixel", img->samplesperpixel); return
(0);
}
*/
break;
case PHOTOMETRIC_YCBCR:
if (planarconfig != PLANARCONFIG_CONTIG)
{
sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
"Planarconfiguration", planarconfig);
return (0);
}
/* It would probably be nice to have a reality check here. */
{
uint16_t compress;
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
if (compress == COMPRESSION_JPEG &&
planarconfig == PLANARCONFIG_CONTIG)
{
/* can rely on libjpeg to convert to RGB */
/* XXX should restore current state on exit */
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
img->photometric = PHOTOMETRIC_RGB;
}
}
break;
case PHOTOMETRIC_RGB:
if (colorchannels < 3)
{
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
"Color channels", colorchannels);
return (0);
}
break;
case PHOTOMETRIC_SEPARATED:
{
uint16_t inkset;
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
if (inkset != INKSET_CMYK)
{
sprintf(emsg,
"Sorry, can not handle separated image with %s=%d",
"InkSet", inkset);
return (0);
}
if (img->samplesperpixel != 4)
{
sprintf(emsg,
"Sorry, can not handle separated image with %s=%d",
"Samples/pixel", img->samplesperpixel);
return (0);
}
break;
}
default:
sprintf(emsg, "Sorry, can not handle image with %s=%d", photoTag,
img->photometric);
return (0);
}
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
switch (img->orientation) {
case ORIENTATION_BOTRIGHT:
case ORIENTATION_RIGHTBOT: /* XXX */
case ORIENTATION_LEFTBOT: /* XXX */
TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
img->orientation = ORIENTATION_BOTLEFT;
/* fall through... */
case ORIENTATION_BOTLEFT:
break;
case ORIENTATION_TOPRIGHT:
case ORIENTATION_RIGHTTOP: /* XXX */
case ORIENTATION_LEFTTOP: /* XXX */
default:
TIFFWarning(TIFFFileName(tif), "using top-left orientation");
img->orientation = ORIENTATION_TOPLEFT;
/* fall through... */
case ORIENTATION_TOPLEFT:
break;
switch (img->orientation)
{
case ORIENTATION_BOTRIGHT:
case ORIENTATION_RIGHTBOT: /* XXX */
case ORIENTATION_LEFTBOT: /* XXX */
TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
img->orientation = ORIENTATION_BOTLEFT;
/* fall through... */
case ORIENTATION_BOTLEFT:
break;
case ORIENTATION_TOPRIGHT:
case ORIENTATION_RIGHTTOP: /* XXX */
case ORIENTATION_LEFTTOP: /* XXX */
default:
TIFFWarning(TIFFFileName(tif), "using top-left orientation");
img->orientation = ORIENTATION_TOPLEFT;
/* fall through... */
case ORIENTATION_TOPLEFT:
break;
}
img->isContig =
!(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
if (img->isContig) {
img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
} else {
img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
!(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
if (img->isContig)
{
img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
}
else
{
img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
}
return (1);
}
int
TIFFImageIterGet(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
int TIFFImageIterGet(TIFFImageIter *img, void *udata, uint32_t w, uint32_t h)
{
if (img->get == NULL) {
TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "No \"get\" routine setup");
return (0);
if (img->get == NULL)
{
TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
"No \"get\" routine setup");
return (0);
}
if (img->callback.any == NULL) {
TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
"No \"put\" routine setupl; probably can not handle image format");
return (0);
if (img->callback.any == NULL)
{
TIFFErrorExtR(
img->tif, TIFFFileName(img->tif),
"No \"put\" routine setupl; probably can not handle image format");
return (0);
}
return (*img->get)(img, udata, w, h);
}
TIFFImageIterEnd(TIFFImageIter* img)
{
/* Nothing to free... ? */
TIFFImageIterEnd(TIFFImageIter *img)
{ /* Nothing to free... ? */
}
/*
* Read the specified image into an ABGR-format raster.
*/
int
TIFFReadImageIter(TIFF* tif,
uint32_t rwidth, uint32_t rheight, uint8_t* raster, int stop)
int TIFFReadImageIter(TIFF *tif, uint32_t rwidth, uint32_t rheight,
uint8_t *raster, int stop)
{
char emsg[1024];
TIFFImageIter img;
int ok;
if (TIFFImageIterBegin(&img, tif, stop, emsg)) {
/* XXX verify rwidth and rheight against width and height */
ok = TIFFImageIterGet(&img, raster, rwidth, img.height);
TIFFImageIterEnd(&img);
} else {
TIFFErrorExtR(tif, TIFFFileName(tif), emsg);
ok = 0;
if (TIFFImageIterBegin(&img, tif, stop, emsg))
{
/* XXX verify rwidth and rheight against width and height */
ok = TIFFImageIterGet(&img, raster, rwidth, img.height);
TIFFImageIterEnd(&img);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif), emsg);
ok = 0;
}
return (ok);
}
/*
* Get an tile-organized image that has
* PlanarConfiguration contiguous if SamplesPerPixel > 1
* or
* SamplesPerPixel == 1
*/
static int
gtTileContig(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
*/
static int gtTileContig(TIFFImageIter *img, void *udata, uint32_t w, uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
ImageIterTileContigRoutine callback = img->callback.contig;
uint16_t orientation;
uint32_t col, row;
uint32_t tw, th;
u_char* buf;
u_char *buf;
int32_t fromskew;
uint32_t nrow;
buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif));
if (buf == 0) {
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
buf = (u_char *)_TIFFmalloc(TIFFTileSize(tif));
if (buf == 0)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
}
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
orientation = img->orientation;
for (row = 0; row < h; row += th) {
nrow = (row + th > h ? h - row : th);
for (col = 0; col < w; col += tw) {
if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && img->stoponerr)
break;
if (col + tw > w) {
/*
* Tile is clipped horizontally. Calculate
* visible portion and skewing factors.
*/
uint32_t npix = w - col;
fromskew = tw - npix;
(*callback)(img, udata, col, row, npix, nrow, fromskew, buf);
} else {
(*callback)(img, udata, col, row, tw, nrow, 0, buf);
}
}
for (row = 0; row < h; row += th)
{
nrow = (row + th > h ? h - row : th);
for (col = 0; col < w; col += tw)
{
if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && img->stoponerr)
break;
if (col + tw > w)
{
/*
* Tile is clipped horizontally. Calculate
* visible portion and skewing factors.
*/
uint32_t npix = w - col;
fromskew = tw - npix;
(*callback)(img, udata, col, row, npix, nrow, fromskew, buf);
}
else
{
(*callback)(img, udata, col, row, tw, nrow, 0, buf);
}
}
}
_TIFFfree(buf);
return (1);
@@ -301,63 +326,71 @@ gtTileContig(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
* SamplesPerPixel > 1
* PlanarConfiguration separated
* We assume that all such images are RGB.
*/
static int
gtTileSeparate(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
*/
static int gtTileSeparate(TIFFImageIter *img, void *udata, uint32_t w,
uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
ImageIterTileSeparateRoutine callback = img->callback.separate;
uint16_t orientation;
uint32_t col, row;
uint32_t tw, th;
u_char* buf;
u_char* r;
u_char* g;
u_char* b;
u_char* a;
u_char *buf;
u_char *r;
u_char *g;
u_char *b;
u_char *a;
tsize_t tilesize;
int32_t fromskew;
int alpha = img->alpha;
uint32_t nrow;
tilesize = TIFFTileSize(tif);
buf = (u_char*) _TIFFmalloc(4*tilesize);
if (buf == 0) {
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
buf = (u_char *)_TIFFmalloc(4 * tilesize);
if (buf == 0)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
}
r = buf;
g = r + tilesize;
b = g + tilesize;
a = b + tilesize;
if (!alpha)
memset(a, 0xff, tilesize);
memset(a, 0xff, tilesize);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
orientation = img->orientation;
for (row = 0; row < h; row += th) {
nrow = (row + th > h ? h - row : th);
for (col = 0; col < w; col += tw) {
if (TIFFReadTile(tif, r, col, row,0,0) < 0 && img->stoponerr)
break;
if (TIFFReadTile(tif, g, col, row,0,1) < 0 && img->stoponerr)
break;
if (TIFFReadTile(tif, b, col, row,0,2) < 0 && img->stoponerr)
break;
if (alpha && TIFFReadTile(tif,a,col,row,0,3) < 0 && img->stoponerr)
break;
if (col + tw > w) {
/*
* Tile is clipped horizontally. Calculate
* visible portion and skewing factors.
*/
uint32_t npix = w - col;
fromskew = tw - npix;
(*callback)(img, udata, col, row, npix, nrow, fromskew, r, g, b, a);
} else {
(*callback)(img, udata, col, row, tw, nrow, 0, r, g, b, a);
}
}
for (row = 0; row < h; row += th)
{
nrow = (row + th > h ? h - row : th);
for (col = 0; col < w; col += tw)
{
if (TIFFReadTile(tif, r, col, row, 0, 0) < 0 && img->stoponerr)
break;
if (TIFFReadTile(tif, g, col, row, 0, 1) < 0 && img->stoponerr)
break;
if (TIFFReadTile(tif, b, col, row, 0, 2) < 0 && img->stoponerr)
break;
if (alpha && TIFFReadTile(tif, a, col, row, 0, 3) < 0 &&
img->stoponerr)
break;
if (col + tw > w)
{
/*
* Tile is clipped horizontally. Calculate
* visible portion and skewing factors.
*/
uint32_t npix = w - col;
fromskew = tw - npix;
(*callback)(img, udata, col, row, npix, nrow, fromskew, r, g, b,
a);
}
else
{
(*callback)(img, udata, col, row, tw, nrow, 0, r, g, b, a);
}
}
}
_TIFFfree(buf);
return (1);
@@ -368,35 +401,38 @@ gtTileSeparate(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
* PlanarConfiguration contiguous if SamplesPerPixel > 1
* or
* SamplesPerPixel == 1
*/
static int
gtStripContig(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
*/
static int gtStripContig(TIFFImageIter *img, void *udata, uint32_t w,
uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
ImageIterTileContigRoutine callback = img->callback.contig;
uint16_t orientation;
uint32_t row, nrow;
u_char* buf;
u_char *buf;
uint32_t rowsperstrip;
uint32_t imagewidth = img->width;
tsize_t scanline;
int32_t fromskew;
buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
if (buf == 0) {
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
return (0);
buf = (u_char *)_TIFFmalloc(TIFFStripSize(tif));
if (buf == 0)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
return (0);
}
orientation = img->orientation;
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
scanline = TIFFScanlineSize(tif);
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += rowsperstrip) {
nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
buf, nrow*scanline) < 0 && img->stoponerr)
break;
(*callback)(img, udata, 0, row, w, nrow, fromskew, buf);
for (row = 0; row < h; row += rowsperstrip)
{
nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf,
nrow * scanline) < 0 &&
img->stoponerr)
break;
(*callback)(img, udata, 0, row, w, nrow, fromskew, buf);
}
_TIFFfree(buf);
return (1);
@@ -408,10 +444,10 @@ gtStripContig(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
* PlanarConfiguration separated
* We assume that all such images are RGB.
*/
static int
gtStripSeparate(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
static int gtStripSeparate(TIFFImageIter *img, void *udata, uint32_t w,
uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
ImageIterTileSeparateRoutine callback = img->callback.separate;
uint16_t orientation;
u_char *buf;
@@ -425,36 +461,41 @@ gtStripSeparate(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
int alpha = img->alpha;
stripsize = TIFFStripSize(tif);
r = buf = (u_char *)_TIFFmalloc(4*stripsize);
if (buf == 0) {
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
r = buf = (u_char *)_TIFFmalloc(4 * stripsize);
if (buf == 0)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
return (0);
}
g = r + stripsize;
b = g + stripsize;
a = b + stripsize;
if (!alpha)
memset(a, 0xff, stripsize);
memset(a, 0xff, stripsize);
orientation = img->orientation;
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
scanline = TIFFScanlineSize(tif);
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += rowsperstrip) {
nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
r, nrow*scanline) < 0 && img->stoponerr)
break;
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
g, nrow*scanline) < 0 && img->stoponerr)
break;
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
b, nrow*scanline) < 0 && img->stoponerr)
break;
if (alpha &&
(TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3),
a, nrow*scanline) < 0 && img->stoponerr))
break;
(*callback)(img, udata, 0, row, w, nrow, fromskew, r, g, b, a);
for (row = 0; row < h; row += rowsperstrip)
{
nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), r,
nrow * scanline) < 0 &&
img->stoponerr)
break;
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1), g,
nrow * scanline) < 0 &&
img->stoponerr)
break;
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2), b,
nrow * scanline) < 0 &&
img->stoponerr)
break;
if (alpha && (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3),
a, nrow * scanline) < 0 &&
img->stoponerr))
break;
(*callback)(img, udata, 0, row, w, nrow, fromskew, r, g, b, a);
}
_TIFFfree(buf);
return (1);
@@ -462,18 +503,18 @@ gtStripSeparate(TIFFImageIter* img, void *udata, uint32_t w, uint32_t h)
DECLAREContigCallbackFunc(TestContigCallback)
{
printf("Contig Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n",
x, y, w, h, fromskew);
printf("Contig Callback called with x = %d, y = %d, w = %d, h = %d, "
"fromskew = %d\n",
x, y, w, h, fromskew);
}
DECLARESepCallbackFunc(TestSepCallback)
{
printf("Sep Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n",
x, y, w, h, fromskew);
printf("Sep Callback called with x = %d, y = %d, w = %d, h = %d, fromskew "
"= %d\n",
x, y, w, h, fromskew);
}
#ifdef MAIN
main(int argc, char **argv)
{
@@ -489,28 +530,35 @@ main(int argc, char **argv)
unsigned char *ColorMap;
unsigned char *data;
if (argc < 2) {
fprintf(stderr,"usage: %s tiff_file\n",argv[0]);
exit(1);
if (argc < 2)
{
fprintf(stderr, "usage: %s tiff_file\n", argv[0]);
exit(1);
}
tif = (TIFF *)PLIGetImage(argv[1], (void *) &data, &ColorMap,
&nx, &ny, &BitsPerSample, &SamplesPerPixel,
&isColorMapped, &isPliFile);
if (tif != NULL) {
tif = (TIFF *)PLIGetImage(argv[1], (void *)&data, &ColorMap, &nx, &ny,
&BitsPerSample, &SamplesPerPixel, &isColorMapped,
&isPliFile);
if (tif != NULL)
{
if (TIFFImageIterBegin(&img, tif, stop, emsg)) {
/* Here need to set data and callback function! */
if (img.isContig) {
img.callback = TestContigCallback;
} else {
img.callback = TestSepCallback;
}
ok = TIFFImageIterGet(&img, NULL, img.width, img.height);
TIFFImageIterEnd(&img);
} else {
TIFFErrorExtR(tif, TIFFFileName(tif), emsg);
}
if (TIFFImageIterBegin(&img, tif, stop, emsg))
{
/* Here need to set data and callback function! */
if (img.isContig)
{
img.callback = TestContigCallback;
}
else
{
img.callback = TestSepCallback;
}
ok = TIFFImageIterGet(&img, NULL, img.width, img.height);
TIFFImageIterEnd(&img);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif), emsg);
}
}
}
#endif

View File

@@ -7,51 +7,45 @@ typedef struct _TIFFImageIter TIFFImageIter;
img->samplesperpixel consecutive samples each containing img->bitspersample
bits of data. The array pp is ordered in h consecutive rows of w+fromskew
pixels each. */
typedef void (*ImageIterTileContigRoutine)
(TIFFImageIter*, void *, uint32_t, uint32_t, uint32_t, uint32_t, int32_t,
unsigned char*);
#define DECLAREContigCallbackFunc(name) \
static void name(\
TIFFImageIter* img, \
void* user_data, \
uint32_t x, uint32_t y, \
uint32_t w, uint32_t h, \
int32_t fromskew, \
u_char* pp \
)
typedef void (*ImageIterTileContigRoutine)(TIFFImageIter *, void *, uint32_t,
uint32_t, uint32_t, uint32_t,
int32_t, unsigned char *);
#define DECLAREContigCallbackFunc(name) \
static void name(TIFFImageIter *img, void *user_data, uint32_t x, \
uint32_t y, uint32_t w, uint32_t h, int32_t fromskew, \
u_char *pp)
typedef void (*ImageIterTileSeparateRoutine)
(TIFFImageIter*, void *, uint32_t, uint32_t, uint32_t, uint32_t, int32_t,
unsigned char*, unsigned char*, unsigned char*, unsigned char*);
#define DECLARESepCallbackFunc(name) \
static void name(\
TIFFImageIter* img, \
void* user_data, \
uint32_t x, uint32_t y, \
uint32_t w, uint32_t h,\
int32_t fromskew, \
u_char* r, u_char* g, u_char* b, u_char* a\
)
typedef void (*ImageIterTileSeparateRoutine)(TIFFImageIter *, void *, uint32_t,
uint32_t, uint32_t, uint32_t,
int32_t, unsigned char *,
unsigned char *, unsigned char *,
unsigned char *);
#define DECLARESepCallbackFunc(name) \
static void name(TIFFImageIter *img, void *user_data, uint32_t x, \
uint32_t y, uint32_t w, uint32_t h, int32_t fromskew, \
u_char *r, u_char *g, u_char *b, u_char *a)
struct _TIFFImageIter {
TIFF* tif; /* image handle */
int stoponerr; /* stop on read error */
int isContig; /* data is packed/separate */
int alpha; /* type of alpha data present */
uint32_t width; /* image width */
uint32_t height; /* image height */
uint16_t bitspersample; /* image bits/sample */
uint16_t samplesperpixel; /* image samples/pixel */
uint16_t orientation; /* image orientation */
uint16_t photometric; /* image photometric interp */
uint16_t* redcmap; /* colormap palette */
uint16_t* greencmap;
uint16_t* bluecmap;
/* get image data routine */
int (*get)(TIFFImageIter*, void *udata, uint32_t, uint32_t);
union {
void (*any)(TIFFImageIter*);
ImageIterTileContigRoutine contig;
ImageIterTileSeparateRoutine separate;
} callback; /* fn to exec for each block */
struct _TIFFImageIter
{
TIFF *tif; /* image handle */
int stoponerr; /* stop on read error */
int isContig; /* data is packed/separate */
int alpha; /* type of alpha data present */
uint32_t width; /* image width */
uint32_t height; /* image height */
uint16_t bitspersample; /* image bits/sample */
uint16_t samplesperpixel; /* image samples/pixel */
uint16_t orientation; /* image orientation */
uint16_t photometric; /* image photometric interp */
uint16_t *redcmap; /* colormap palette */
uint16_t *greencmap;
uint16_t *bluecmap;
/* get image data routine */
int (*get)(TIFFImageIter *, void *udata, uint32_t, uint32_t);
union
{
void (*any)(TIFFImageIter *);
ImageIterTileContigRoutine contig;
ImageIterTileSeparateRoutine separate;
} callback; /* fn to exec for each block */
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -43,157 +43,152 @@ static char sccsid[] = "@(#)ras2tif.c 1.2 90/03/06";
* real file since seek(2) is used.
*/
#include "tiffio.h"
#include <pixrect/pixrect_hs.h>
#include <stdio.h>
#include <sys/time.h>
#include <pixrect/pixrect_hs.h>
#include "tiffio.h"
typedef int boolean;
#define True (1)
#define False (0)
#define SCALE(x) (((x)*((1L<<16)-1))/255)
#define SCALE(x) (((x) * ((1L << 16) - 1)) / 255)
boolean Verbose = False;
boolean dummyinput = False;
char *pname; /* program name (used for error messages) */
boolean Verbose = False;
boolean dummyinput = False;
char *pname; /* program name (used for error messages) */
void
error(s1, s2)
char *s1,
*s2;
void error(s1, s2) char *s1, *s2;
{
fprintf(stderr, s1, pname, s2);
exit(1);
}
void
usage()
{
error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL);
}
void usage() { error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL); }
main(argc, argv)
int argc;
char *argv[];
main(argc, argv) int argc;
char *argv[];
{
char *inf = NULL;
char *outf = NULL;
FILE *fp;
int depth,
i;
long row;
TIFF *tif;
Pixrect *pix; /* The Sun Pixrect */
colormap_t Colormap; /* The Pixrect Colormap */
u_short red[256],
green[256],
blue[256];
struct tm *ct;
char *inf = NULL;
char *outf = NULL;
FILE *fp;
int depth, i;
long row;
TIFF *tif;
Pixrect *pix; /* The Sun Pixrect */
colormap_t Colormap; /* The Pixrect Colormap */
u_short red[256], green[256], blue[256];
struct tm *ct;
struct timeval tv;
long width,
height;
long rowsperstrip;
int year;
short photometric;
short samplesperpixel;
short bitspersample;
int bpsl;
long width, height;
long rowsperstrip;
int year;
short photometric;
short samplesperpixel;
short bitspersample;
int bpsl;
static char *version = "ras2tif 1.0";
static char *datetime = "1990:01:01 12:00:00";
gettimeofday(&tv, (struct timezone *) NULL);
gettimeofday(&tv, (struct timezone *)NULL);
ct = localtime(&tv.tv_sec);
year=1900 + ct->tm_year;
sprintf(datetime, "%04d:%02d:%02d %02d:%02d:%02d",
year, ct->tm_mon + 1, ct->tm_mday,
ct->tm_hour, ct->tm_min, ct->tm_sec);
year = 1900 + ct->tm_year;
sprintf(datetime, "%04d:%02d:%02d %02d:%02d:%02d", year, ct->tm_mon + 1,
ct->tm_mday, ct->tm_hour, ct->tm_min, ct->tm_sec);
setbuf(stderr, NULL);
pname = argv[0];
while (--argc) {
if ((++argv)[0][0] == '-') {
switch (argv[0][1]) {
case 'v':
Verbose = True;
break;
case 'q':
usage();
break;
case '\0':
if (inf == NULL)
dummyinput = True;
else
usage();
break;
default:
fprintf(stderr, "%s: illegal option -%c.\n", pname,
argv[0][1]);
exit(1);
}
} else if (inf == NULL && !dummyinput) {
inf = argv[0];
} else if (outf == NULL)
outf = argv[0];
else
usage();
while (--argc)
{
if ((++argv)[0][0] == '-')
{
switch (argv[0][1])
{
case 'v':
Verbose = True;
break;
case 'q':
usage();
break;
case '\0':
if (inf == NULL)
dummyinput = True;
else
usage();
break;
default:
fprintf(stderr, "%s: illegal option -%c.\n", pname,
argv[0][1]);
exit(1);
}
}
else if (inf == NULL && !dummyinput)
{
inf = argv[0];
}
else if (outf == NULL)
outf = argv[0];
else
usage();
}
if (outf == NULL)
error("%s: can't write output file to a stream.\n", NULL);
error("%s: can't write output file to a stream.\n", NULL);
if (dummyinput || inf == NULL) {
inf = "Standard Input";
fp = stdin;
} else if ((fp = fopen(inf, "r")) == NULL)
error("%s: %s couldn't be opened.\n", inf);
if (dummyinput || inf == NULL)
{
inf = "Standard Input";
fp = stdin;
}
else if ((fp = fopen(inf, "r")) == NULL)
error("%s: %s couldn't be opened.\n", inf);
if (Verbose)
fprintf(stderr, "Reading rasterfile from %s...", inf);
fprintf(stderr, "Reading rasterfile from %s...", inf);
pix = pr_load(fp, &Colormap);
if (pix == NULL)
error("%s: %s is not a raster file.\n", inf);
error("%s: %s is not a raster file.\n", inf);
if (Verbose)
fprintf(stderr, "done.\n");
fprintf(stderr, "done.\n");
if (Verbose)
fprintf(stderr, "Writing %s...", outf);
fprintf(stderr, "Writing %s...", outf);
tif = TIFFOpen(outf, "w");
if (tif == NULL)
error("%s: error opening TIFF file %s", outf);
error("%s: error opening TIFF file %s", outf);
width = pix->pr_width;
height = pix->pr_height;
depth = pix->pr_depth;
switch (depth) {
case 1:
samplesperpixel = 1;
bitspersample = 1;
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 8:
samplesperpixel = 1;
bitspersample = 8;
photometric = PHOTOMETRIC_PALETTE;
break;
case 24:
samplesperpixel = 3;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
break;
case 32:
samplesperpixel = 4;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
break;
default:
error("%s: bogus depth: %d\n", depth);
switch (depth)
{
case 1:
samplesperpixel = 1;
bitspersample = 1;
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 8:
samplesperpixel = 1;
bitspersample = 8;
photometric = PHOTOMETRIC_PALETTE;
break;
case 24:
samplesperpixel = 3;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
break;
case 32:
samplesperpixel = 4;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
break;
default:
error("%s: bogus depth: %d\n", depth);
}
bpsl = ((depth * width + 15) >> 3) & ~1;
@@ -217,29 +212,31 @@ main(argc, argv)
memset(red, 0, sizeof(red));
memset(green, 0, sizeof(green));
memset(blue, 0, sizeof(blue));
if (depth == 8) {
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
for (i = 0; i < Colormap.length; i++) {
red[i] = SCALE(Colormap.map[0][i]);
green[i] = SCALE(Colormap.map[1][i]);
blue[i] = SCALE(Colormap.map[2][i]);
}
if (depth == 8)
{
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
for (i = 0; i < Colormap.length; i++)
{
red[i] = SCALE(Colormap.map[0][i]);
green[i] = SCALE(Colormap.map[1][i]);
blue[i] = SCALE(Colormap.map[2][i]);
}
}
if (Verbose)
fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
for (row = 0; row < height; row++)
if (TIFFWriteScanline(tif,
(u_char *) mprd_addr(mpr_d(pix), 0, row),
row, 0) < 0) {
fprintf("failed a scanline write (%d)\n", row);
break;
}
if (TIFFWriteScanline(tif, (u_char *)mprd_addr(mpr_d(pix), 0, row), row,
0) < 0)
{
fprintf("failed a scanline write (%d)\n", row);
break;
}
TIFFFlushData(tif);
TIFFClose(tif);
if (Verbose)
fprintf(stderr, "done.\n");
fprintf(stderr, "done.\n");
pr_destroy(pix);

View File

@@ -40,295 +40,295 @@
* file since seek(2) is used.
*/
#include <stdio.h>
#include <pixrect/pixrect_hs.h>
#include "tiffio.h"
#include <pixrect/pixrect_hs.h>
#include <stdio.h>
typedef int boolean;
#define True (1)
#define False (0)
#define CVT(x) (((x) * 255) / ((1L<<16)-1))
#define CVT(x) (((x)*255) / ((1L << 16) - 1))
boolean Verbose = False;
char *pname; /* program name (used for error messages) */
boolean Verbose = False;
char *pname; /* program name (used for error messages) */
void
error(s1, s2)
char *s1,
*s2;
void error(s1, s2) char *s1, *s2;
{
fprintf(stderr, s1, pname, s2);
exit(1);
}
void
usage()
{
error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
}
void usage() { error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL); }
main(argc, argv)
int argc;
char *argv[];
main(argc, argv) int argc;
char *argv[];
{
char *inf = NULL;
char *outf = NULL;
FILE *fp;
long width,
height;
int depth,
numcolors;
char *inf = NULL;
char *outf = NULL;
FILE *fp;
long width, height;
int depth, numcolors;
register TIFF *tif;
TIFFDirectory *td;
register u_char *inp,
*outp;
register int col,
i;
register u_char *inp, *outp;
register int col, i;
register long row;
u_char *Map = NULL;
u_char *buf;
short bitspersample;
short samplesperpixel;
short photometric;
u_short *redcolormap,
*bluecolormap,
*greencolormap;
u_char *Map = NULL;
u_char *buf;
short bitspersample;
short samplesperpixel;
short photometric;
u_short *redcolormap, *bluecolormap, *greencolormap;
Pixrect *pix; /* The Sun Pixrect */
colormap_t Colormap; /* The Pixrect Colormap */
u_char red[256],
green[256],
blue[256];
Pixrect *pix; /* The Sun Pixrect */
colormap_t Colormap; /* The Pixrect Colormap */
u_char red[256], green[256], blue[256];
setbuf(stderr, NULL);
pname = argv[0];
while (--argc) {
if ((++argv)[0][0] == '-')
switch (argv[0][1]) {
case 'v':
Verbose = True;
break;
case 'q':
usage();
break;
default:
fprintf(stderr, "%s: illegal option -%c.\n", pname,
argv[0][1]);
exit(1);
}
else if (inf == NULL)
inf = argv[0];
else if (outf == NULL)
outf = argv[0];
else
usage();
while (--argc)
{
if ((++argv)[0][0] == '-')
switch (argv[0][1])
{
case 'v':
Verbose = True;
break;
case 'q':
usage();
break;
default:
fprintf(stderr, "%s: illegal option -%c.\n", pname,
argv[0][1]);
exit(1);
}
else if (inf == NULL)
inf = argv[0];
else if (outf == NULL)
outf = argv[0];
else
usage();
}
if (inf == NULL)
error("%s: can't read input file from a stream.\n", NULL);
error("%s: can't read input file from a stream.\n", NULL);
if (Verbose)
fprintf(stderr, "Reading %s...", inf);
fprintf(stderr, "Reading %s...", inf);
tif = TIFFOpen(inf, "r");
if (tif == NULL)
error("%s: error opening TIFF file %s", inf);
error("%s: error opening TIFF file %s", inf);
if (Verbose)
TIFFPrintDirectory(tif, stderr, True, False, False);
TIFFPrintDirectory(tif, stderr, True, False, False);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
if (bitspersample > 8)
error("%s: can't handle more than 8-bits per sample\n", NULL);
error("%s: can't handle more than 8-bits per sample\n", NULL);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
switch (samplesperpixel) {
case 1:
if (bitspersample == 1)
depth = 1;
else
depth = 8;
break;
case 3:
case 4:
depth = 24;
break;
default:
error("%s: only handle 1-channel gray scale or 3-channel color\n");
switch (samplesperpixel)
{
case 1:
if (bitspersample == 1)
depth = 1;
else
depth = 8;
break;
case 3:
case 4:
depth = 24;
break;
default:
error("%s: only handle 1-channel gray scale or 3-channel color\n");
}
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
if (Verbose)
fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
if (Verbose)
fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
bitspersample, samplesperpixel);
fprintf(stderr, "%d bits/sample, %d samples/pixel, ", bitspersample,
samplesperpixel);
pix = mem_create(width, height, depth);
if (pix == (Pixrect *) NULL)
error("%s: can't allocate memory for output pixrect...\n", NULL);
if (pix == (Pixrect *)NULL)
error("%s: can't allocate memory for output pixrect...\n", NULL);
numcolors = (1 << bitspersample);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
if (numcolors == 2) {
if (Verbose)
fprintf(stderr, "monochrome ");
Colormap.type = RMT_NONE;
Colormap.length = 0;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
} else {
switch (photometric) {
case PHOTOMETRIC_MINISBLACK:
if (Verbose)
fprintf(stderr, "%d graylevels (min=black), ", numcolors);
Map = (u_char *) malloc(numcolors * sizeof(u_char));
for (i = 0; i < numcolors; i++)
Map[i] = (255 * i) / numcolors;
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
break;
case PHOTOMETRIC_MINISWHITE:
if (Verbose)
fprintf(stderr, "%d graylevels (min=white), ", numcolors);
Map = (u_char *) malloc(numcolors * sizeof(u_char));
for (i = 0; i < numcolors; i++)
Map[i] = 255 - ((255 * i) / numcolors);
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
break;
case PHOTOMETRIC_RGB:
if (Verbose)
fprintf(stderr, "truecolor ");
Colormap.type = RMT_NONE;
Colormap.length = 0;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
break;
case PHOTOMETRIC_PALETTE:
if (Verbose)
fprintf(stderr, "colormapped ");
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
memset(red, 0, sizeof(red));
memset(green, 0, sizeof(green));
memset(blue, 0, sizeof(blue));
TIFFGetField(tif, TIFFTAG_COLORMAP,
&redcolormap, &greencolormap, &bluecolormap);
for (i = 0; i < numcolors; i++) {
red[i] = (u_char) CVT(redcolormap[i]);
green[i] = (u_char) CVT(greencolormap[i]);
blue[i] = (u_char) CVT(bluecolormap[i]);
}
Colormap.map[0] = red;
Colormap.map[1] = green;
Colormap.map[2] = blue;
break;
case PHOTOMETRIC_MASK:
error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
break;
case PHOTOMETRIC_DEPTH:
error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
break;
default:
error("%s: unknown photometric (cmap): %d\n", photometric);
}
if (numcolors == 2)
{
if (Verbose)
fprintf(stderr, "monochrome ");
Colormap.type = RMT_NONE;
Colormap.length = 0;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
}
else
{
switch (photometric)
{
case PHOTOMETRIC_MINISBLACK:
if (Verbose)
fprintf(stderr, "%d graylevels (min=black), ", numcolors);
Map = (u_char *)malloc(numcolors * sizeof(u_char));
for (i = 0; i < numcolors; i++)
Map[i] = (255 * i) / numcolors;
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
break;
case PHOTOMETRIC_MINISWHITE:
if (Verbose)
fprintf(stderr, "%d graylevels (min=white), ", numcolors);
Map = (u_char *)malloc(numcolors * sizeof(u_char));
for (i = 0; i < numcolors; i++)
Map[i] = 255 - ((255 * i) / numcolors);
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
break;
case PHOTOMETRIC_RGB:
if (Verbose)
fprintf(stderr, "truecolor ");
Colormap.type = RMT_NONE;
Colormap.length = 0;
Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
break;
case PHOTOMETRIC_PALETTE:
if (Verbose)
fprintf(stderr, "colormapped ");
Colormap.type = RMT_EQUAL_RGB;
Colormap.length = numcolors;
memset(red, 0, sizeof(red));
memset(green, 0, sizeof(green));
memset(blue, 0, sizeof(blue));
TIFFGetField(tif, TIFFTAG_COLORMAP, &redcolormap,
&greencolormap, &bluecolormap);
for (i = 0; i < numcolors; i++)
{
red[i] = (u_char)CVT(redcolormap[i]);
green[i] = (u_char)CVT(greencolormap[i]);
blue[i] = (u_char)CVT(bluecolormap[i]);
}
Colormap.map[0] = red;
Colormap.map[1] = green;
Colormap.map[2] = blue;
break;
case PHOTOMETRIC_MASK:
error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
break;
case PHOTOMETRIC_DEPTH:
error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
break;
default:
error("%s: unknown photometric (cmap): %d\n", photometric);
}
}
buf = (u_char *) malloc(TIFFScanlineSize(tif));
buf = (u_char *)malloc(TIFFScanlineSize(tif));
if (buf == NULL)
error("%s: can't allocate memory for scanline buffer...\n", NULL);
error("%s: can't allocate memory for scanline buffer...\n", NULL);
for (row = 0; row < height; row++) {
if (TIFFReadScanline(tif, buf, row, 0) < 0)
error("%s: bad data read on line: %d\n", row);
inp = buf;
outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
switch (photometric) {
case PHOTOMETRIC_RGB:
if (samplesperpixel == 4)
for (col = 0; col < width; col++) {
*outp++ = *inp++; /* Blue */
*outp++ = *inp++; /* Green */
*outp++ = *inp++; /* Red */
inp++; /* skip alpha channel */
}
else
for (col = 0; col < width; col++) {
*outp++ = *inp++; /* Blue */
*outp++ = *inp++; /* Green */
*outp++ = *inp++; /* Red */
}
break;
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
switch (bitspersample) {
case 1:
for (col = 0; col < ((width + 7) / 8); col++)
*outp++ = *inp++;
break;
case 2:
for (col = 0; col < ((width + 3) / 4); col++) {
*outp++ = (*inp >> 6) & 3;
*outp++ = (*inp >> 4) & 3;
*outp++ = (*inp >> 2) & 3;
*outp++ = *inp++ & 3;
}
break;
case 4:
for (col = 0; col < width / 2; col++) {
*outp++ = *inp >> 4;
*outp++ = *inp++ & 0xf;
}
break;
case 8:
for (col = 0; col < width; col++)
*outp++ = *inp++;
break;
default:
error("%s: bad bits/sample: %d\n", bitspersample);
}
break;
case PHOTOMETRIC_PALETTE:
memcpy(outp, inp, width);
break;
default:
error("%s: unknown photometric (write): %d\n", photometric);
}
for (row = 0; row < height; row++)
{
if (TIFFReadScanline(tif, buf, row, 0) < 0)
error("%s: bad data read on line: %d\n", row);
inp = buf;
outp = (u_char *)mprd_addr(mpr_d(pix), 0, row);
switch (photometric)
{
case PHOTOMETRIC_RGB:
if (samplesperpixel == 4)
for (col = 0; col < width; col++)
{
*outp++ = *inp++; /* Blue */
*outp++ = *inp++; /* Green */
*outp++ = *inp++; /* Red */
inp++; /* skip alpha channel */
}
else
for (col = 0; col < width; col++)
{
*outp++ = *inp++; /* Blue */
*outp++ = *inp++; /* Green */
*outp++ = *inp++; /* Red */
}
break;
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
switch (bitspersample)
{
case 1:
for (col = 0; col < ((width + 7) / 8); col++)
*outp++ = *inp++;
break;
case 2:
for (col = 0; col < ((width + 3) / 4); col++)
{
*outp++ = (*inp >> 6) & 3;
*outp++ = (*inp >> 4) & 3;
*outp++ = (*inp >> 2) & 3;
*outp++ = *inp++ & 3;
}
break;
case 4:
for (col = 0; col < width / 2; col++)
{
*outp++ = *inp >> 4;
*outp++ = *inp++ & 0xf;
}
break;
case 8:
for (col = 0; col < width; col++)
*outp++ = *inp++;
break;
default:
error("%s: bad bits/sample: %d\n", bitspersample);
}
break;
case PHOTOMETRIC_PALETTE:
memcpy(outp, inp, width);
break;
default:
error("%s: unknown photometric (write): %d\n", photometric);
}
}
free((char *) buf);
free((char *)buf);
if (Verbose)
fprintf(stderr, "done.\n");
fprintf(stderr, "done.\n");
if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
outf = "Standard Output";
fp = stdout;
} else {
if (!(fp = fopen(outf, "w")))
error("%s: %s couldn't be opened for writing.\n", outf);
if (outf == NULL || strcmp(outf, "Standard Output") == 0)
{
outf = "Standard Output";
fp = stdout;
}
else
{
if (!(fp = fopen(outf, "w")))
error("%s: %s couldn't be opened for writing.\n", outf);
}
if (Verbose)
fprintf(stderr, "Writing rasterfile in %s...", outf);
fprintf(stderr, "Writing rasterfile in %s...", outf);
if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
error("%s: error writing Sun Rasterfile: %s\n", outf);
error("%s: error writing Sun Rasterfile: %s\n", outf);
if (Verbose)
fprintf(stderr, "done.\n");
fprintf(stderr, "done.\n");
pr_destroy(pix);
if (fp != stdout)
fclose(fp);
fclose(fp);
exit(0);
}

View File

@@ -2,231 +2,213 @@
#include "tiffstream.h"
const char* TiffStream::m_name = "TiffStream";
const char *TiffStream::m_name = "TiffStream";
TiffStream::TiffStream()
{
m_tif = NULL;
m_inStream = NULL;
m_outStream = NULL;
m_ioStream = NULL;
m_outStream = NULL;
m_ioStream = NULL;
m_streamLength = 0;
m_streamLength = 0;
m_this = reinterpret_cast<thandle_t>(this);
m_this = reinterpret_cast<thandle_t>(this);
};
TiffStream::~TiffStream()
{
if(m_tif != NULL) TIFFClose(m_tif);
if (m_tif != NULL)
TIFFClose(m_tif);
}
TIFF*
TiffStream::makeFileStream(istream* str)
TIFF *TiffStream::makeFileStream(istream *str)
{
m_inStream = str;
m_outStream = NULL;
m_ioStream = NULL;
m_outStream = NULL;
m_ioStream = NULL;
m_streamLength = getSize(m_this);
m_tif = TIFFClientOpen(m_name,
"r",
m_this,
read,
write,
seek,
close,
size,
map,
unmap);
m_tif = TIFFClientOpen(m_name, "r", m_this, read, write, seek, close, size,
map, unmap);
return m_tif;
}
TIFF*
TiffStream::makeFileStream(ostream* str)
TIFF *TiffStream::makeFileStream(ostream *str)
{
m_inStream = NULL;
m_inStream = NULL;
m_outStream = str;
m_ioStream = NULL;
m_streamLength = getSize(m_this);
m_ioStream = NULL;
m_streamLength = getSize(m_this);
m_tif = TIFFClientOpen(m_name,
"w",
m_this,
read,
write,
seek,
close,
size,
map,
unmap);
m_tif = TIFFClientOpen(m_name, "w", m_this, read, write, seek, close, size,
map, unmap);
return m_tif;
}
TIFF*
TiffStream::makeFileStream(iostream* str)
TIFF *TiffStream::makeFileStream(iostream *str)
{
m_inStream = NULL;
m_outStream = NULL;
m_inStream = NULL;
m_outStream = NULL;
m_ioStream = str;
m_streamLength = getSize(m_this);
m_streamLength = getSize(m_this);
m_tif = TIFFClientOpen(m_name,
"r+w",
m_this,
read,
write,
seek,
close,
size,
map,
unmap);
m_tif = TIFFClientOpen(m_name, "r+w", m_this, read, write, seek, close,
size, map, unmap);
return m_tif;
}
tsize_t
TiffStream::read(thandle_t fd, tdata_t buf, tsize_t size)
tsize_t TiffStream::read(thandle_t fd, tdata_t buf, tsize_t size)
{
istream* istr;
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
if(ts->m_inStream != NULL) {
istr = ts->m_inStream;
} else if(ts->m_ioStream != NULL) {
istr = ts->m_ioStream;
}
istream *istr;
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
if (ts->m_inStream != NULL)
{
istr = ts->m_inStream;
}
else if (ts->m_ioStream != NULL)
{
istr = ts->m_ioStream;
}
int remain = ts->m_streamLength - ts->tell(fd);
int actual = remain < size ? remain : size;
istr->read(reinterpret_cast<char*>(buf), actual);
int remain = ts->m_streamLength - ts->tell(fd);
int actual = remain < size ? remain : size;
istr->read(reinterpret_cast<char *>(buf), actual);
return istr->gcount();
}
tsize_t
TiffStream::write(thandle_t fd, tdata_t buf, tsize_t size)
tsize_t TiffStream::write(thandle_t fd, tdata_t buf, tsize_t size)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
ostream* ostr;
if(ts->m_outStream != NULL) {
ostr = ts->m_outStream;
} else if(ts->m_ioStream != NULL) {
ostr = ts->m_ioStream;
}
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
ostream *ostr;
if (ts->m_outStream != NULL)
{
ostr = ts->m_outStream;
}
else if (ts->m_ioStream != NULL)
{
ostr = ts->m_ioStream;
}
streampos start = ostr->tellp();
ostr->write(reinterpret_cast<const char*>(buf), size);
return ostr->tellp() - start;
streampos start = ostr->tellp();
ostr->write(reinterpret_cast<const char *>(buf), size);
return ostr->tellp() - start;
}
toff_t
TiffStream::seek(thandle_t fd, toff_t offset, int origin)
toff_t TiffStream::seek(thandle_t fd, toff_t offset, int origin)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
if(ts->seekInt(fd, offset, origin) == true) return offset;
else return -1;
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
if (ts->seekInt(fd, offset, origin) == true)
return offset;
else
return -1;
}
int
TiffStream::close(thandle_t fd)
int TiffStream::close(thandle_t fd)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
if(ts->m_inStream != NULL) {
ts->m_inStream = NULL;
return 0;
} else if(ts->m_outStream != NULL) {
ts->m_outStream = NULL;
return 0;
} else if(ts->m_ioStream != NULL) {
ts->m_ioStream = NULL;
return 0;
}
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
if (ts->m_inStream != NULL)
{
ts->m_inStream = NULL;
return 0;
}
else if (ts->m_outStream != NULL)
{
ts->m_outStream = NULL;
return 0;
}
else if (ts->m_ioStream != NULL)
{
ts->m_ioStream = NULL;
return 0;
}
return -1;
}
toff_t
TiffStream::size(thandle_t fd)
toff_t TiffStream::size(thandle_t fd)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
return ts->getSize(fd);
}
int
TiffStream::map(thandle_t fd, tdata_t* phase, toff_t* psize)
int TiffStream::map(thandle_t fd, tdata_t *phase, toff_t *psize) { return 0; }
void TiffStream::unmap(thandle_t fd, tdata_t base, tsize_t size) {}
unsigned int TiffStream::getSize(thandle_t fd)
{
if (!isOpen(fd))
return 0;
unsigned int pos = tell(fd);
seekInt(fd, 0, end);
unsigned int size = tell(fd);
seekInt(fd, pos, beg);
return size;
}
unsigned int TiffStream::tell(thandle_t fd)
{
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
if (ts->m_inStream != NULL)
{
return ts->m_inStream->tellg();
}
else if (ts->m_outStream != NULL)
{
return ts->m_outStream->tellp();
}
else if (ts->m_ioStream != NULL)
{
return ts->m_ioStream->tellg();
}
return 0;
}
void
TiffStream::unmap(thandle_t fd, tdata_t base, tsize_t size)
bool TiffStream::seekInt(thandle_t fd, unsigned int offset, int origin)
{
}
if (!isOpen(fd))
return false;
unsigned int
TiffStream::getSize(thandle_t fd)
{
if(!isOpen(fd)) return 0;
ios::seek_dir org;
switch (origin)
{
case beg:
org = ios::beg;
break;
case cur:
org = ios::cur;
break;
case end:
org = ios::end;
break;
}
unsigned int pos = tell(fd);
seekInt(fd, 0, end);
unsigned int size = tell(fd);
seekInt(fd, pos, beg);
return size;
}
unsigned int
TiffStream::tell(thandle_t fd)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
if(ts->m_inStream != NULL) {
return ts->m_inStream->tellg();
} else if(ts->m_outStream != NULL) {
return ts->m_outStream->tellp();
} else if(ts->m_ioStream != NULL) {
return ts->m_ioStream->tellg();
}
return 0;
}
bool
TiffStream::seekInt(thandle_t fd, unsigned int offset, int origin)
{
if(!isOpen(fd)) return false;
ios::seek_dir org;
switch(origin) {
case beg:
org = ios::beg;
break;
case cur:
org = ios::cur;
break;
case end:
org = ios::end;
break;
}
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
if(ts->m_inStream != NULL) {
ts->m_inStream->seekg(offset, org);
return true;
} else if(ts->m_outStream != NULL) {
ts->m_outStream->seekp(offset, org);
return true;
} else if(ts->m_ioStream != NULL) {
ts->m_ioStream->seekg(offset, org);
ts->m_ioStream->seekp(offset, org);
return true;
}
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
if (ts->m_inStream != NULL)
{
ts->m_inStream->seekg(offset, org);
return true;
}
else if (ts->m_outStream != NULL)
{
ts->m_outStream->seekp(offset, org);
return true;
}
else if (ts->m_ioStream != NULL)
{
ts->m_ioStream->seekg(offset, org);
ts->m_ioStream->seekp(offset, org);
return true;
}
return false;
}
bool
TiffStream::isOpen(thandle_t fd)
bool TiffStream::isOpen(thandle_t fd)
{
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
return (ts->m_inStream != NULL ||
ts->m_outStream != NULL ||
ts->m_ioStream != NULL);
TiffStream *ts = reinterpret_cast<TiffStream *>(fd);
return (ts->m_inStream != NULL || ts->m_outStream != NULL ||
ts->m_ioStream != NULL);
}

View File

@@ -7,57 +7,58 @@
#include "tiffio.h"
class TiffStream {
class TiffStream
{
public:
public:
// ctor/dtor
TiffStream();
~TiffStream();
~TiffStream();
public:
enum SeekDir {
beg,
cur,
end,
public:
enum SeekDir
{
beg,
cur,
end,
};
public:
public:
// factory methods
TIFF* makeFileStream(iostream* str);
TIFF* makeFileStream(istream* str);
TIFF* makeFileStream(ostream* str);
TIFF *makeFileStream(iostream *str);
TIFF *makeFileStream(istream *str);
TIFF *makeFileStream(ostream *str);
public:
public:
// tiff client methods
static tsize_t read(thandle_t fd, tdata_t buf, tsize_t size);
static tsize_t write(thandle_t fd, tdata_t buf, tsize_t size);
static toff_t seek(thandle_t fd, toff_t offset, int origin);
static toff_t size(thandle_t fd);
static int close(thandle_t fd);
static int map(thandle_t fd, tdata_t* phase, toff_t* psize);
static void unmap(thandle_t fd, tdata_t base, tsize_t size);
static tsize_t read(thandle_t fd, tdata_t buf, tsize_t size);
static tsize_t write(thandle_t fd, tdata_t buf, tsize_t size);
static toff_t seek(thandle_t fd, toff_t offset, int origin);
static toff_t size(thandle_t fd);
static int close(thandle_t fd);
static int map(thandle_t fd, tdata_t *phase, toff_t *psize);
static void unmap(thandle_t fd, tdata_t base, tsize_t size);
public:
public:
// query method
TIFF* getTiffHandle() const { return m_tif; }
unsigned int getStreamLength() { return m_streamLength; }
TIFF *getTiffHandle() const { return m_tif; }
unsigned int getStreamLength() { return m_streamLength; }
private:
// internal methods
private:
// internal methods
unsigned int getSize(thandle_t fd);
unsigned int tell(thandle_t fd);
bool seekInt(thandle_t fd, unsigned int offset, int origin);
bool isOpen(thandle_t fd);
unsigned int tell(thandle_t fd);
bool seekInt(thandle_t fd, unsigned int offset, int origin);
bool isOpen(thandle_t fd);
private:
thandle_t m_this;
TIFF* m_tif;
static const char* m_name;
istream* m_inStream;
ostream* m_outStream;
iostream* m_ioStream;
int m_streamLength;
private:
thandle_t m_this;
TIFF *m_tif;
static const char *m_name;
istream *m_inStream;
ostream *m_outStream;
iostream *m_ioStream;
int m_streamLength;
};
#endif // _TIFF_STREAM_H_

View File

@@ -5,27 +5,30 @@
#include "xtiffio.h"
#include <stdlib.h>
void main(int argc,char *argv[])
void main(int argc, char *argv[])
{
char *fname="newtif.tif";
int flags;
char *fname = "newtif.tif";
int flags;
TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */
TIFF *tif = (TIFF *)0; /* TIFF-level descriptor */
if (argc > 1)
fname = argv[1];
tif = XTIFFOpen(fname, "r");
if (!tif)
goto failure;
/* We want the double array listed */
flags = TIFFPRINT_MYMULTIDOUBLES;
TIFFPrintDirectory(tif, stdout, flags);
XTIFFClose(tif);
exit(0);
if (argc>1) fname=argv[1];
tif=XTIFFOpen(fname,"r");
if (!tif) goto failure;
/* We want the double array listed */
flags = TIFFPRINT_MYMULTIDOUBLES;
TIFFPrintDirectory(tif,stdout,flags);
XTIFFClose(tif);
exit (0);
failure:
printf("failure in listtif\n");
if (tif) XTIFFClose(tif);
exit (-1);
printf("failure in listtif\n");
if (tif)
XTIFFClose(tif);
exit(-1);
}

View File

@@ -3,9 +3,8 @@
* the XTIFF extended tiff example tags.
*/
#include <stdlib.h>
#include "xtiffio.h"
#include <stdlib.h>
void SetUpTIFFDirectory(TIFF *tif);
void WriteImage(TIFF *tif);
@@ -15,52 +14,52 @@ void WriteImage(TIFF *tif);
void main()
{
TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */
tif=XTIFFOpen("newtif.tif","w");
if (!tif) goto failure;
SetUpTIFFDirectory(tif);
WriteImage(tif);
XTIFFClose(tif);
exit (0);
failure:
printf("failure in maketif\n");
if (tif) XTIFFClose(tif);
exit (-1);
}
TIFF *tif = (TIFF *)0; /* TIFF-level descriptor */
tif = XTIFFOpen("newtif.tif", "w");
if (!tif)
goto failure;
SetUpTIFFDirectory(tif);
WriteImage(tif);
XTIFFClose(tif);
exit(0);
failure:
printf("failure in maketif\n");
if (tif)
XTIFFClose(tif);
exit(-1);
}
void SetUpTIFFDirectory(TIFF *tif)
{
double mymulti[6]={0.0,1.0,2.0, 3.1415926, 5.0,1.0};
uint32_t mysingle=3456;
char *ascii="This file was produced by Steven Spielberg. NOT";
double mymulti[6] = {0.0, 1.0, 2.0, 3.1415926, 5.0, 1.0};
uint32_t mysingle = 3456;
char *ascii = "This file was produced by Steven Spielberg. NOT";
TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,WIDTH);
TIFFSetField(tif,TIFFTAG_IMAGELENGTH,HEIGHT);
TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE);
TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8);
TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,20);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 20);
/* Install the extended TIFF tag examples */
TIFFSetField(tif,TIFFTAG_EXAMPLE_MULTI,6,mymulti);
TIFFSetField(tif,TIFFTAG_EXAMPLE_SINGLE,mysingle);
TIFFSetField(tif,TIFFTAG_EXAMPLE_ASCII,ascii);
/* Install the extended TIFF tag examples */
TIFFSetField(tif, TIFFTAG_EXAMPLE_MULTI, 6, mymulti);
TIFFSetField(tif, TIFFTAG_EXAMPLE_SINGLE, mysingle);
TIFFSetField(tif, TIFFTAG_EXAMPLE_ASCII, ascii);
}
void WriteImage(TIFF *tif)
{
int i;
char buffer[WIDTH];
memset(buffer,0,sizeof(buffer));
for (i=0;i<HEIGHT;i++)
if (!TIFFWriteScanline(tif, buffer, i, 0))
TIFFErrorExtR(tif, "WriteImage","failure in WriteScanline\n");
int i;
char buffer[WIDTH];
memset(buffer, 0, sizeof(buffer));
for (i = 0; i < HEIGHT; i++)
if (!TIFFWriteScanline(tif, buffer, i, 0))
TIFFErrorExtR(tif, "WriteImage", "failure in WriteScanline\n");
}

View File

@@ -10,14 +10,14 @@
*
* Author: Niles D. Ritter
*/
#include "xtiffiop.h"
#include <stdio.h>
/* Tiff info structure.
*
* Entry format:
* { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM,
* { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM,
* OkToChange, PassDirCountOnSet, AsciiName }
*
* For ReadCount, WriteCount, -1 = unknown; used for mult-valued
@@ -25,219 +25,216 @@
*/
static const TIFFFieldInfo xtiffFieldInfo[] = {
/* XXX Replace these example tags with your own extended tags */
{ TIFFTAG_EXAMPLE_MULTI, -1,-1, TIFF_DOUBLE, FIELD_EXAMPLE_MULTI,
TRUE, TRUE, "MyMultivaluedTag" },
{ TIFFTAG_EXAMPLE_SINGLE, 1, 1, TIFF_LONG, FIELD_EXAMPLE_SINGLE,
TRUE, FALSE, "MySingleLongTag" },
{ TIFFTAG_EXAMPLE_ASCII, -1,-1, TIFF_ASCII, FIELD_EXAMPLE_ASCII,
TRUE, FALSE, "MyAsciiTag" },
/* XXX Replace these example tags with your own extended tags */
{TIFFTAG_EXAMPLE_MULTI, -1, -1, TIFF_DOUBLE, FIELD_EXAMPLE_MULTI, TRUE,
TRUE, "MyMultivaluedTag"},
{TIFFTAG_EXAMPLE_SINGLE, 1, 1, TIFF_LONG, FIELD_EXAMPLE_SINGLE, TRUE, FALSE,
"MySingleLongTag"},
{TIFFTAG_EXAMPLE_ASCII, -1, -1, TIFF_ASCII, FIELD_EXAMPLE_ASCII, TRUE,
FALSE, "MyAsciiTag"},
};
#define N(a) (sizeof (a) / sizeof (a[0]))
#define N(a) (sizeof(a) / sizeof(a[0]))
static void
_XTIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
static void _XTIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
{
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory *xd = &xt->xtif_dir;
int i,num;
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory *xd = &xt->xtif_dir;
int i, num;
/* call the inherited method */
if (PARENT(xt,printdir))
(PARENT(xt,printdir))(tif,fd,flags);
/* call the inherited method */
if (PARENT(xt, printdir))
(PARENT(xt, printdir))(tif, fd, flags);
/* XXX Add field printing here. Replace the three example
* tags implemented below with your own.
*/
/* XXX Add field printing here. Replace the three example
* tags implemented below with your own.
*/
fprintf(fd,"--My Example Tags--\n");
fprintf(fd, "--My Example Tags--\n");
/* Our first example tag may have a lot of values, so we
* will only print them out if the TIFFPRINT_MYMULTIDOUBLES
* flag is passed into the print method.
*/
if (TIFFFieldSet(tif,FIELD_EXAMPLE_MULTI))
{
fprintf(fd, " My Multi-Valued Doubles:");
if (flags & TIFFPRINT_MYMULTIDOUBLES)
{
double *value = xd->xd_example_multi;
num = xd->xd_num_multi;
fprintf(fd,"(");
for (i=0;i<num;i++) fprintf(fd, " %lg", *value++);
fprintf(fd,")\n");
} else
fprintf(fd, "(present)\n");
}
/* Our first example tag may have a lot of values, so we
* will only print them out if the TIFFPRINT_MYMULTIDOUBLES
* flag is passed into the print method.
*/
if (TIFFFieldSet(tif, FIELD_EXAMPLE_MULTI))
{
fprintf(fd, " My Multi-Valued Doubles:");
if (flags & TIFFPRINT_MYMULTIDOUBLES)
{
double *value = xd->xd_example_multi;
if (TIFFFieldSet(tif,FIELD_EXAMPLE_SINGLE))
{
fprintf(fd, " My Single Long Tag: %lu\n", xd->xd_example_single);
}
num = xd->xd_num_multi;
fprintf(fd, "(");
for (i = 0; i < num; i++)
fprintf(fd, " %lg", *value++);
fprintf(fd, ")\n");
}
else
fprintf(fd, "(present)\n");
}
if (TIFFFieldSet(tif,FIELD_EXAMPLE_ASCII))
{
_TIFFprintAsciiTag(fd,"My ASCII Tag",
xd->xd_example_ascii);
}
if (TIFFFieldSet(tif, FIELD_EXAMPLE_SINGLE))
{
fprintf(fd, " My Single Long Tag: %lu\n", xd->xd_example_single);
}
if (TIFFFieldSet(tif, FIELD_EXAMPLE_ASCII))
{
_TIFFprintAsciiTag(fd, "My ASCII Tag", xd->xd_example_ascii);
}
}
static int
_XTIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
static int _XTIFFVSetField(TIFF *tif, ttag_t tag, va_list ap)
{
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory* xd = &xt->xtif_dir;
int status = 1;
uint32_t v32=0;
int i=0, v=0;
va_list ap1 = ap;
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory *xd = &xt->xtif_dir;
int status = 1;
uint32_t v32 = 0;
int i = 0, v = 0;
va_list ap1 = ap;
/* va_start is called by the calling routine */
switch (tag) {
/*
* XXX put your extended tags here; replace the implemented
* example tags with your own.
*/
case TIFFTAG_EXAMPLE_MULTI:
/* multi-valued tags need to store the count as well */
xd->xd_num_multi = (uint16_t) va_arg(ap, int);
_TIFFsetDoubleArray(&xd->xd_example_multi, va_arg(ap, double*),
(long) xd->xd_num_multi);
break;
case TIFFTAG_EXAMPLE_SINGLE:
xd->xd_example_single = va_arg(ap, uint32_t);
break;
case TIFFTAG_EXAMPLE_ASCII:
_TIFFsetString(&xd->xd_example_ascii, va_arg(ap, char*));
break;
default:
/* call the inherited method */
return (PARENT(xt,vsetfield))(tif,tag,ap);
break;
}
if (status) {
/* we have to override the print method here,
* after the compression tags have gotten to it.
* This makes sense because the only time we would
* need the extended print method is if an extended
* tag is set by the reader.
*/
if (!(xt->xtif_flags & XTIFFP_PRINT))
{
PARENT(xt,printdir) = TIFFMEMBER(tif,printdir);
TIFFMEMBER(tif,printdir) = _XTIFFPrintDirectory;
xt->xtif_flags |= XTIFFP_PRINT;
}
TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
tif->tif_flags |= TIFF_DIRTYDIRECT;
}
va_end(ap);
return (status);
/* va_start is called by the calling routine */
switch (tag)
{
/*
* XXX put your extended tags here; replace the implemented
* example tags with your own.
*/
case TIFFTAG_EXAMPLE_MULTI:
/* multi-valued tags need to store the count as well */
xd->xd_num_multi = (uint16_t)va_arg(ap, int);
_TIFFsetDoubleArray(&xd->xd_example_multi, va_arg(ap, double *),
(long)xd->xd_num_multi);
break;
case TIFFTAG_EXAMPLE_SINGLE:
xd->xd_example_single = va_arg(ap, uint32_t);
break;
case TIFFTAG_EXAMPLE_ASCII:
_TIFFsetString(&xd->xd_example_ascii, va_arg(ap, char *));
break;
default:
/* call the inherited method */
return (PARENT(xt, vsetfield))(tif, tag, ap);
break;
}
if (status)
{
/* we have to override the print method here,
* after the compression tags have gotten to it.
* This makes sense because the only time we would
* need the extended print method is if an extended
* tag is set by the reader.
*/
if (!(xt->xtif_flags & XTIFFP_PRINT))
{
PARENT(xt, printdir) = TIFFMEMBER(tif, printdir);
TIFFMEMBER(tif, printdir) = _XTIFFPrintDirectory;
xt->xtif_flags |= XTIFFP_PRINT;
}
TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
tif->tif_flags |= TIFF_DIRTYDIRECT;
}
va_end(ap);
return (status);
badvalue:
TIFFErrorExtR(tif, tif->tif_name, "%d: Bad value for \"%s\"", v,
_TIFFFieldWithTag(tif, tag)->field_name);
va_end(ap);
return (0);
TIFFErrorExtR(tif, tif->tif_name, "%d: Bad value for \"%s\"", v,
_TIFFFieldWithTag(tif, tag)->field_name);
va_end(ap);
return (0);
badvalue32:
TIFFErrorExtR(tif, tif->tif_name, "%ld: Bad value for \"%s\"", v32,
_TIFFFieldWithTag(tif, tag)->field_name);
va_end(ap);
return (0);
TIFFErrorExtR(tif, tif->tif_name, "%ld: Bad value for \"%s\"", v32,
_TIFFFieldWithTag(tif, tag)->field_name);
va_end(ap);
return (0);
}
static int
_XTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
static int _XTIFFVGetField(TIFF *tif, ttag_t tag, va_list ap)
{
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory* xd = &xt->xtif_dir;
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory *xd = &xt->xtif_dir;
switch (tag) {
/*
* XXX put your extended tags here; replace the implemented
* example tags with your own.
*/
case TIFFTAG_EXAMPLE_MULTI:
*va_arg(ap, uint16_t*) = xd->xd_num_multi;
*va_arg(ap, double**) = xd->xd_example_multi;
break;
case TIFFTAG_EXAMPLE_ASCII:
*va_arg(ap, char**) = xd->xd_example_ascii;
break;
case TIFFTAG_EXAMPLE_SINGLE:
*va_arg(ap, uint32_t*) = xd->xd_example_single;
break;
default:
/* return inherited method */
return (PARENT(xt,vgetfield))(tif,tag,ap);
break;
}
return (1);
switch (tag)
{
/*
* XXX put your extended tags here; replace the implemented
* example tags with your own.
*/
case TIFFTAG_EXAMPLE_MULTI:
*va_arg(ap, uint16_t *) = xd->xd_num_multi;
*va_arg(ap, double **) = xd->xd_example_multi;
break;
case TIFFTAG_EXAMPLE_ASCII:
*va_arg(ap, char **) = xd->xd_example_ascii;
break;
case TIFFTAG_EXAMPLE_SINGLE:
*va_arg(ap, uint32_t *) = xd->xd_example_single;
break;
default:
/* return inherited method */
return (PARENT(xt, vgetfield))(tif, tag, ap);
break;
}
return (1);
}
#define CleanupField(member) { \
if (xd->member) { \
_TIFFfree(xd->member); \
xd->member = 0; \
} \
}
#define CleanupField(member) \
{ \
if (xd->member) \
{ \
_TIFFfree(xd->member); \
xd->member = 0; \
} \
}
/*
* Release storage associated with a directory.
*/
static void
_XTIFFFreeDirectory(xtiff* xt)
static void _XTIFFFreeDirectory(xtiff *xt)
{
XTIFFDirectory* xd = &xt->xtif_dir;
XTIFFDirectory *xd = &xt->xtif_dir;
/*
* XXX - Purge all Your allocated memory except
* for the xtiff directory itself. This includes
* all fields that require a _TIFFsetXXX call in
* _XTIFFVSetField().
*/
CleanupField(xd_example_multi);
CleanupField(xd_example_ascii);
/*
* XXX - Purge all Your allocated memory except
* for the xtiff directory itself. This includes
* all fields that require a _TIFFsetXXX call in
* _XTIFFVSetField().
*/
CleanupField(xd_example_multi);
CleanupField(xd_example_ascii);
}
#undef CleanupField
static void _XTIFFLocalDefaultDirectory(TIFF *tif)
{
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory* xd = &xt->xtif_dir;
xtiff *xt = XTIFFDIR(tif);
XTIFFDirectory *xd = &xt->xtif_dir;
/* Install the extended Tag field info */
_TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
/* Install the extended Tag field info */
_TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
/*
* free up any dynamically allocated arrays
* before the new directory is read in.
*/
_XTIFFFreeDirectory(xt);
_TIFFmemset(xt,0,sizeof(xtiff));
/*
* free up any dynamically allocated arrays
* before the new directory is read in.
*/
/* Override the tag access methods */
_XTIFFFreeDirectory(xt);
_TIFFmemset(xt, 0, sizeof(xtiff));
PARENT(xt,vsetfield) = TIFFMEMBER(tif,vsetfield);
TIFFMEMBER(tif,vsetfield) = _XTIFFVSetField;
PARENT(xt,vgetfield) = TIFFMEMBER(tif,vgetfield);
TIFFMEMBER(tif,vgetfield) = _XTIFFVGetField;
/* Override the tag access methods */
/*
* XXX Set up any default values here.
*/
xd->xd_example_single = 234;
PARENT(xt, vsetfield) = TIFFMEMBER(tif, vsetfield);
TIFFMEMBER(tif, vsetfield) = _XTIFFVSetField;
PARENT(xt, vgetfield) = TIFFMEMBER(tif, vgetfield);
TIFFMEMBER(tif, vgetfield) = _XTIFFVGetField;
/*
* XXX Set up any default values here.
*/
xd->xd_example_single = 234;
}
/**********************************************************************
* Nothing below this line should need to be changed.
**********************************************************************/
@@ -250,39 +247,37 @@ static TIFFExtendProc _ParentExtender;
* every time a new TIFF directory is opened.
*/
static void
_XTIFFDefaultDirectory(TIFF *tif)
static void _XTIFFDefaultDirectory(TIFF *tif)
{
xtiff *xt;
/* Allocate Directory Structure if first time, and install it */
if (!(tif->tif_flags & XTIFF_INITIALIZED))
{
xt = _TIFFmalloc(sizeof(xtiff));
if (!xt)
{
/* handle memory allocation failure here ! */
return;
}
_TIFFmemset(xt,0,sizeof(xtiff));
/*
* Install into TIFF structure.
*/
TIFFMEMBER(tif,clientdir) = (tidata_t)xt;
tif->tif_flags |= XTIFF_INITIALIZED; /* don't do this again! */
}
/* set up our own defaults */
_XTIFFLocalDefaultDirectory(tif);
xtiff *xt;
/* Since an XTIFF client module may have overridden
* the default directory method, we call it now to
* allow it to set up the rest of its own methods.
/* Allocate Directory Structure if first time, and install it */
if (!(tif->tif_flags & XTIFF_INITIALIZED))
{
xt = _TIFFmalloc(sizeof(xtiff));
if (!xt)
{
/* handle memory allocation failure here ! */
return;
}
_TIFFmemset(xt, 0, sizeof(xtiff));
/*
* Install into TIFF structure.
*/
TIFFMEMBER(tif, clientdir) = (tidata_t)xt;
tif->tif_flags |= XTIFF_INITIALIZED; /* don't do this again! */
}
if (_ParentExtender)
(*_ParentExtender)(tif);
/* set up our own defaults */
_XTIFFLocalDefaultDirectory(tif);
/* Since an XTIFF client module may have overridden
* the default directory method, we call it now to
* allow it to set up the rest of its own methods.
*/
if (_ParentExtender)
(*_ParentExtender)(tif);
}
/*
@@ -290,54 +285,49 @@ _XTIFFDefaultDirectory(TIFF *tif)
* procedure for the TIFF module.
*/
static
void _XTIFFInitialize(void)
static void _XTIFFInitialize(void)
{
static first_time=1;
if (! first_time) return; /* Been there. Done that. */
first_time = 0;
/* Grab the inherited method and install */
_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
}
static first_time = 1;
if (!first_time)
return; /* Been there. Done that. */
first_time = 0;
/* Grab the inherited method and install */
_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
}
/*
* Public File I/O Routines.
*/
TIFF*
XTIFFOpen(const char* name, const char* mode)
TIFF *XTIFFOpen(const char *name, const char *mode)
{
/* Set up the callback */
_XTIFFInitialize();
/* Open the file; the callback will set everything up
*/
return TIFFOpen(name, mode);
/* Set up the callback */
_XTIFFInitialize();
/* Open the file; the callback will set everything up
*/
return TIFFOpen(name, mode);
}
TIFF*
XTIFFFdOpen(int fd, const char* name, const char* mode)
TIFF *XTIFFFdOpen(int fd, const char *name, const char *mode)
{
/* Set up the callback */
_XTIFFInitialize();
/* Set up the callback */
_XTIFFInitialize();
/* Open the file; the callback will set everything up
*/
return TIFFFdOpen(fd, name, mode);
/* Open the file; the callback will set everything up
*/
return TIFFFdOpen(fd, name, mode);
}
void
XTIFFClose(TIFF *tif)
void XTIFFClose(TIFF *tif)
{
xtiff *xt = XTIFFDIR(tif);
/* call inherited function first */
TIFFClose(tif);
/* Free up extended allocated memory */
_XTIFFFreeDirectory(xt);
_TIFFfree(xt);
xtiff *xt = XTIFFDIR(tif);
/* call inherited function first */
TIFFClose(tif);
/* Free up extended allocated memory */
_XTIFFFreeDirectory(xt);
_TIFFfree(xt);
}

View File

@@ -14,35 +14,36 @@
#include "tiffio.h"
/*
* XXX Define your private Tag names and values here
/*
* XXX Define your private Tag names and values here
*/
/* These tags are not valid, but are provided for example */
#define TIFFTAG_EXAMPLE_MULTI 61234
#define TIFFTAG_EXAMPLE_SINGLE 61235
#define TIFFTAG_EXAMPLE_ASCII 61236
#define TIFFTAG_EXAMPLE_MULTI 61234
#define TIFFTAG_EXAMPLE_SINGLE 61235
#define TIFFTAG_EXAMPLE_ASCII 61236
/*
/*
* XXX Define Printing method flags. These
* flags may be passed in to TIFFPrintDirectory() to
* indicate that those particular field values should
* be printed out in full, rather than just an indicator
* of whether they are present or not.
*/
#define TIFFPRINT_MYMULTIDOUBLES 0x80000000
#define TIFFPRINT_MYMULTIDOUBLES 0x80000000
/**********************************************************************
* Nothing below this line should need to be changed by the user.
**********************************************************************/
#if defined(__cplusplus)
extern "C" {
extern "C"
{
#endif
extern TIFF* XTIFFOpen(const char* name, const char* mode);
extern TIFF* XTIFFFdOpen(int fd, const char* name, const char* mode);
extern void XTIFFClose(TIFF *tif);
extern TIFF *XTIFFOpen(const char *name, const char *mode);
extern TIFF *XTIFFFdOpen(int fd, const char *name, const char *mode);
extern void XTIFFClose(TIFF *tif);
#if defined(__cplusplus)
}

View File

@@ -22,20 +22,20 @@
/* XXX - Define number of your extended tags here */
#define NUM_XFIELD 3
#define XFIELD_BASE (FIELD_LAST-NUM_XFIELD)
#define XFIELD_BASE (FIELD_LAST - NUM_XFIELD)
/* XXX - Define your Tag Fields here */
#define FIELD_EXAMPLE_MULTI (XFIELD_BASE+0)
#define FIELD_EXAMPLE_SINGLE (XFIELD_BASE+1)
#define FIELD_EXAMPLE_ASCII (XFIELD_BASE+2)
#define FIELD_EXAMPLE_MULTI (XFIELD_BASE + 0)
#define FIELD_EXAMPLE_SINGLE (XFIELD_BASE + 1)
#define FIELD_EXAMPLE_ASCII (XFIELD_BASE + 2)
/* XXX - Define Private directory tag structure here */
struct XTIFFDirectory {
uint16_t xd_num_multi; /* dir-count for the multi tag */
double* xd_example_multi;
uint32_t xd_example_single;
char* xd_example_ascii;
struct XTIFFDirectory
{
uint16_t xd_num_multi; /* dir-count for the multi tag */
double *xd_example_multi;
uint32_t xd_example_single;
char *xd_example_ascii;
};
typedef struct XTIFFDirectory XTIFFDirectory;
@@ -43,23 +43,23 @@ typedef struct XTIFFDirectory XTIFFDirectory;
* Nothing below this line should need to be changed by the user.
**********************************************************************/
struct xtiff {
TIFF *xtif_tif; /* parent TIFF pointer */
uint32_t xtif_flags;
#define XTIFFP_PRINT 0x00000001
XTIFFDirectory xtif_dir; /* internal rep of current directory */
TIFFVSetMethod xtif_vsetfield; /* inherited tag set routine */
TIFFVGetMethod xtif_vgetfield; /* inherited tag get routine */
TIFFPrintMethod xtif_printdir; /* inherited dir print method */
struct xtiff
{
TIFF *xtif_tif; /* parent TIFF pointer */
uint32_t xtif_flags;
#define XTIFFP_PRINT 0x00000001
XTIFFDirectory xtif_dir; /* internal rep of current directory */
TIFFVSetMethod xtif_vsetfield; /* inherited tag set routine */
TIFFVGetMethod xtif_vgetfield; /* inherited tag get routine */
TIFFPrintMethod xtif_printdir; /* inherited dir print method */
};
typedef struct xtiff xtiff;
#define PARENT(xt, pmember) ((xt)->xtif_##pmember)
#define TIFFMEMBER(tf, pmember) ((tf)->tif_##pmember)
#define XTIFFDIR(tif) ((xtiff *)TIFFMEMBER(tif, clientdir))
#define PARENT(xt,pmember) ((xt)->xtif_ ## pmember)
#define TIFFMEMBER(tf,pmember) ((tf)->tif_ ## pmember)
#define XTIFFDIR(tif) ((xtiff *)TIFFMEMBER(tif,clientdir))
/* Extended TIFF flags */
#define XTIFF_INITIALIZED 0x80000000
#endif /* __xtiffiop_h */

View File

@@ -1,11 +1,11 @@
#include "StdAfx.h"
//#define STRICT
// #define STRICT
#include "diblib.h"
#include <commdlg.h>
#include <stdlib.h> // MAX_ constants
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <stdlib.h> // MAX_ constants
#include "diblib.h"
/*--------------------------------------------------------------------
READ TIFF
@@ -31,44 +31,42 @@
#include <assert.h>
#include <stdio.h>
// piggyback some data on top of the RGBA Image
struct TIFFDibImage {
struct TIFFDibImage
{
TIFFRGBAImage tif;
int dibinstalled;
} ;
int dibinstalled;
};
HANDLE LoadTIFFinDIB(LPCTSTR lpFileName);
HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster) ;
HANDLE TIFFRGBA2DIB(TIFFDibImage *dib, uint32_t *raster);
static void
MyWarningHandler(const char* module, const char* fmt, va_list ap)
static void MyWarningHandler(const char *module, const char *fmt, va_list ap)
{
// ignore all warnings (unused tags, etc)
return;
}
static void
MyErrorHandler(const char* module, const char* fmt, va_list ap)
static void MyErrorHandler(const char *module, const char *fmt, va_list ap)
{
return;
}
// Turn off the error and warning handlers to check if a valid file.
// Necessary because of the way that the Doc loads images and restart files.
int ChkTIFF ( LPCTSTR lpszPath )
int ChkTIFF(LPCTSTR lpszPath)
{
int rtn = 0;
TIFFErrorHandler eh;
TIFFErrorHandler wh;
TIFFErrorHandler eh;
TIFFErrorHandler wh;
eh = TIFFSetErrorHandler(NULL);
wh = TIFFSetWarningHandler(NULL);
TIFF* tif = TIFFOpen(lpszPath, "r");
if (tif) {
TIFF *tif = TIFFOpen(lpszPath, "r");
if (tif)
{
rtn = 1;
TIFFClose(tif);
}
@@ -79,34 +77,42 @@ int ChkTIFF ( LPCTSTR lpszPath )
return rtn;
}
void DibInstallHack(TIFFDibImage* img) ;
void DibInstallHack(TIFFDibImage *img);
PVOID ReadTIFF ( LPCTSTR lpszPath )
PVOID ReadTIFF(LPCTSTR lpszPath)
{
void* pDIB = 0;
TIFFErrorHandler wh;
void *pDIB = 0;
TIFFErrorHandler wh;
wh = TIFFSetWarningHandler(MyWarningHandler);
if (ChkTIFF(lpszPath)) {
TIFF* tif = TIFFOpen(lpszPath, "r");
if (tif) {
if (ChkTIFF(lpszPath))
{
TIFF *tif = TIFFOpen(lpszPath, "r");
if (tif)
{
char emsg[1024];
if (TIFFRGBAImageOK(tif, emsg)) {
if (TIFFRGBAImageOK(tif, emsg))
{
TIFFDibImage img;
char emsg[1024];
if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg)) {
if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg))
{
size_t npixels;
uint32_t* raster;
uint32_t *raster;
DibInstallHack(&img);
npixels = img.tif.width * img.tif.height;
raster = (uint32_t*) _TIFFmalloc(npixels * sizeof (uint32_t));
if (raster != NULL) {
if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width, img.tif.height)) {
raster =
(uint32_t *)_TIFFmalloc(npixels * sizeof(uint32_t));
if (raster != NULL)
{
if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width,
img.tif.height))
{
pDIB = TIFFRGBA2DIB(&img, raster);
}
}
@@ -114,8 +120,9 @@ PVOID ReadTIFF ( LPCTSTR lpszPath )
}
TIFFRGBAImageEnd(&img.tif);
}
else {
TRACE("Unable to open image(%s): %s\n", lpszPath, emsg );
else
{
TRACE("Unable to open image(%s): %s\n", lpszPath, emsg);
}
TIFFClose(tif);
}
@@ -126,12 +133,10 @@ PVOID ReadTIFF ( LPCTSTR lpszPath )
return pDIB;
}
HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
HANDLE TIFFRGBA2DIB(TIFFDibImage *dib, uint32_t *raster)
{
void* pDIB = 0;
TIFFRGBAImage* img = &dib->tif;
void *pDIB = 0;
TIFFRGBAImage *img = &dib->tif;
uint32_t imageLength;
uint32_t imageWidth;
@@ -140,8 +145,8 @@ HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
uint32_t RowsPerStrip;
uint16_t PhotometricInterpretation;
BITMAPINFOHEADER bi;
int dwDIBSize ;
BITMAPINFOHEADER bi;
int dwDIBSize;
TIFFGetField(img->tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
TIFFGetField(img->tif, TIFFTAG_IMAGELENGTH, &imageLength);
@@ -150,91 +155,97 @@ HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
TIFFGetField(img->tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
TIFFGetField(img->tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
if ( BitsPerSample == 1 && SamplePerPixel == 1 && dib->dibinstalled ) { // bilevel
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = imageWidth;
bi.biHeight = imageLength;
bi.biPlanes = 1; // always
bi.biBitCount = 1;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0; // must be zero for RGB compression (none)
bi.biClrImportant = 0; // always
if (BitsPerSample == 1 && SamplePerPixel == 1 && dib->dibinstalled)
{ // bilevel
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = imageWidth;
bi.biHeight = imageLength;
bi.biPlanes = 1; // always
bi.biBitCount = 1;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0; // must be zero for RGB compression (none)
bi.biClrImportant = 0; // always
// Get the size of the DIB
dwDIBSize = GetDIBSize( &bi );
dwDIBSize = GetDIBSize(&bi);
// Allocate for the BITMAPINFO structure and the color table.
pDIB = GlobalAllocPtr( GHND, dwDIBSize );
if (pDIB == 0) {
return( NULL );
pDIB = GlobalAllocPtr(GHND, dwDIBSize);
if (pDIB == 0)
{
return (NULL);
}
// Copy the header info
*((BITMAPINFOHEADER*)pDIB) = bi;
*((BITMAPINFOHEADER *)pDIB) = bi;
// Get a pointer to the color table
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
pRgbq[0].rgbRed = 0;
pRgbq[0].rgbBlue = 0;
pRgbq[0].rgbGreen = 0;
pRgbq[0].rgbRed = 0;
pRgbq[0].rgbBlue = 0;
pRgbq[0].rgbGreen = 0;
pRgbq[0].rgbReserved = 0;
pRgbq[1].rgbRed = 255;
pRgbq[1].rgbBlue = 255;
pRgbq[1].rgbGreen = 255;
pRgbq[1].rgbRed = 255;
pRgbq[1].rgbBlue = 255;
pRgbq[1].rgbGreen = 255;
pRgbq[1].rgbReserved = 255;
// Pointers to the bits
//PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
// PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
//
// In the BITMAPINFOHEADER documentation, it appears that
// there should be no color table for 32 bit images, but
// experience shows that the image is off by 3 words if it
// is not included. So here it is.
PVOID pbiBits = GetDIBImagePtr((BITMAPINFOHEADER*)pDIB); //(LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
PVOID pbiBits = GetDIBImagePtr(
(BITMAPINFOHEADER *)pDIB); //(LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
int sizeWords = bi.biSizeImage/4;
RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
long* rgbTif = (long*)raster;
int sizeWords = bi.biSizeImage / 4;
RGBQUAD *rgbDib = (RGBQUAD *)pbiBits;
long *rgbTif = (long *)raster;
_TIFFmemcpy(pbiBits, raster, bi.biSizeImage);
}
// For now just always default to the RGB 32 bit form. // save as 32 bit for simplicity
else if ( true /*BitsPerSample == 8 && SamplePerPixel == 3*/ ) { // 24 bit color
// For now just always default to the RGB 32 bit form. // save as 32 bit
// for simplicity
else if (true /*BitsPerSample == 8 && SamplePerPixel == 3*/)
{ // 24 bit color
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = imageWidth;
bi.biHeight = imageLength;
bi.biPlanes = 1; // always
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0; // must be zero for RGB compression (none)
bi.biClrImportant = 0; // always
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = imageWidth;
bi.biHeight = imageLength;
bi.biPlanes = 1; // always
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0; // must be zero for RGB compression (none)
bi.biClrImportant = 0; // always
// Get the size of the DIB
dwDIBSize = GetDIBSize( &bi );
dwDIBSize = GetDIBSize(&bi);
// Allocate for the BITMAPINFO structure and the color table.
pDIB = GlobalAllocPtr( GHND, dwDIBSize );
if (pDIB == 0) {
return( NULL );
pDIB = GlobalAllocPtr(GHND, dwDIBSize);
if (pDIB == 0)
{
return (NULL);
}
// Copy the header info
*((BITMAPINFOHEADER*)pDIB) = bi;
*((BITMAPINFOHEADER *)pDIB) = bi;
// Get a pointer to the color table
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
// Pointers to the bits
//PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
// PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
//
// In the BITMAPINFOHEADER documentation, it appears that
// there should be no color table for 32 bit images, but
@@ -242,15 +253,15 @@ HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
// is not included. So here it is.
PVOID pbiBits = (LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
int sizeWords = bi.biSizeImage/4;
RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
long* rgbTif = (long*)raster;
int sizeWords = bi.biSizeImage / 4;
RGBQUAD *rgbDib = (RGBQUAD *)pbiBits;
long *rgbTif = (long *)raster;
// Swap the byte order while copying
for ( int i = 0 ; i < sizeWords ; ++i )
for (int i = 0; i < sizeWords; ++i)
{
rgbDib[i].rgbRed = TIFFGetR(rgbTif[i]);
rgbDib[i].rgbBlue = TIFFGetB(rgbTif[i]);
rgbDib[i].rgbRed = TIFFGetR(rgbTif[i]);
rgbDib[i].rgbBlue = TIFFGetB(rgbTif[i]);
rgbDib[i].rgbGreen = TIFFGetG(rgbTif[i]);
rgbDib[i].rgbReserved = 0;
}
@@ -259,9 +270,6 @@ HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
return pDIB;
}
///////////////////////////////////////////////////////////////
//
// Hacked from tif_getimage.c in libtiff in v3.5.7
@@ -269,49 +277,42 @@ HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32_t* raster)
//
typedef unsigned char u_char;
#define DECLAREContigPutFunc(name) \
static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \
uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \
u_char *pp)
#define DECLAREContigPutFunc(name) \
static void name(\
TIFFRGBAImage* img, \
uint32_t* cp, \
uint32_t x, uint32_t y, \
uint32_t w, uint32_t h, \
int32_t fromskew, int32_t toskew, \
u_char* pp \
)
#define DECLARESepPutFunc(name) \
static void name(\
TIFFRGBAImage* img,\
uint32_t* cp,\
uint32_t x, uint32_t y, \
uint32_t w, uint32_t h,\
int32_t fromskew, int32_t toskew,\
u_char* r, u_char* g, u_char* b, u_char* a\
)
#define DECLARESepPutFunc(name) \
static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \
uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \
u_char *r, u_char *g, u_char *b, u_char *a)
DECLAREContigPutFunc(putContig1bitTile);
static int getStripContig1Bit(TIFFRGBAImage* img, uint32_t* uraster, uint32_t w, uint32_t h);
static int getStripContig1Bit(TIFFRGBAImage *img, uint32_t *uraster, uint32_t w,
uint32_t h);
//typdef struct TIFFDibImage {
// TIFFRGBAImage tif;
// dibinstalled;
//} TIFFDibImage ;
// typdef struct TIFFDibImage {
// TIFFRGBAImage tif;
// dibinstalled;
// } TIFFDibImage ;
void DibInstallHack(TIFFDibImage* dib) {
TIFFRGBAImage* img = &dib->tif;
void DibInstallHack(TIFFDibImage *dib)
{
TIFFRGBAImage *img = &dib->tif;
dib->dibinstalled = false;
switch (img->photometric) {
switch (img->photometric)
{
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
switch (img->bitspersample) {
case 1:
img->put.contig = putContig1bitTile;
img->get = getStripContig1Bit;
dib->dibinstalled = true;
break;
}
break;
switch (img->bitspersample)
{
case 1:
img->put.contig = putContig1bitTile;
img->get = getStripContig1Bit;
dib->dibinstalled = true;
break;
}
break;
}
}
@@ -324,15 +325,16 @@ DECLAREContigPutFunc(putContig1bitTile)
{
int samplesperpixel = img->samplesperpixel;
(void) y;
(void)y;
fromskew *= samplesperpixel;
int wb = WIDTHBYTES(w);
u_char* ucp = (u_char*)cp;
u_char *ucp = (u_char *)cp;
/* Convert 'w' to bytes from pixels (rounded up) */
w = (w+7)/8;
w = (w + 7) / 8;
while (h-- > 0) {
while (h-- > 0)
{
_TIFFmemcpy(ucp, pp, w);
/*
for (x = wb; x-- > 0;) {
@@ -348,32 +350,32 @@ DECLAREContigPutFunc(putContig1bitTile)
/*
* Hacked from the tif_getimage.c file.
*/
static uint32_t
setorientation(TIFFRGBAImage* img, uint32_t h)
static uint32_t setorientation(TIFFRGBAImage *img, uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
uint32_t y;
switch (img->orientation) {
case ORIENTATION_BOTRIGHT:
case ORIENTATION_RIGHTBOT: /* XXX */
case ORIENTATION_LEFTBOT: /* XXX */
TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
img->orientation = ORIENTATION_BOTLEFT;
/* fall through... */
case ORIENTATION_BOTLEFT:
y = 0;
break;
case ORIENTATION_TOPRIGHT:
case ORIENTATION_RIGHTTOP: /* XXX */
case ORIENTATION_LEFTTOP: /* XXX */
default:
TIFFWarning(TIFFFileName(tif), "using top-left orientation");
img->orientation = ORIENTATION_TOPLEFT;
/* fall through... */
case ORIENTATION_TOPLEFT:
y = h-1;
break;
switch (img->orientation)
{
case ORIENTATION_BOTRIGHT:
case ORIENTATION_RIGHTBOT: /* XXX */
case ORIENTATION_LEFTBOT: /* XXX */
TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
img->orientation = ORIENTATION_BOTLEFT;
/* fall through... */
case ORIENTATION_BOTLEFT:
y = 0;
break;
case ORIENTATION_TOPRIGHT:
case ORIENTATION_RIGHTTOP: /* XXX */
case ORIENTATION_LEFTTOP: /* XXX */
default:
TIFFWarning(TIFFFileName(tif), "using top-left orientation");
img->orientation = ORIENTATION_TOPLEFT;
/* fall through... */
case ORIENTATION_TOPLEFT:
y = h - 1;
break;
}
return (y);
}
@@ -389,52 +391,55 @@ setorientation(TIFFRGBAImage* img, uint32_t h)
* This is set up to allow us to just copy the data to the raster
* for 1-bit bitmaps
*/
static int
getStripContig1Bit(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h)
static int getStripContig1Bit(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
uint32_t h)
{
TIFF* tif = img->tif;
TIFF *tif = img->tif;
tileContigRoutine put = img->put.contig;
uint16_t orientation;
uint32_t row, y, nrow, rowstoread;
uint32_t pos;
u_char* buf;
u_char *buf;
uint32_t rowsperstrip;
uint32_t imagewidth = img->width;
tsize_t scanline;
int32_t fromskew, toskew;
tstrip_t strip;
tsize_t stripsize;
u_char* braster = (u_char*)raster; // byte wide raster
uint32_t wb = WIDTHBYTES(w);
tsize_t stripsize;
u_char *braster = (u_char *)raster; // byte wide raster
uint32_t wb = WIDTHBYTES(w);
int ret = 1;
buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
if (buf == 0) {
buf = (u_char *)_TIFFmalloc(TIFFStripSize(tif));
if (buf == 0)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
return (0);
}
y = setorientation(img, h);
orientation = img->orientation;
toskew = -(int32_t) (orientation == ORIENTATION_TOPLEFT ? wb+wb : wb-wb);
toskew = -(int32_t)(orientation == ORIENTATION_TOPLEFT ? wb + wb : wb - wb);
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
scanline = TIFFScanlineSize(tif);
fromskew = (w < imagewidth ? imagewidth - w : 0)/8;
fromskew = (w < imagewidth ? imagewidth - w : 0) / 8;
for (row = 0; row < h; row += nrow)
{
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
strip = TIFFComputeStrip(tif,row+img->row_offset, 0);
stripsize = ((row + img->row_offset)%rowsperstrip + nrow) * scanline;
if (TIFFReadEncodedStrip(tif, strip, buf, stripsize ) < 0
&& img->stoponerr)
strip = TIFFComputeStrip(tif, row + img->row_offset, 0);
stripsize = ((row + img->row_offset) % rowsperstrip + nrow) * scanline;
if (TIFFReadEncodedStrip(tif, strip, buf, stripsize) < 0 &&
img->stoponerr)
{
ret = 0;
break;
}
pos = ((row + img->row_offset) % rowsperstrip) * scanline;
(*put)(img, (uint32_t*)(braster+y*wb), 0, y, w, nrow, fromskew, toskew, buf + pos);
y += (orientation == ORIENTATION_TOPLEFT ?-(int32_t) nrow : (int32_t) nrow);
(*put)(img, (uint32_t *)(braster + y * wb), 0, y, w, nrow, fromskew,
toskew, buf + pos);
y += (orientation == ORIENTATION_TOPLEFT ? -(int32_t)nrow
: (int32_t)nrow);
}
_TIFFfree(buf);
return (ret);

View File

@@ -1,42 +1,39 @@
/*************************************************************************
*
* Source file for Windows 95/Win32.
* Source file for Windows 95/Win32.
*
* The function LoadTIFFinDIB in this source file let you load
* a TIFF file and build a memory DIB with it and return the
* The function LoadTIFFinDIB in this source file let you load
* a TIFF file and build a memory DIB with it and return the
* HANDLE (HDIB) of the memory block containing the DIB.
*
* Example :
*
* Example :
*
* HDIB hDIB;
* hDIB = LoadTIFFinDIB("sample.tif");
*
*
* To build this source file you must include the TIFF library
* To build this source file you must include the TIFF library
* in your project.
*
* 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com
*
************************************************************************/
#include "tiffio.h"
#include "tiffio.h"
#define HDIB HANDLE
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
#define CVT(x) (((x)*255L) / ((1L << 16) - 1))
static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount);
static LPSTR FindDIBBits(LPSTR lpDIB);
static WORD PaletteSize(LPSTR lpDIB);
static WORD DIBNumColors(LPSTR lpDIB);
static int checkcmap(int n, uint16_t* r, uint16_t* g, uint16_t* b);
static int checkcmap(int n, uint16_t *r, uint16_t *g, uint16_t *b);
/*************************************************************************
*
* HDIB LoadTIFFinDIB(LPSTR lpFileName)
* HDIB LoadTIFFinDIB(LPSTR lpFileName)
*
* Parameter:
*
@@ -56,181 +53,173 @@ static int checkcmap(int n, uint16_t* r, uint16_t* g, uint16_t* b);
*
************************************************************************/
HDIB LoadTIFFinDIB(LPSTR lpFileName)
HDIB LoadTIFFinDIB(LPSTR lpFileName)
{
TIFF *tif;
unsigned long imageLength;
unsigned long imageWidth;
unsigned int BitsPerSample;
TIFF *tif;
unsigned long imageLength;
unsigned long imageWidth;
unsigned int BitsPerSample;
unsigned long LineSize;
unsigned int SamplePerPixel;
unsigned long RowsPerStrip;
int PhotometricInterpretation;
long nrow;
unsigned long row;
char *buf;
LPBITMAPINFOHEADER lpDIB;
HDIB hDIB;
char *lpBits;
HGLOBAL hStrip;
int i,l;
int Align;
unsigned int SamplePerPixel;
unsigned long RowsPerStrip;
int PhotometricInterpretation;
long nrow;
unsigned long row;
char *buf;
LPBITMAPINFOHEADER lpDIB;
HDIB hDIB;
char *lpBits;
HGLOBAL hStrip;
int i, l;
int Align;
tif = TIFFOpen(lpFileName, "r");
if (!tif)
goto TiffOpenError;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
LineSize = TIFFScanlineSize(tif); //Number of byte in ine line
SamplePerPixel = (int) (LineSize/imageWidth);
LineSize = TIFFScanlineSize(tif); // Number of byte in ine line
//Align = Number of byte to add at the end of each line of the DIB
SamplePerPixel = (int)(LineSize / imageWidth);
// Align = Number of byte to add at the end of each line of the DIB
Align = 4 - (LineSize % 4);
if (Align == 4) Align = 0;
if (Align == 4)
Align = 0;
//Create a new DIB
hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
(BitsPerSample*SamplePerPixel));
lpDIB = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
// Create a new DIB
hDIB = CreateDIB((DWORD)imageWidth, (DWORD)imageLength,
(WORD)(BitsPerSample * SamplePerPixel));
lpDIB = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
if (!lpDIB)
goto OutOfDIBMemory;
if (lpDIB)
lpBits = FindDIBBits((LPSTR) lpDIB);
else
lpBits = NULL;
goto OutOfDIBMemory;
//In the tiff file the lines are save from up to down
//In a DIB the lines must be save from down to up
if (lpDIB)
lpBits = FindDIBBits((LPSTR)lpDIB);
else
lpBits = NULL;
// In the tiff file the lines are save from up to down
// In a DIB the lines must be save from down to up
if (lpBits)
{
lpBits = FindDIBBits((LPSTR) lpDIB);
lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
//now lpBits pointe on the bottom line
hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
buf = GlobalLock(hStrip);
{
lpBits = FindDIBBits((LPSTR)lpDIB);
lpBits += ((imageWidth * SamplePerPixel) + Align) * (imageLength - 1);
// now lpBits pointe on the bottom line
hStrip = GlobalAlloc(GHND, TIFFStripSize(tif));
buf = GlobalLock(hStrip);
if (!buf)
goto OutOfBufMemory;
//PhotometricInterpretation = 2 image is RGB
//PhotometricInterpretation = 3 image have a color palette
goto OutOfBufMemory;
// PhotometricInterpretation = 2 image is RGB
// PhotometricInterpretation = 3 image have a color palette
if (PhotometricInterpretation == 3)
{
uint16_t* red;
uint16_t* green;
uint16_t* blue;
int16_t i;
LPBITMAPINFO lpbmi;
int Palette16Bits;
TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
uint16_t *red;
uint16_t *green;
uint16_t *blue;
int16_t i;
LPBITMAPINFO lpbmi;
int Palette16Bits;
//Is the palette 16 or 8 bits ?
if (checkcmap(1<<BitsPerSample, red, green, blue) == 16)
Palette16Bits = TRUE;
else
Palette16Bits = FALSE;
lpbmi = (LPBITMAPINFO)lpDIB;
//load the palette in the DIB
for (i = (1<<BitsPerSample)-1; i >= 0; i--)
{
if (Palette16Bits)
{
lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]);
lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]);
lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]);
}
else
{
lpbmi->bmiColors[i].rgbRed = (BYTE) red[i];
lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i];
lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i];
}
}
}
//read the tiff lines and save them in the DIB
//with RGB mode, we have to change the order of the 3 samples RGB
<=> BGR
for (row = 0; row < imageLength; row += RowsPerStrip)
{
nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
RowsPerStrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
buf, nrow*LineSize)==-1)
{
goto TiffReadError;
}
TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
// Is the palette 16 or 8 bits ?
if (checkcmap(1 << BitsPerSample, red, green, blue) == 16)
Palette16Bits = TRUE;
else
{
for (l = 0; l < nrow; l++)
{
if (SamplePerPixel == 3)
for (i=0;i< (int) (imageWidth);i++)
{
lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
PerPixel+2];
lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
PerPixel+1];
lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
PerPixel+0];
}
else
memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
imageWidth*SamplePerPixel);
lpBits-=imageWidth*SamplePerPixel+Align;
Palette16Bits = FALSE;
}
}
}
lpbmi = (LPBITMAPINFO)lpDIB;
// load the palette in the DIB
for (i = (1 << BitsPerSample) - 1; i >= 0; i--)
{
if (Palette16Bits)
{
lpbmi->bmiColors[i].rgbRed = (BYTE)CVT(red[i]);
lpbmi->bmiColors[i].rgbGreen = (BYTE)CVT(green[i]);
lpbmi->bmiColors[i].rgbBlue = (BYTE)CVT(blue[i]);
}
else
{
lpbmi->bmiColors[i].rgbRed = (BYTE)red[i];
lpbmi->bmiColors[i].rgbGreen = (BYTE)green[i];
lpbmi->bmiColors[i].rgbBlue = (BYTE)blue[i];
}
}
}
// read the tiff lines and save them in the DIB
// with RGB mode, we have to change the order of the 3 samples RGB
<=> BGR for (row = 0; row < imageLength; row += RowsPerStrip)
{
nrow = (row + RowsPerStrip > imageLength ? imageLength - row
: RowsPerStrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf,
nrow * LineSize) == -1)
{
goto TiffReadError;
}
else
{
for (l = 0; l < nrow; l++)
{
if (SamplePerPixel == 3)
for (i = 0; i < (int)(imageWidth); i++)
{
lpBits[i * SamplePerPixel + 0] =
buf[l * LineSize + i * Sample PerPixel + 2];
lpBits[i * SamplePerPixel + 1] =
buf[l * LineSize + i * Sample PerPixel + 1];
lpBits[i * SamplePerPixel + 2] =
buf[l * LineSize + i * Sample PerPixel + 0];
}
else
memcpy(lpBits, &buf[(int)(l * LineSize)],
(int)imageWidth * SamplePerPixel);
lpBits -= imageWidth * SamplePerPixel + Align;
}
}
}
GlobalUnlock(hStrip);
GlobalFree(hStrip);
GlobalUnlock(hDIB);
GlobalUnlock(hDIB);
TIFFClose(tif);
}
}
return hDIB;
OutOfBufMemory:
TiffReadError:
GlobalUnlock(hDIB);
GlobalFree(hStrip);
OutOfDIBMemory:
TIFFClose(tif);
TiffOpenError:
return (HANDLE) 0;
OutOfBufMemory:
TiffReadError:
GlobalUnlock(hDIB);
GlobalFree(hStrip);
OutOfDIBMemory:
TIFFClose(tif);
TiffOpenError:
return (HANDLE)0;
}
static int checkcmap(int n, uint16_t* r, uint16_t* g, uint16_t* b)
static int checkcmap(int n, uint16_t *r, uint16_t *g, uint16_t *b)
{
while (n-- > 0)
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
return (16);
return (16);
return (8);
}
/*************************************************************************
* All the following functions were created by microsoft, they are
* parts of the sample project "wincap" given with the SDK Win32.
@@ -247,128 +236,124 @@ static int checkcmap(int n, uint16_t* r, uint16_t* g, uint16_t* b)
HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
{
BITMAPINFOHEADER bi; // bitmap header
LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER
DWORD dwLen; // size of memory block
HDIB hDIB;
DWORD dwBytesPerLine; // Number of bytes per scanline
BITMAPINFOHEADER bi; // bitmap header
LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER
DWORD dwLen; // size of memory block
HDIB hDIB;
DWORD dwBytesPerLine; // Number of bytes per scanline
// Make sure bits per pixel is valid
if (wBitCount <= 1)
wBitCount = 1;
else if (wBitCount <= 4)
wBitCount = 4;
else if (wBitCount <= 8)
wBitCount = 8;
else if (wBitCount <= 24)
wBitCount = 24;
else
wBitCount = 4; // set default value to 4 if parameter is bogus
// Make sure bits per pixel is valid
if (wBitCount <= 1)
wBitCount = 1;
else if (wBitCount <= 4)
wBitCount = 4;
else if (wBitCount <= 8)
wBitCount = 8;
else if (wBitCount <= 24)
wBitCount = 24;
else
wBitCount = 4; // set default value to 4 if parameter is bogus
// initialize BITMAPINFOHEADER
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = dwWidth; // fill in width from parameter
bi.biHeight = dwHeight; // fill in height from parameter
bi.biPlanes = 1; // must be 1
bi.biBitCount = wBitCount; // from parameter
bi.biCompression = BI_RGB;
bi.biSizeImage =
(dwWidth * dwHeight * wBitCount) / 8; // 0; // 0's here
mean "default" bi.biXPelsPerMeter = 2834; // 0;
bi.biYPelsPerMeter = 2834; // 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// initialize BITMAPINFOHEADER
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = dwWidth; // fill in width from parameter
bi.biHeight = dwHeight; // fill in height from parameter
bi.biPlanes = 1; // must be 1
bi.biBitCount = wBitCount; // from parameter
bi.biCompression = BI_RGB;
bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0; // 0's here
mean "default"
bi.biXPelsPerMeter = 2834; //0;
bi.biYPelsPerMeter = 2834; //0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// calculate size of memory block required to store the DIB. This
// block should be big enough to hold the BITMAPINFOHEADER, the color
// table, and the bits
// calculate size of memory block required to store the DIB. This
// block should be big enough to hold the BITMAPINFOHEADER, the color
// table, and the bits
dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4);
dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight);
dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4);
dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight);
// alloc memory block to store our bitmap
hDIB = GlobalAlloc(GHND, dwLen);
// alloc memory block to store our bitmap
hDIB = GlobalAlloc(GHND, dwLen);
// major bummer if we couldn't get memory block
if (!hDIB)
{
return NULL;
}
// major bummer if we couldn't get memory block
if (!hDIB)
{
return NULL;
}
// lock memory and get pointer to it
lpbi = (VOID FAR *)GlobalLock(hDIB);
// lock memory and get pointer to it
lpbi = (VOID FAR *)GlobalLock(hDIB);
// use our bitmap info structure to fill in first part of
// our DIB with the BITMAPINFOHEADER
*lpbi = bi;
// use our bitmap info structure to fill in first part of
// our DIB with the BITMAPINFOHEADER
*lpbi = bi;
// Since we don't know what the colortable and bits should contain,
// just leave these blank. Unlock the DIB and return the HDIB.
// Since we don't know what the colortable and bits should contain,
// just leave these blank. Unlock the DIB and return the HDIB.
GlobalUnlock(hDIB);
GlobalUnlock(hDIB);
/* return handle to the DIB */
return hDIB;
/* return handle to the DIB */
return hDIB;
}
LPSTR FAR FindDIBBits(LPSTR lpDIB)
{
return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
}
WORD FAR PaletteSize(LPSTR lpDIB)
{
/* calculate the size required by the palette */
if (IS_WIN30_DIB (lpDIB))
return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
else
return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
/* calculate the size required by the palette */
if (IS_WIN30_DIB(lpDIB))
return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
else
return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
}
WORD DIBNumColors(LPSTR lpDIB)
{
WORD wBitCount; // DIB bit count
WORD wBitCount; // DIB bit count
/* If this is a Windows-style DIB, the number of colors in the
* color table can be less than the number of bits per pixel
* allows for (i.e. lpbi->biClrUsed can be set to some value).
* If this is the case, return the appropriate value.
*/
/* If this is a Windows-style DIB, the number of colors in the
* color table can be less than the number of bits per pixel
* allows for (i.e. lpbi->biClrUsed can be set to some value).
* If this is the case, return the appropriate value.
*/
if (IS_WIN30_DIB(lpDIB))
{
DWORD dwClrUsed;
if (IS_WIN30_DIB(lpDIB))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
if (dwClrUsed)
return (WORD)dwClrUsed;
}
dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
if (dwClrUsed)
return (WORD)dwClrUsed;
}
/* Calculate the number of colors in the color table based on
* the number of bits per pixel for the DIB.
*/
if (IS_WIN30_DIB(lpDIB))
wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
/* Calculate the number of colors in the color table based on
* the number of bits per pixel for the DIB.
*/
if (IS_WIN30_DIB(lpDIB))
wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
/* return number of colors based on bits per pixel */
switch (wBitCount)
{
case 1:
return 2;
/* return number of colors based on bits per pixel */
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 4:
return 16;
case 8:
return 256;
case 8:
return 256;
default:
return 0;
}
default:
return 0;
}
}

View File

@@ -2,9 +2,4 @@
* Dummy function, just to be ensure that the library always will be created.
*/
void
libport_dummy_function()
{
return;
}
void libport_dummy_function() { return; }

View File

@@ -32,92 +32,99 @@ static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
__RCSID("$NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $");
#endif
#include "libport.h"
#include <stdio.h>
#include <string.h>
#include "libport.h"
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(int argc, char * const argv[], const char *optstring)
int getopt(int argc, char *const argv[], const char *optstring)
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || *place == 0) { /* update scanning pointer */
optreset = 0;
place = argv[optind];
if (optind >= argc || *place++ != '-') {
/* Argument is absent or is not an option */
place = EMSG;
return (-1);
}
optopt = *place++;
if (optopt == '-' && *place == 0) {
/* "--" => end of options */
++optind;
place = EMSG;
return (-1);
}
if (optopt == 0) {
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
place = EMSG;
if (strchr(optstring, '-') == NULL)
return -1;
optopt = '-';
}
} else
optopt = *place++;
if (optreset || *place == 0)
{ /* update scanning pointer */
optreset = 0;
place = argv[optind];
if (optind >= argc || *place++ != '-')
{
/* Argument is absent or is not an option */
place = EMSG;
return (-1);
}
optopt = *place++;
if (optopt == '-' && *place == 0)
{
/* "--" => end of options */
++optind;
place = EMSG;
return (-1);
}
if (optopt == 0)
{
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
place = EMSG;
if (strchr(optstring, '-') == NULL)
return -1;
optopt = '-';
}
}
else
optopt = *place++;
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(optstring, optopt)) == NULL) {
if (*place == 0)
++optind;
if (opterr && *optstring != ':')
(void)fprintf(stderr,
"unknown option -- %c\n", optopt);
return (BADCH);
}
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(optstring, optopt)) == NULL)
{
if (*place == 0)
++optind;
if (opterr && *optstring != ':')
(void)fprintf(stderr, "unknown option -- %c\n", optopt);
return (BADCH);
}
/* Does this option need an argument? */
if (oli[1] != ':') {
/* don't need argument */
optarg = NULL;
if (*place == 0)
++optind;
} else {
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*place)
optarg = place;
else if (argc > ++optind)
optarg = argv[optind];
else {
/* option-argument absent */
place = EMSG;
if (*optstring == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"option requires an argument -- %c\n",
optopt);
return (BADCH);
}
place = EMSG;
++optind;
}
return (optopt); /* return option letter */
/* Does this option need an argument? */
if (oli[1] != ':')
{
/* don't need argument */
optarg = NULL;
if (*place == 0)
++optind;
}
else
{
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*place)
optarg = place;
else if (argc > ++optind)
optarg = argv[optind];
else
{
/* option-argument absent */
place = EMSG;
if (*optstring == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr, "option requires an argument -- %c\n",
optopt);
return (BADCH);
}
place = EMSG;
++optind;
}
return (optopt); /* return option letter */
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2009 Frank Warmerdam
*
* Permission to use, copy, modify, distribute, and sell this software and
* 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.
*
*
* 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,
@@ -22,21 +22,21 @@
*/
#ifndef _LIBPORT_
#define _LIBPORT_
#define _LIBPORT_
#include <libport_config.h>
#if HAVE_GETOPT
# if HAVE_UNISTD_H
# include <unistd.h>
# endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#else
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int opterr;
extern int optind;
extern int optopt;
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int opterr;
extern int optind;
extern int optopt;
#endif