Blame contrib/tags/xtif_dir.c

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