tif_dir.c
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 1,436 行 · 第 1/3 页
C
1,436 行
/* $Header: /pack/cvsroots/wxwidgets/wxWindows/src/tiff/tif_dir.c,v 1.4 2004/11/19 22:29:42 VZ 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;
case TIFFTAG_STONITS:
d = va_arg(ap, dblparam_t);
if (d <= 0.)
goto badvaluedbl;
td->td_stonits = d;
break;
/* Begin Pixar Tags */
case TIFFTAG_PIXAR_IMAGEFULLWIDTH:
td->td_imagefullwidth = va_arg(ap, uint32);
break;
case TIFFTAG_PIXAR_IMAGEFULLLENGTH:
td->td_imagefulllength = va_arg(ap, uint32);
break;
case TIFFTAG_PIXAR_TEXTUREFORMAT:
_TIFFsetString(&td->td_textureformat, va_arg(ap, char*));
break;
case TIFFTAG_PIXAR_WRAPMODES:
_TIFFsetString(&td->td_wrapmodes, va_arg(ap, char*));
break;
case TIFFTAG_PIXAR_FOVCOT:
td->td_fovcot = (float) va_arg(ap, dblparam_t);
break;
case TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN:
_TIFFsetFloatArray(&td->td_matrixWorldToScreen,
va_arg(ap, float*), 16);
break;
case TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA:
_TIFFsetFloatArray(&td->td_matrixWorldToCamera,
va_arg(ap, float*), 16);
break;
/* End Pixar Tags */
case TIFFTAG_SUBIFD:
if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
td->td_nsubifd = (uint16) va_arg(ap, int);
_TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
(long) td->td_nsubifd);
} else {
TIFFError(module, "%s: Sorry, cannot nest SubIFDs",
tif->tif_name);
status = 0;
}
break;
case TIFFTAG_YCBCRCOEFFICIENTS:
_TIFFsetFloatArray(&td->td_ycbcrcoeffs, va_arg(ap, float*), 3);
break;
case TIFFTAG_YCBCRPOSITIONING:
td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
break;
case TIFFTAG_YCBCRSUBSAMPLING:
td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
break;
case TIFFTAG_WHITEPOINT:
_TIFFsetFloatArray(&td->td_whitepoint, va_arg(ap, float*), 2);
break;
case TIFFTAG_PRIMARYCHROMATICITIES:
_TIFFsetFloatArray(&td->td_primarychromas, va_arg(ap, float*), 6);
break;
case TIFFTAG_TRANSFERFUNCTION:
v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
for (i = 0; i < v; i++)
_TIFFsetShortArray(&td->td_transferfunction[i],
va_arg(ap, uint16*), 1L<<td->td_bitspersample);
break;
case TIFFTAG_REFERENCEBLACKWHITE:
/* XXX should check for null range */
_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
break;
case TIFFTAG_INKSET:
td->td_inkset = (uint16) va_arg(ap, int);
break;
case TIFFTAG_DOTRANGE:
/* XXX should check for null range */
td->td_dotrange[0] = (uint16) va_arg(ap, int);
td->td_dotrange[1] = (uint16) va_arg(ap, int);
break;
case TIFFTAG_INKNAMES:
i = va_arg(ap, int);
s = va_arg(ap, char*);
i = checkInkNamesString(tif, i, s);
status = i > 0;
if( i > 0 ) {
_TIFFsetNString(&td->td_inknames, s, i);
td->td_inknameslen = i;
}
break;
case TIFFTAG_NUMBEROFINKS:
td->td_ninks = (uint16) va_arg(ap, int);
break;
case TIFFTAG_TARGETPRINTER:
_TIFFsetString(&td->td_targetprinter, va_arg(ap, char*));
break;
case TIFFTAG_ICCPROFILE:
td->td_profileLength = (uint32) va_arg(ap, uint32);
_TIFFsetByteArray(&td->td_profileData, va_arg(ap, void*),
td->td_profileLength);
break;
case TIFFTAG_PHOTOSHOP:
td->td_photoshopLength = (uint32) va_arg(ap, uint32);
_TIFFsetByteArray (&td->td_photoshopData, va_arg(ap, void*),
td->td_photoshopLength);
break;
case TIFFTAG_RICHTIFFIPTC:
td->td_richtiffiptcLength = (uint32) va_arg(ap, uint32);
_TIFFsetLongArray ((uint32**)&td->td_richtiffiptcData,
va_arg(ap, uint32*),
td->td_richtiffiptcLength);
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?