TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
{
	static const char module[] = "TIFFAdvanceDirectory";
	if (isMapped(tif))
	{
		uint64 poff=*nextdir;
		if (!(tif->tif_flags&TIFF_BIGTIFF))
		{
			tmsize_t poffa,poffb,poffc,poffd;
			uint16 dircount;
			uint32 nextdir32;
			poffa=(tmsize_t)poff;
			poffb=poffa+sizeof(uint16);
			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
                                  *nextdir=0;
				return(0);
			}
			_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
			if (tif->tif_flags&TIFF_SWAB)
				TIFFSwabShort(&dircount);
			poffc=poffb+dircount*12;
			poffd=poffc+sizeof(uint32);
			if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
				return(0);
			}
			if (off!=NULL)
				*off=(uint64)poffc;
			_TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
			if (tif->tif_flags&TIFF_SWAB)
				TIFFSwabLong(&nextdir32);
			*nextdir=nextdir32;
		}
		else
		{
			tmsize_t poffa,poffb,poffc,poffd;
			uint64 dircount64;
			uint16 dircount16;
			poffa=(tmsize_t)poff;
			poffb=poffa+sizeof(uint64);
			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
				return(0);
			}
			_TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
			if (tif->tif_flags&TIFF_SWAB)
				TIFFSwabLong8(&dircount64);
			if (dircount64>0xFFFF)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
				return(0);
			}
			dircount16=(uint16)dircount64;
			poffc=poffb+dircount16*20;
			poffd=poffc+sizeof(uint64);
			if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
				return(0);
			}
			if (off!=NULL)
				*off=(uint64)poffc;
			_TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
			if (tif->tif_flags&TIFF_SWAB)
				TIFFSwabLong8(nextdir);
		}
		return(1);
	}
	else
	{
		if (!(tif->tif_flags&TIFF_BIGTIFF))
		{
			uint16 dircount;
			uint32 nextdir32;
			if (!SeekOK(tif, *nextdir) ||
			    !ReadOK(tif, &dircount, sizeof (uint16))) {
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
				    tif->tif_name);
				return (0);
			}
			if (tif->tif_flags & TIFF_SWAB)
				TIFFSwabShort(&dircount);
			if (off != NULL)
				*off = TIFFSeekFile(tif,
				    dircount*12, SEEK_CUR);
			else
				(void) TIFFSeekFile(tif,
				    dircount*12, SEEK_CUR);
			if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
				    tif->tif_name);
				return (0);
			}
			if (tif->tif_flags & TIFF_SWAB)
				TIFFSwabLong(&nextdir32);
			*nextdir=nextdir32;
		}
		else
		{
			uint64 dircount64;
			uint16 dircount16;
			if (!SeekOK(tif, *nextdir) ||
			    !ReadOK(tif, &dircount64, sizeof (uint64))) {
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
				    tif->tif_name);
				return (0);
			}
			if (tif->tif_flags & TIFF_SWAB)
				TIFFSwabLong8(&dircount64);
			if (dircount64>0xFFFF)
			{
				TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
				return(0);
			}
			dircount16 = (uint16)dircount64;
			if (off != NULL)
				*off = TIFFSeekFile(tif,
				    dircount16*20, SEEK_CUR);
			else
				(void) TIFFSeekFile(tif,
				    dircount16*20, SEEK_CUR);
			if (!ReadOK(tif, nextdir, sizeof (uint64))) {
				TIFFErrorExt(tif->tif_clientdata, module,
                                             "%s: Error fetching directory link",
				    tif->tif_name);
				return (0);
			}
			if (tif->tif_flags & TIFF_SWAB)
				TIFFSwabLong8(nextdir);
		}
		return (1);
	}
}