tif_dir.c

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 1,436 行 · 第 1/3 页

C
1,436
字号
	case TIFFTAG_XMLPACKET:
		td->td_xmlpacketLength = (uint32) va_arg(ap, uint32);
		_TIFFsetByteArray(&td->td_xmlpacketData, va_arg(ap, void*),
		    td->td_xmlpacketLength);
		break;
        default: {
            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
            TIFFTagValue *tv;
            int           tv_size, iCustom;

            /*
             * This can happen if multiple images are open with
             * different codecs which have private tags.  The
             * global tag information table may then have tags
             * that are valid for one file but not the other. 
             * If the client tries to set a tag that is not valid
             * for the image's codec then we'll arrive here.  This
             * happens, for example, when tiffcp is used to convert
             * between compression schemes and codec-specific tags
             * are blindly copied.
             */
            if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
            {
		TIFFError(module,
		    "%s: Invalid %stag \"%s\" (not supported by codec)",
		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
		    _TIFFFieldWithTag(tif, tag)->field_name);
		status = 0;
		break;
            }

            /*
             * Find the existing entry for this custom value.
             */
            tv = NULL;
            for( iCustom = 0; iCustom < td->td_customValueCount; iCustom++ )
            {
                if( td->td_customValues[iCustom].info == fip )
                {
                    tv = td->td_customValues + iCustom;
                    if( tv->value != NULL )
                        _TIFFfree( tv->value );
                    break;
                }
            }

            /*
             * Grow the custom list if the entry was not found.
             */
            if( tv == NULL )
            {
		TIFFTagValue	*new_customValues;
		
		td->td_customValueCount++;
		new_customValues = (TIFFTagValue *)
			_TIFFrealloc(td->td_customValues,
				     sizeof(TIFFTagValue) * td->td_customValueCount);
		if (!new_customValues) {
			TIFFError(module,
		"%s: Failed to allocate space for list of custom values",
				  tif->tif_name);
			status = 0;
			goto end;
		}

		td->td_customValues = new_customValues;

                tv = td->td_customValues + (td->td_customValueCount-1);
                tv->info = fip;
                tv->value = NULL;
                tv->count = 0;
            }

            /*
             * Set custom value ... save a copy of the custom tag value.
             */
            tv_size = TIFFDataWidth(fip->field_type);
            if( fip->field_passcount )
                tv->count = (int) va_arg(ap, int);
            else
                tv->count = 1;
            if( fip->field_passcount )
            {
                tv->value = _TIFFmalloc(tv_size * tv->count);
		if ( !tv->value ) {
			va_end(ap);
			return 0;
		}
                _TIFFmemcpy( tv->value, (void *) va_arg(ap,void*),
                             tv->count * tv_size );
            }
            else if( fip->field_type == TIFF_ASCII )
            {
                const char *value = (const char *) va_arg(ap,const char *);
                tv->count = strlen(value)+1;
                tv->value = _TIFFmalloc(tv->count);
		if ( !tv->value ) {
			va_end(ap);
			return 0;
		}
                strcpy( tv->value, value );
            }
            else
            {
                /* not supporting "pass by value" types yet */
		TIFFWarning(module, " ... pass by value not implemented.");

                tv->value = _TIFFmalloc(tv_size * tv->count);
		if ( !tv->value ) {
			va_end(ap);
			return 0;
		}
                _TIFFmemset( tv->value, 0, tv->count * tv_size );
                status = 0;
            }
          }
	}
	if (status) {
            TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
            tif->tif_flags |= TIFF_DIRTYDIRECT;
	}

end:
	va_end(ap);
	return (status);
badvalue:
	TIFFError(module, "%.1000s: Bad value %d for \"%s\"",
		  tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name);
	va_end(ap);
	return (0);
badvalue32:
	TIFFError(module, "%.1000s: Bad value %ld for \"%s\"",
		   tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name);
	va_end(ap);
	return (0);
badvaluedbl:
	TIFFError(module, "%.1000s: Bad value %f for \"%s\"",
		  tif->tif_name, d, _TIFFFieldWithTag(tif, tag)->field_name);
	va_end(ap);
	return (0);
}

/*
 * Return 1/0 according to whether or not
 * it is permissible to set the tag's value.
 * Note that we allow ImageLength to be changed
 * so that we can append and extend to images.
 * Any other tag may not be altered once writing
 * has commenced, unless its value has no effect
 * on the format of the data that is written.
 */
static int
OkToChangeTag(TIFF* tif, ttag_t tag)
{
	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
	if (!fip) {			/* unknown tag */
		TIFFError("TIFFSetField", "%s: Unknown %stag %u",
		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
		return (0);
	}
	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
	    !fip->field_oktochange) {
		/*
		 * Consult info table to see if tag can be changed
		 * after we've started writing.  We only allow changes
		 * to those tags that don't/shouldn't affect the
		 * compression and/or format of the data.
		 */
		TIFFError("TIFFSetField",
		    "%s: Cannot modify tag \"%s\" while writing",
		    tif->tif_name, fip->field_name);
		return (0);
	}
	return (1);
}

/*
 * Record the value of a field in the
 * internal directory structure.  The
 * field will be written to the file
 * when/if the directory structure is
 * updated.
 */
int
TIFFSetField(TIFF* tif, ttag_t tag, ...)
{
	va_list ap;
	int status;

	va_start(ap, tag);
	status = TIFFVSetField(tif, tag, ap);
	va_end(ap);
	return (status);
}

/*
 * Like TIFFSetField, but taking a varargs
 * parameter list.  This routine is useful
 * for building higher-level interfaces on
 * top of the library.
 */
int
TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
{
	return OkToChangeTag(tif, tag) ?
	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
}

static int
_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
{
    TIFFDirectory* td = &tif->tif_dir;
    int            ret_val = 1;

    switch (tag) {
	case TIFFTAG_SUBFILETYPE:
            *va_arg(ap, uint32*) = td->td_subfiletype;
            break;
	case TIFFTAG_IMAGEWIDTH:
            *va_arg(ap, uint32*) = td->td_imagewidth;
            break;
	case TIFFTAG_IMAGELENGTH:
            *va_arg(ap, uint32*) = td->td_imagelength;
            break;
	case TIFFTAG_BITSPERSAMPLE:
            *va_arg(ap, uint16*) = td->td_bitspersample;
            break;
	case TIFFTAG_COMPRESSION:
            *va_arg(ap, uint16*) = td->td_compression;
            break;
	case TIFFTAG_PHOTOMETRIC:
            *va_arg(ap, uint16*) = td->td_photometric;
            break;
	case TIFFTAG_THRESHHOLDING:
            *va_arg(ap, uint16*) = td->td_threshholding;
            break;
	case TIFFTAG_FILLORDER:
            *va_arg(ap, uint16*) = td->td_fillorder;
            break;
	case TIFFTAG_DOCUMENTNAME:
            *va_arg(ap, char**) = td->td_documentname;
            break;
	case TIFFTAG_ARTIST:
            *va_arg(ap, char**) = td->td_artist;
            break;
	case TIFFTAG_DATETIME:
            *va_arg(ap, char**) = td->td_datetime;
            break;
	case TIFFTAG_HOSTCOMPUTER:
            *va_arg(ap, char**) = td->td_hostcomputer;
            break;
	case TIFFTAG_IMAGEDESCRIPTION:
            *va_arg(ap, char**) = td->td_imagedescription;
            break;
	case TIFFTAG_MAKE:
            *va_arg(ap, char**) = td->td_make;
            break;
	case TIFFTAG_MODEL:
            *va_arg(ap, char**) = td->td_model;
            break;
	case TIFFTAG_COPYRIGHT:
            *va_arg(ap, char**) = td->td_copyright;
            break;
	case TIFFTAG_ORIENTATION:
            *va_arg(ap, uint16*) = td->td_orientation;
            break;
	case TIFFTAG_SAMPLESPERPIXEL:
            *va_arg(ap, uint16*) = td->td_samplesperpixel;
            break;
	case TIFFTAG_ROWSPERSTRIP:
            *va_arg(ap, uint32*) = td->td_rowsperstrip;
            break;
	case TIFFTAG_MINSAMPLEVALUE:
            *va_arg(ap, uint16*) = td->td_minsamplevalue;
            break;
	case TIFFTAG_MAXSAMPLEVALUE:
            *va_arg(ap, uint16*) = td->td_maxsamplevalue;
            break;
	case TIFFTAG_SMINSAMPLEVALUE:
            *va_arg(ap, double*) = td->td_sminsamplevalue;
            break;
	case TIFFTAG_SMAXSAMPLEVALUE:
            *va_arg(ap, double*) = td->td_smaxsamplevalue;
            break;
	case TIFFTAG_XRESOLUTION:
            *va_arg(ap, float*) = td->td_xresolution;
            break;
	case TIFFTAG_YRESOLUTION:
            *va_arg(ap, float*) = td->td_yresolution;
            break;
	case TIFFTAG_PLANARCONFIG:
            *va_arg(ap, uint16*) = td->td_planarconfig;
            break;
	case TIFFTAG_XPOSITION:
            *va_arg(ap, float*) = td->td_xposition;
            break;
	case TIFFTAG_YPOSITION:
            *va_arg(ap, float*) = td->td_yposition;
            break;
	case TIFFTAG_PAGENAME:
            *va_arg(ap, char**) = td->td_pagename;
            break;
	case TIFFTAG_RESOLUTIONUNIT:
            *va_arg(ap, uint16*) = td->td_resolutionunit;
            break;
	case TIFFTAG_PAGENUMBER:
            *va_arg(ap, uint16*) = td->td_pagenumber[0];
            *va_arg(ap, uint16*) = td->td_pagenumber[1];
            break;
	case TIFFTAG_HALFTONEHINTS:
            *va_arg(ap, uint16*) = td->td_halftonehints[0];
            *va_arg(ap, uint16*) = td->td_halftonehints[1];
            break;
	case TIFFTAG_COLORMAP:
            *va_arg(ap, uint16**) = td->td_colormap[0];
            *va_arg(ap, uint16**) = td->td_colormap[1];
            *va_arg(ap, uint16**) = td->td_colormap[2];
            break;
	case TIFFTAG_STRIPOFFSETS:
	case TIFFTAG_TILEOFFSETS:
            *va_arg(ap, uint32**) = td->td_stripoffset;
            break;
	case TIFFTAG_STRIPBYTECOUNTS:
	case TIFFTAG_TILEBYTECOUNTS:
            *va_arg(ap, uint32**) = td->td_stripbytecount;
            break;
	case TIFFTAG_MATTEING:
            *va_arg(ap, uint16*) =
                (td->td_extrasamples == 1 &&
                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
            break;
	case TIFFTAG_EXTRASAMPLES:
            *va_arg(ap, uint16*) = td->td_extrasamples;
            *va_arg(ap, uint16**) = td->td_sampleinfo;
            break;
	case TIFFTAG_TILEWIDTH:
            *va_arg(ap, uint32*) = td->td_tilewidth;
            break;
	case TIFFTAG_TILELENGTH:
            *va_arg(ap, uint32*) = td->td_tilelength;
            break;
	case TIFFTAG_TILEDEPTH:
            *va_arg(ap, uint32*) = td->td_tiledepth;
            break;
	case TIFFTAG_DATATYPE:
            switch (td->td_sampleformat) {
		case SAMPLEFORMAT_UINT:
                    *va_arg(ap, uint16*) = DATATYPE_UINT;
                    break;
		case SAMPLEFORMAT_INT:
                    *va_arg(ap, uint16*) = DATATYPE_INT;
                    break;
		case SAMPLEFORMAT_IEEEFP:
                    *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
                    break;
		case SAMPLEFORMAT_VOID:
                    *va_arg(ap, uint16*) = DATATYPE_VOID;
                    break;
            }
            break;
	case TIFFTAG_SAMPLEFORMAT:
            *va_arg(ap, uint16*) = td->td_sampleformat;
            break;
	case TIFFTAG_IMAGEDEPTH:
            *va_arg(ap, uint32*) = td->td_imagedepth;
            break;
	case TIFFTAG_STONITS:
            *va_arg(ap, double*) = td->td_stonits;
            break;
	case TIFFTAG_SUBIFD:
            *va_arg(ap, uint16*) = td->td_nsubifd;
            *va_arg(ap, uint32**) = td->td_subifd;
            break;
	case TIFFTAG_YCBCRCOEFFICIENTS:
            *va_arg(ap, float**) = td->td_ycbcrcoeffs;
            break;
	case TIFFTAG_YCBCRPOSITIONING:
            *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
            break;
	case TIFFTAG_YCBCRSUBSAMPLING:
            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
            break;
	case TIFFTAG_WHITEPOINT:
            *va_arg(ap, float**) = td->td_whitepoint;
            break;
	case TIFFTAG_PRIMARYCHROMATICITIES:
            *va_arg(ap, float**) = td->td_primarychromas;
            break;
	case TIFFTAG_TRANSFERFUNCTION:
            *va_arg(ap, uint16**) = td->td_transferfunction[0];
            if (td->td_samplesperpixel - td->td_extrasamples > 1) {
                *va_arg(ap, uint16**) = td->td_transferfunction[1];
                *va_arg(ap, uint16**) = td->td_transferfunction[2];
            }
            break;
	case TIFFTAG_REFERENCEBLACKWHITE:
            *va_arg(ap, float**) = td->td_refblackwhite;
            break;
	case TIFFTAG_INKSET:
            *va_arg(ap, uint16*) = td->td_inkset;
            break;
	case TIFFTAG_DOTRANGE:
            *va_arg(ap, uint16*) = td->td_dotrange[0];
            *va_arg(ap, uint16*) = td->td_dotrange[1];
            break;
	case TIFFTAG_INKNAMES:
            *va_arg(ap, char**) = td->td_inknames;
            break;
	case TIFFTAG_NUMBEROFINKS:
            *va_arg(ap, uint16*) = td->td_ninks;
            break;
	case TIFFTAG_TARGETPRINTER:
            *va_arg(ap, char**) = td->td_targetprinter;
            break;
	case TIFFTAG_ICCPROFILE:
            *va_arg(ap, uint32*) = td->td_profileLength;
            *va_arg(ap, void**) = td->td_profileData;
            break;
 	case TIFFTAG_PHOTOSHOP:
            *va_arg(ap, uint32*) = td->td_photoshopLength;
            *va_arg(ap, void**) = td->td_photoshopData;
            break;
 	case TIFFTAG_RICHTIFFIPTC:
            *va_arg(ap, uint32*) = td->td_richtiffiptcLength;
            *va_arg(ap, void**) = td->td_richtiffiptcData;
            break;
	case TIFFTAG_XMLPACKET:
            *va_arg(ap, uint32*) = td->td_xmlpacketLength;
            *va_arg(ap, void**) = td->td_xmlpacketData;
            break;
            /* Begin Pixar Tags */
 	case TIFFTAG_PIXAR_IMAGEFULLWIDTH:
            *va_arg(ap, uint32*) = td->td_imagefullwidth;
            break;
 	case TIFFTAG_PIXAR_IMAGEFULLLENGTH:
            *va_arg(ap, uint32*) = td->td_imagefulllength;
            break;
 	case TIFFTAG_PIXAR_TEXTUREFORMAT:
            *va_arg(ap, char**) = td->td_textureformat;
            break;
 	case TIFFTAG_PIXAR_WRAPMODES:
            *va_arg(ap, char**) = td->td_wrapmodes;
            break;
 	case TIFFTAG_PIXAR_FOVCOT:
            *va_arg(ap, float*) = td->td_fovcot;
            break;
 	case TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN:
            *va_arg(ap, float**) = td->td_matrixWorldToScreen;
            break;
 	case TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA:
            *va_arg(ap, float**) = td->td_matrixWorldToCamera;
            break;
            /* End Pixar Tags */

        default:
        {
            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
            int           i;
            
            /*
             * This can happen if multiple images are open with
             * different codecs which have private tags.  The
             * global tag information table may then have tags
             * that are valid for one file but not the other. 
             * If the client tries to get a tag that is not valid
             * for the image's codec then we'll arrive here.
             */
            if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
            {
                TIFFError("_TIFFVGetField",
                          "%s: Invalid %stag \"%s\" (not supported by codec)",
                          tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
                          _TIFFFieldWithTag(tif, tag)->field_name);
                ret_val = 0;
                break;
            }

            /*

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?