mirror of
https://gitlab.com/libtiff/libtiff.git
synced 2026-01-18 21:51:18 +01:00
Reformatting in all other directories using 'pre-commit run'
This commit is contained in:
committed by
Even Rouault
parent
dee020782c
commit
aee0113f5e
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
157
port/getopt.c
157
port/getopt.c
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user