|
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 |
*/
|