/* * xtif_dir.c * * Extended TIFF Directory Tag Support. * * You may use this file as a template to add your own * extended tags to the library. Only the parts of the code * marked with "XXX" require modification. Three example tags * are shown; you should replace them with your own. * * Author: Niles D. Ritter */ #include #include #include "xtiffiop.h" /* Tiff info structure. * * Entry format: * { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, * OkToChange, PassDirCountOnSet, AsciiName } * * For ReadCount, WriteCount, -1 = unknown; used for mult-valued * tags and ASCII. */ static const TIFFFieldInfo xtiffFieldInfo[] = { { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, FIELD_33432, TRUE, FALSE, "copyright" }, { TIFFTAG_KDC_33423, -1, -1, TIFF_ASCII, FIELD_33423, TRUE, FALSE, "kdc_33423" }, { TIFFTAG_KDC_33424, 1, -1, TIFF_LONG, FIELD_33424, TRUE, FALSE, "kdc_33424" }, { TIFFTAG_KDC_33434, 1, -1, TIFF_RATIONAL, FIELD_33434, TRUE, FALSE, "kdc_33434" }, { TIFFTAG_KDC_33437, 1, -1, TIFF_RATIONAL, FIELD_33437, TRUE, FALSE, "kdc_33437" }, { TIFFTAG_KDC_34850, 1, -1, TIFF_SHORT, FIELD_34850, TRUE, FALSE, "kdc_34850" }, { TIFFTAG_KDC_34859, 1, -1, TIFF_SHORT, FIELD_34859, TRUE, FALSE, "kdc_34859" }, { TIFFTAG_KDC_DATETIME, -1, -1, TIFF_ASCII, FIELD_36867, TRUE, FALSE, "kdc_datetime" }, { TIFFTAG_KDC_37382, -1, -1, TIFF_RATIONAL, FIELD_37382, TRUE, FALSE, "kdc_37382" }, { TIFFTAG_KDC_37385, 1, -1, TIFF_SHORT, FIELD_37385, TRUE, FALSE, "kdc_37385" }, { TIFFTAG_KDC_37386, 1, -1, TIFF_RATIONAL, FIELD_37386, TRUE, FALSE, "kdc_37386" }, { TIFFTAG_KDC_37393, 1, -1, TIFF_SHORT, FIELD_37393, TRUE, FALSE, "kdc_37393" }, { TIFFTAG_KDC_37398, 4, -1, TIFF_BYTE, FIELD_37398, TRUE, FALSE, "kdc_37398" }, { TIFFTAG_KDC_37399, 1, -1, TIFF_SHORT, FIELD_37399, TRUE, FALSE, "kdc_37399" }, { TIFFTAG_KDC_33421, 2, -1, TIFF_SHORT, FIELD_33421, TRUE, FALSE, "kdc_33421" }, { TIFFTAG_KDC_33422, 4, -1, TIFF_BYTE, FIELD_33422, TRUE, FALSE, "kdc_33422" }, { TIFFTAG_KDC_37122, -1, -1, TIFF_RATIONAL, FIELD_37122, TRUE, FALSE, "kdc_37122" }, { TIFFTAG_KDC_37400, 12, -1, TIFF_SRATIONAL, FIELD_37400, TRUE, FALSE, "kdc_37400" } }; #define N(a) (sizeof (a) / sizeof (a[0])) static void _XTIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) { xtiff *xt = XTIFFDIR(tif); XTIFFDirectory *xd = &xt->xtif_dir; /* call the inherited method */ if (PARENT(xt,printdir)) (PARENT(xt,printdir))(tif,fd,flags); /* XXX Add field printing here. Replace the three example * tags implemented below with your own. */ if (TIFFFieldSet(tif,FIELD_33432)) { _TIFFprintAsciiTag(fd,"Copyright",xd->xd_copyright); } fprintf(fd,"--KDC Specific Tags--\n"); if (TIFFFieldSet(tif,FIELD_33423)) { _TIFFprintAsciiTag(fd,"Battery Status",xd->xd_kdc_33423); } if (TIFFFieldSet(tif,FIELD_36867)) { _TIFFprintAsciiTag(fd,"Date & Time",xd->xd_kdc_36867); } if (TIFFFieldSet(tif,FIELD_33424)) { fprintf(fd," 33424: %ld\n", xd->xd_kdc_33424); } if (TIFFFieldSet(tif,FIELD_33434)) { fprintf(fd," 33434: %ld/%ld\n", xd->xd_kdc_33434[0],xd->xd_kdc_33434[1]); } if (TIFFFieldSet(tif,FIELD_33437)) { fprintf(fd," 33437: %ld/%ld\n", xd->xd_kdc_33437[0],xd->xd_kdc_33437[1]); } if (TIFFFieldSet(tif,FIELD_34850)) { fprintf(fd," 34850: %d\n", xd->xd_kdc_34850); } if (TIFFFieldSet(tif,FIELD_34859)) { fprintf(fd," 34859: %d\n", xd->xd_kdc_34859); } if (TIFFFieldSet(tif,FIELD_37382)) { // fprintf(fd," 37382: %ld/%ld\n", xd->xd_kdc_37382[0],xd->xd_kdc_37382[1]); } if (TIFFFieldSet(tif,FIELD_37385)) { fprintf(fd," 37385: %d\n", xd->xd_kdc_37385); } if (TIFFFieldSet(tif,FIELD_37386)) { // fprintf(fd," 37386: %ld/%ld\n", xd->xd_kdc_37386[0],xd->xd_kdc_37386[1]); } if (TIFFFieldSet(tif,FIELD_37393)) { fprintf(fd," 37393: %d\n", xd->xd_kdc_37393); } if (TIFFFieldSet(tif,FIELD_37398)) { unsigned char* u = (unsigned char*)xd->xd_kdc_37398; fprintf(fd," 37398: %d %d %d %d\n", u[0],u[1],u[2],u[3]); } if (TIFFFieldSet(tif,FIELD_37399)) { fprintf(fd," 37399: %d\n", xd->xd_kdc_37399); } if (TIFFFieldSet(tif,FIELD_33421)) { fprintf(fd," 33421: %d %d\n", xd->xd_kdc_33421[0],xd->xd_kdc_33421[1]); } if (TIFFFieldSet(tif,FIELD_33422)) { unsigned char* u = (unsigned char*)xd->xd_kdc_33422; fprintf(fd," 33422: %d %d %d %d\n", u[0],u[1],u[2],u[3]); } if (TIFFFieldSet(tif,FIELD_37122)) { // fprintf(fd," 37122: %d\n", xd->xd_kdc_37122); } if (TIFFFieldSet(tif,FIELD_37400)) { fprintf(fd," 37400: %ld/%ld\n", xd->xd_kdc_37400[0],xd->xd_kdc_37400[1]); } } static int _XTIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) { xtiff *xt = XTIFFDIR(tif); XTIFFDirectory* xd = &xt->xtif_dir; int status = 1; /*uint32 v32=0; int v=0;*/ /*va_list ap1 = ap;*/ //fprintf(stderr,"_XTIFFVSetField() entered %d\n",tag); /* va_start is called by the calling routine */ switch (tag) { /* * XXX put your extended tags here; replace the implemented * example tags with your own. */ case TIFFTAG_KDC_33423: /*(0x828f) ASCII (2) 6*/ _TIFFsetString(&xd->xd_kdc_33423, va_arg(ap, char*)); break; case TIFFTAG_KDC_33424: /*(0x8290) LONG (4) 1<1002>*/ xd->xd_kdc_33424 = va_arg(ap, uint32); break; case TIFFTAG_KDC_33434: /*(0x829a) RATIONAL (5) 1<0.01069>*/ // _TIFFsetLongArray(&xd->xd_kdc_33434, va_arg(ap, uint32*),2); break; case TIFFTAG_KDC_33437: /*(0x829d) RATIONAL (5) 1<2.5>*/ // _TIFFsetLongArray(&xd->xd_kdc_33437, va_arg(ap, uint32*),2); break; case TIFFTAG_KDC_34850: /*(0x8822) SHORT (3) 1<2>*/ xd->xd_kdc_34850 = va_arg(ap, uint16); break; case TIFFTAG_KDC_34859: /*(0x882b) SHORT (3) 1<0>*/ xd->xd_kdc_34859 = va_arg(ap, uint16); break; case TIFFTAG_KDC_DATETIME: /*(0x9003) ASCII (2) 20<1994:03:25 00:00:25\0>*/ _TIFFsetString(&xd->xd_kdc_36867, va_arg(ap, char*)); break; case TIFFTAG_KDC_37382: /*(0x9206) RATIONAL (5) 1<0.7>*/ // _TIFFsetLongArray(&xd->xd_kdc_37382, va_arg(ap, uint32*),2); break; case TIFFTAG_KDC_37385: /*(0x9209) SHORT (3) 1<31>*/ xd->xd_kdc_37385 = va_arg(ap, uint16); break; case TIFFTAG_KDC_37386: /*(0x920a) RATIONAL (5) 1<100>*/ // _TIFFsetLongArray(&xd->xd_kdc_37386, va_arg(ap, uint32*),2); break; case TIFFTAG_KDC_37393: /*(0x9211) SHORT (3) 1<1>*/ xd->xd_kdc_37393 = va_arg(ap, uint16); break; case TIFFTAG_KDC_37398: /*(0x9216) BYTE (1) 4<00 00 00 0x1>*/ _TIFFsetByteArray(&xd->xd_kdc_37398, va_arg(ap, void*),4); break; case TIFFTAG_KDC_37399: /*(0x9217) SHORT (3) 1<2>*/ xd->xd_kdc_37399 = va_arg(ap, uint16); break; case TIFFTAG_KDC_33421: /*(0x828d) SHORT (3) 2<2 2>*/ _TIFFsetShortArray(&xd->xd_kdc_33421, va_arg(ap, uint16*),2); break; case TIFFTAG_KDC_33422: /*(0x828e) BYTE (1) 4<0x1 0x2 00 0x1>*/ _TIFFsetByteArray(&xd->xd_kdc_33422, va_arg(ap, void*),4); break; case TIFFTAG_KDC_37122: /*(0x9102) RATIONAL (5) 1<0.75>*/ // _TIFFsetLongArray(&xd->xd_kdc_37122, va_arg(ap, uint32*),2); break; case TIFFTAG_KDC_37400: /*(0x9218) SRATIONAL (10) 12<0 -2.02926 1.04202*/ // _TIFFsetLongArray(&xd->xd_kdc_37400, va_arg(ap, uint32*),24); break; case TIFFTAG_COPYRIGHT: _TIFFsetString(&xd->xd_copyright, va_arg(ap, char*)); break; default: /* call the inherited method */ return (PARENT(xt,vsetfield))(tif,tag,ap); break; } if (status) { /* we have to override the print method here, * after the compression tags have gotten to it. * This makes sense because the only time we would * need the extended print method is if an extended * tag is set by the reader. */ if (!(xt->xtif_flags & XTIFFP_PRINT)) { PARENT(xt,printdir) = TIFFMEMBER(tif,printdir); TIFFMEMBER(tif,printdir) = _XTIFFPrintDirectory; xt->xtif_flags |= XTIFFP_PRINT; } TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); tif->tif_flags |= TIFF_DIRTYDIRECT; } va_end(ap); return (status); /* badvalue: TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v, _TIFFFieldWithTag(tif, tag)->field_name); va_end(ap); return (0); badvalue32: TIFFError(tif->tif_name, "%ld: Bad value for \"%s\"", v32, _TIFFFieldWithTag(tif, tag)->field_name); va_end(ap); return (0); */ } static int _XTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) { xtiff *xt = XTIFFDIR(tif); XTIFFDirectory* xd = &xt->xtif_dir; switch (tag) { /* * XXX put your extended tags here; replace the implemented * example tags with your own. */ case TIFFTAG_KDC_33423: /*(0x828f) ASCII (2) 6*/ *va_arg(ap, char**) = xd->xd_kdc_33423; break; case TIFFTAG_KDC_33424: /*(0x8290) LONG (4) 1<1002>*/ *va_arg(ap, uint32*) = xd->xd_kdc_33424; break; case TIFFTAG_KDC_33434: /*(0x829a) RATIONAL (5) 1<0.01069>*/ *va_arg(ap, uint32**) = xd->xd_kdc_33434; break; case TIFFTAG_KDC_33437: /*(0x829d) RATIONAL (5) 1<2.5>*/ *va_arg(ap, uint32**) = xd->xd_kdc_33437; break; case TIFFTAG_KDC_34850: /*(0x8822) SHORT (3) 1<2>*/ *va_arg(ap, uint16*) = xd->xd_kdc_34850; break; case TIFFTAG_KDC_34859: /*(0x882b) SHORT (3) 1<0>*/ *va_arg(ap, uint16*) = xd->xd_kdc_34859; break; case TIFFTAG_KDC_DATETIME: /*(0x9003) ASCII (2) 20<1994:03:25 00:00:25\0>*/ *va_arg(ap, char**) = xd->xd_kdc_36867; break; case TIFFTAG_KDC_37382: /*(0x9206) RATIONAL (5) 1<0.7>*/ *va_arg(ap, uint32**) = xd->xd_kdc_37382; break; case TIFFTAG_KDC_37385: /*(0x9209) SHORT (3) 1<31>*/ *va_arg(ap, uint16*) = xd->xd_kdc_37385; break; case TIFFTAG_KDC_37386: /*(0x920a) RATIONAL (5) 1<100>*/ *va_arg(ap, uint32**) = xd->xd_kdc_37386; break; case TIFFTAG_KDC_37393: /*(0x9211) SHORT (3) 1<1>*/ *va_arg(ap, uint16*) = xd->xd_kdc_37393; break; case TIFFTAG_KDC_37398: /*(0x9216) BYTE (1) 4<00 00 00 0x1>*/ *va_arg(ap, void**) = xd->xd_kdc_37398; break; case TIFFTAG_KDC_37399: /*(0x9217) SHORT (3) 1<2>*/ *va_arg(ap, uint16*) = xd->xd_kdc_37399; break; case TIFFTAG_KDC_33421: /*(0x828d) SHORT (3) 2<2 2>*/ *va_arg(ap, uint16**) = xd->xd_kdc_33421; break; case TIFFTAG_KDC_33422: /*(0x828e) BYTE (1) 4<0x1 0x2 00 0x1>*/ *va_arg(ap, void**) = xd->xd_kdc_33422; break; case TIFFTAG_KDC_37122: /*(0x9102) RATIONAL (5) 1<0.75>*/ *va_arg(ap, uint32**) = xd->xd_kdc_37122; break; case TIFFTAG_KDC_37400: /*(0x9218) SRATIONAL (10) 12<0 -2.02926 1.04202*/ *va_arg(ap, uint32**) = xd->xd_kdc_37400; break; case TIFFTAG_COPYRIGHT: *va_arg(ap, char**) = xd->xd_copyright; break; default: /* return inherited method */ return (PARENT(xt,vgetfield))(tif,tag,ap); break; } return (1); } #define CleanupField(member) { \ if (xd->member) { \ _TIFFfree(xd->member); \ xd->member = 0; \ } \ } /* * Release storage associated with a directory. */ static void _XTIFFFreeDirectory(xtiff* xt) { XTIFFDirectory* xd = &xt->xtif_dir; /* * XXX - Purge all Your allocated memory except * for the xtiff directory itself. This includes * all fields that require a _TIFFsetXXX call in * _XTIFFVSetField(). */ CleanupField(xd_kdc_33423); CleanupField(xd_kdc_33434); /* RATIONAL */ CleanupField(xd_kdc_33437); /* RATIONAL */ CleanupField(xd_kdc_36867); CleanupField(xd_kdc_37382); /* RATIONAL */ CleanupField(xd_kdc_37386); /* RATIONAL */ CleanupField(xd_kdc_37398); CleanupField(xd_kdc_33421); CleanupField(xd_kdc_33422); CleanupField(xd_kdc_37122); /* RATIONAL */ CleanupField(xd_kdc_37400); /* 24 x SRATIONAL */ CleanupField(xd_copyright); } #undef CleanupField static void _XTIFFLocalDefaultDirectory(TIFF *tif) { xtiff *xt = XTIFFDIR(tif); /*XTIFFDirectory* xd = &xt->xtif_dir;*/ /* Install the extended Tag field info */ _TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo)); /* * free up any dynamically allocated arrays * before the new directory is read in. */ _XTIFFFreeDirectory(xt); _TIFFmemset(xt,0,sizeof(xtiff)); /* Override the tag access methods */ PARENT(xt,vsetfield) = TIFFMEMBER(tif,vsetfield); TIFFMEMBER(tif,vsetfield) = _XTIFFVSetField; PARENT(xt,vgetfield) = TIFFMEMBER(tif,vgetfield); TIFFMEMBER(tif,vgetfield) = _XTIFFVGetField; /* * XXX Set up any default values here. */ } /********************************************************************** * Nothing below this line should need to be changed. **********************************************************************/ static TIFFExtendProc _ParentExtender; /* * This is the callback procedure, and is * called by the DefaultDirectory method * every time a new TIFF directory is opened. */ static void _XTIFFDefaultDirectory(TIFF *tif) { xtiff *xt; /* Allocate Directory Structure if first time, and install it */ if (!(tif->tif_flags & XTIFF_INITIALIZED)) { xt = _TIFFmalloc(sizeof(xtiff)); if (!xt) { /* handle memory allocation failure here ! */ return; } _TIFFmemset(xt,0,sizeof(xtiff)); /* * Install into TIFF structure. */ TIFFMEMBER(tif,clientdir) = (tidata_t)xt; tif->tif_flags |= XTIFF_INITIALIZED; /* dont do this again! */ } /* set up our own defaults */ _XTIFFLocalDefaultDirectory(tif); /* Since an XTIFF client module may have overridden * the default directory method, we call it now to * allow it to set up the rest of its own methods. */ if (_ParentExtender) (*_ParentExtender)(tif); } /* * XTIFF Initializer -- sets up the callback * procedure for the TIFF module. */ static void _XTIFFInitialize(void) { static int first_time=1; if (! first_time) return; /* Been there. Done that. */ first_time = 0; /* Grab the inherited method and install */ _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory); } /* * Public File I/O Routines. */ TIFF* XTIFFOpen(const char* name, const char* mode) { /* Set up the callback */ _XTIFFInitialize(); /* Open the file; the callback will set everything up */ return TIFFOpen(name, mode); } TIFF* XTIFFFdOpen(int fd, const char* name, const char* mode) { /* Set up the callback */ _XTIFFInitialize(); /* Open the file; the callback will set everything up */ return TIFFFdOpen(fd, name, mode); } void XTIFFClose(TIFF *tif) { xtiff *xt = XTIFFDIR(tif); /* call inherited function first */ TIFFClose(tif); /* Free up extended allocated memory */ _XTIFFFreeDirectory(xt); _TIFFfree(xt); }