📄 tif_dir.c
字号:
/* $Id: tif_dir.c,v 1.4 2004/10/16 15:34:33 drolon Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* TIFF Library.
*
* Directory Tag Get & Set Routines.
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
/*
* These are used in the backwards compatibility code...
*/
#define DATATYPE_VOID 0 /* !untyped data */
#define DATATYPE_INT 1 /* !signed integer data */
#define DATATYPE_UINT 2 /* !unsigned integer data */
#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
static void
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
{
if (*vpp)
_TIFFfree(*vpp), *vpp = 0;
if (vp) {
tsize_t bytes = nmemb * elem_size;
if (elem_size && bytes / elem_size == nmemb)
*vpp = (void*) _TIFFmalloc(bytes);
if (*vpp)
_TIFFmemcpy(*vpp, vp, bytes);
}
}
void _TIFFsetByteArray(void** vpp, void* vp, long n)
{ setByteArray(vpp, vp, n, 1); }
void _TIFFsetString(char** cpp, char* cp)
{ setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
void _TIFFsetNString(char** cpp, char* cp, long n)
{ setByteArray((void**) cpp, (void*) cp, n, 1); }
void _TIFFsetShortArray(uint16** wpp, uint16* wp, long n)
{ setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
void _TIFFsetLongArray(uint32** lpp, uint32* lp, long n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
void _TIFFsetFloatArray(float** fpp, float* fp, long n)
{ setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
void _TIFFsetDoubleArray(double** dpp, double* dp, long n)
{ setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
/*
* Install extra samples information.
*/
static int
setExtraSamples(TIFFDirectory* td, va_list ap, int* v)
{
uint16* va;
int i;
*v = va_arg(ap, int);
if ((uint16) *v > td->td_samplesperpixel)
return (0);
va = va_arg(ap, uint16*);
if (*v > 0 && va == NULL) /* typically missing param */
return (0);
for (i = 0; i < *v; i++)
if (va[i] > EXTRASAMPLE_UNASSALPHA)
return (0);
td->td_extrasamples = (uint16) *v;
_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
return (1);
}
static int
checkInkNamesString(TIFF* tif, int slen, const char* s)
{
TIFFDirectory* td = &tif->tif_dir;
int i = td->td_samplesperpixel;
if (slen > 0) {
const char* ep = s+slen;
const char* cp = s;
for (; i > 0; i--) {
for (; *cp != '\0'; cp++)
if (cp >= ep)
goto bad;
cp++; /* skip \0 */
}
return (cp-s);
}
bad:
TIFFError("TIFFSetField",
"%s: Invalid InkNames value; expecting %d names, found %d",
tif->tif_name,
td->td_samplesperpixel,
td->td_samplesperpixel-i);
return (0);
}
static int
_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
{
static const char module[] = "_TIFFVSetField";
TIFFDirectory* td = &tif->tif_dir;
int status = 1;
uint32 v32;
int i, v;
double d;
char* s;
switch (tag) {
case TIFFTAG_SUBFILETYPE:
td->td_subfiletype = va_arg(ap, uint32);
break;
case TIFFTAG_IMAGEWIDTH:
td->td_imagewidth = va_arg(ap, uint32);
break;
case TIFFTAG_IMAGELENGTH:
td->td_imagelength = va_arg(ap, uint32);
break;
case TIFFTAG_BITSPERSAMPLE:
td->td_bitspersample = (uint16) va_arg(ap, int);
/*
* If the data require post-decoding processing
* to byte-swap samples, set it up here. Note
* that since tags are required to be ordered,
* compression code can override this behaviour
* in the setup method if it wants to roll the
* post decoding work in with its normal work.
*/
if (tif->tif_flags & TIFF_SWAB) {
if (td->td_bitspersample == 16)
tif->tif_postdecode = _TIFFSwab16BitData;
else if (td->td_bitspersample == 32)
tif->tif_postdecode = _TIFFSwab32BitData;
else if (td->td_bitspersample == 64)
tif->tif_postdecode = _TIFFSwab64BitData;
}
break;
case TIFFTAG_COMPRESSION:
v = va_arg(ap, int) & 0xffff;
/*
* If we're changing the compression scheme,
* the notify the previous module so that it
* can cleanup any state it's setup.
*/
if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
if (td->td_compression == v)
break;
(*tif->tif_cleanup)(tif);
tif->tif_flags &= ~TIFF_CODERSETUP;
}
/*
* Setup new compression routine state.
*/
if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
td->td_compression = (uint16) v;
else
status = 0;
break;
case TIFFTAG_PHOTOMETRIC:
td->td_photometric = (uint16) va_arg(ap, int);
break;
case TIFFTAG_THRESHHOLDING:
td->td_threshholding = (uint16) va_arg(ap, int);
break;
case TIFFTAG_FILLORDER:
v = va_arg(ap, int);
if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
goto badvalue;
td->td_fillorder = (uint16) v;
break;
case TIFFTAG_DOCUMENTNAME:
_TIFFsetString(&td->td_documentname, va_arg(ap, char*));
break;
case TIFFTAG_ARTIST:
_TIFFsetString(&td->td_artist, va_arg(ap, char*));
break;
case TIFFTAG_DATETIME:
_TIFFsetString(&td->td_datetime, va_arg(ap, char*));
break;
case TIFFTAG_HOSTCOMPUTER:
_TIFFsetString(&td->td_hostcomputer, va_arg(ap, char*));
break;
case TIFFTAG_IMAGEDESCRIPTION:
_TIFFsetString(&td->td_imagedescription, va_arg(ap, char*));
break;
case TIFFTAG_MAKE:
_TIFFsetString(&td->td_make, va_arg(ap, char*));
break;
case TIFFTAG_MODEL:
_TIFFsetString(&td->td_model, va_arg(ap, char*));
break;
case TIFFTAG_COPYRIGHT:
_TIFFsetString(&td->td_copyright, va_arg(ap, char*));
break;
case TIFFTAG_ORIENTATION:
v = va_arg(ap, int);
if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) {
TIFFWarning(tif->tif_name,
"Bad value %ld for \"%s\" tag ignored",
v, _TIFFFieldWithTag(tif, tag)->field_name);
} else
td->td_orientation = (uint16) v;
break;
case TIFFTAG_SAMPLESPERPIXEL:
/* XXX should cross check -- e.g. if pallette, then 1 */
v = va_arg(ap, int);
if (v == 0)
goto badvalue;
td->td_samplesperpixel = (uint16) v;
break;
case TIFFTAG_ROWSPERSTRIP:
v32 = va_arg(ap, uint32);
if (v32 == 0)
goto badvalue32;
td->td_rowsperstrip = v32;
if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
td->td_tilelength = v32;
td->td_tilewidth = td->td_imagewidth;
}
break;
case TIFFTAG_MINSAMPLEVALUE:
td->td_minsamplevalue = (uint16) va_arg(ap, int);
break;
case TIFFTAG_MAXSAMPLEVALUE:
td->td_maxsamplevalue = (uint16) va_arg(ap, int);
break;
case TIFFTAG_SMINSAMPLEVALUE:
td->td_sminsamplevalue = (double) va_arg(ap, dblparam_t);
break;
case TIFFTAG_SMAXSAMPLEVALUE:
td->td_smaxsamplevalue = (double) va_arg(ap, dblparam_t);
break;
case TIFFTAG_XRESOLUTION:
td->td_xresolution = (float) va_arg(ap, dblparam_t);
break;
case TIFFTAG_YRESOLUTION:
td->td_yresolution = (float) va_arg(ap, dblparam_t);
break;
case TIFFTAG_PLANARCONFIG:
v = va_arg(ap, int);
if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
goto badvalue;
td->td_planarconfig = (uint16) v;
break;
case TIFFTAG_PAGENAME:
_TIFFsetString(&td->td_pagename, va_arg(ap, char*));
break;
case TIFFTAG_XPOSITION:
td->td_xposition = (float) va_arg(ap, dblparam_t);
break;
case TIFFTAG_YPOSITION:
td->td_yposition = (float) va_arg(ap, dblparam_t);
break;
case TIFFTAG_RESOLUTIONUNIT:
v = va_arg(ap, int);
if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
goto badvalue;
td->td_resolutionunit = (uint16) v;
break;
case TIFFTAG_PAGENUMBER:
td->td_pagenumber[0] = (uint16) va_arg(ap, int);
td->td_pagenumber[1] = (uint16) va_arg(ap, int);
break;
case TIFFTAG_HALFTONEHINTS:
td->td_halftonehints[0] = (uint16) va_arg(ap, int);
td->td_halftonehints[1] = (uint16) va_arg(ap, int);
break;
case TIFFTAG_COLORMAP:
v32 = (uint32)(1L<<td->td_bitspersample);
_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break;
case TIFFTAG_EXTRASAMPLES:
if (!setExtraSamples(td, ap, &v))
goto badvalue;
break;
case TIFFTAG_MATTEING:
td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
if (td->td_extrasamples) {
uint16 sv = EXTRASAMPLE_ASSOCALPHA;
_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
}
break;
case TIFFTAG_TILEWIDTH:
v32 = va_arg(ap, uint32);
if (v32 % 16) {
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarning(tif->tif_name,
"Nonstandard tile width %d, convert file", v32);
}
td->td_tilewidth = v32;
tif->tif_flags |= TIFF_ISTILED;
break;
case TIFFTAG_TILELENGTH:
v32 = va_arg(ap, uint32);
if (v32 % 16) {
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarning(tif->tif_name,
"Nonstandard tile length %d, convert file", v32);
}
td->td_tilelength = v32;
tif->tif_flags |= TIFF_ISTILED;
break;
case TIFFTAG_TILEDEPTH:
v32 = va_arg(ap, uint32);
if (v32 == 0)
goto badvalue32;
td->td_tiledepth = v32;
break;
case TIFFTAG_DATATYPE:
v = va_arg(ap, int);
switch (v) {
case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
default: goto badvalue;
}
td->td_sampleformat = (uint16) v;
break;
case TIFFTAG_SAMPLEFORMAT:
v = va_arg(ap, int);
if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
goto badvalue;
td->td_sampleformat = (uint16) v;
/* Try to fix up the SWAB function for complex data. */
if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
&& td->td_bitspersample == 32
&& tif->tif_postdecode == _TIFFSwab32BitData )
tif->tif_postdecode = _TIFFSwab16BitData;
else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
|| td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
&& td->td_bitspersample == 64
&& tif->tif_postdecode == _TIFFSwab64BitData )
tif->tif_postdecode = _TIFFSwab32BitData;
else if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP
&& td->td_bitspersample == 128
&& tif->tif_postdecode == NULL )
tif->tif_postdecode = _TIFFSwab64BitData;
break;
case TIFFTAG_IMAGEDEPTH:
td->td_imagedepth = va_arg(ap, uint32);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -