⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_dirwrite.c

📁 一款最完整的工业组态软源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	rc = _TIFFWriteDirectory(tif, FALSE);
	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
	return rc;
}

/*
 * Process tags that are not special cased.
 */
static int
TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
{
	unsigned short wc = (unsigned short) fip->field_writecount;
	uint32 wc2;

	dir->tdir_tag = (uint16) fip->field_tag;
	dir->tdir_type = (unsigned short) fip->field_type;
	dir->tdir_count = wc;
#define	WRITEF(x,y)	x(tif, fip->field_type, fip->field_tag, dir, wc, y)
	switch (fip->field_type) {
	case TIFF_SHORT:
	case TIFF_SSHORT:
		if (wc > 1) {
			uint16* wp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount)
				TIFFGetField(tif, fip->field_tag, &wc, &wp);
			else
				TIFFGetField(tif, fip->field_tag, &wp);
			if (!WRITEF(TIFFWriteShortArray, wp))
				return (0);
		} else {
			if (fip->field_passcount) {
				uint16* wp;
				TIFFGetField(tif, fip->field_tag, &wc, &wp);
				if (!WRITEF(TIFFWriteShortArray, wp))
					return 0;
			} else {
				uint16 sv;
				TIFFGetField(tif, fip->field_tag, &sv);
				dir->tdir_offset =
					TIFFInsertData(tif, dir->tdir_type, sv);
			}
		}
		break;
	case TIFF_LONG:
	case TIFF_SLONG:
	case TIFF_IFD:
		if (wc > 1) {
			uint32* lp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount)
				TIFFGetField(tif, fip->field_tag, &wc, &lp);
			else
				TIFFGetField(tif, fip->field_tag, &lp);
			if (!WRITEF(TIFFWriteLongArray, lp))
				return (0);
		} else {
			if (fip->field_passcount) {
				uint32* lp;
				TIFFGetField(tif, fip->field_tag, &wc, &lp);
				if (!WRITEF(TIFFWriteLongArray, lp))
					return 0;
			} else {
				/* XXX handle LONG->SHORT conversion */
				TIFFGetField(tif, fip->field_tag,
					     &dir->tdir_offset);
			}
		}
		break;
	case TIFF_RATIONAL:
	case TIFF_SRATIONAL:
		if (wc > 1) {
			float* fp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount)
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
			else
				TIFFGetField(tif, fip->field_tag, &fp);
			if (!WRITEF(TIFFWriteRationalArray, fp))
				return (0);
		} else {
			if (fip->field_passcount) {
				float* fp;
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
				if (!WRITEF(TIFFWriteRationalArray, fp))
					return 0;
			} else {
				float fv;
				TIFFGetField(tif, fip->field_tag, &fv);
				if (!WRITEF(TIFFWriteRationalArray, &fv))
					return (0);
			}
		}
		break;
	case TIFF_FLOAT:
		if (wc > 1) {
			float* fp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount)
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
			else
				TIFFGetField(tif, fip->field_tag, &fp);
			if (!WRITEF(TIFFWriteFloatArray, fp))
				return (0);
		} else {
			if (fip->field_passcount) {
				float* fp;
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
				if (!WRITEF(TIFFWriteFloatArray, fp))
					return 0;
			} else {
				float fv;
				TIFFGetField(tif, fip->field_tag, &fv);
				if (!WRITEF(TIFFWriteFloatArray, &fv))
					return (0);
			}
		}
		break;
	case TIFF_DOUBLE:
		if (wc > 1) {
			double* dp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount)
				TIFFGetField(tif, fip->field_tag, &wc, &dp);
			else
				TIFFGetField(tif, fip->field_tag, &dp);
			if (!WRITEF(TIFFWriteDoubleArray, dp))
				return (0);
		} else {
			if (fip->field_passcount) {
				double* dp;
				TIFFGetField(tif, fip->field_tag, &wc, &dp);
				if (!WRITEF(TIFFWriteDoubleArray, dp))
					return 0;
			} else {
				double dv;
				TIFFGetField(tif, fip->field_tag, &dv);
				if (!WRITEF(TIFFWriteDoubleArray, &dv))
					return (0);
			}
		}
		break;
	case TIFF_ASCII:
		{ 
                    char* cp;
                    if (fip->field_passcount)
                        TIFFGetField(tif, fip->field_tag, &wc, &cp);
                    else
                        TIFFGetField(tif, fip->field_tag, &cp);

                    dir->tdir_count = (uint32) (strlen(cp) + 1);
                    if (!TIFFWriteByteArray(tif, dir, cp))
                        return (0);
		}
		break;

        /* added based on patch request from MARTIN.MCBRIDE.MM@agfa.co.uk,
           correctness not verified (FW, 99/08) */
        case TIFF_BYTE:
        case TIFF_SBYTE:          
		if (wc > 1) {
			char* cp;
			if (wc == (unsigned short) TIFF_VARIABLE
			    || fip->field_passcount) {
				TIFFGetField(tif, fip->field_tag, &wc, &cp);
				dir->tdir_count = wc;
			} else if (wc == (unsigned short) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &cp);
				dir->tdir_count = wc2;
			} else
				TIFFGetField(tif, fip->field_tag, &cp);
			if (!TIFFWriteByteArray(tif, dir, cp))
				return (0);
                } else {
			if (fip->field_passcount) {
				char* cp;
				TIFFGetField(tif, fip->field_tag, &wc, &cp);
				dir->tdir_count = wc;
				if (!TIFFWriteByteArray(tif, dir, cp))
					return 0;
			} else {
				char cv;
				TIFFGetField(tif, fip->field_tag, &cv);
				if (!TIFFWriteByteArray(tif, dir, &cv))
					return (0);
			}
                }
                break;

	case TIFF_UNDEFINED:
		{ char* cp;
		  if (wc == (unsigned short) TIFF_VARIABLE) {
			TIFFGetField(tif, fip->field_tag, &wc, &cp);
			dir->tdir_count = wc;
		  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
			TIFFGetField(tif, fip->field_tag, &wc2, &cp);
			dir->tdir_count = wc2;
		  } else 
			TIFFGetField(tif, fip->field_tag, &cp);
		  if (!TIFFWriteByteArray(tif, dir, cp))
			return (0);
		}
		break;

        case TIFF_NOTYPE:
                break;
	}
	return (1);
}
#undef WRITEF

/*
 * Setup a directory entry with either a SHORT
 * or LONG type according to the value.
 */
static void
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_count = 1;
	if (v > 0xffffL) {
		dir->tdir_type = (short) TIFF_LONG;
		dir->tdir_offset = v;
	} else {
		dir->tdir_type = (short) TIFF_SHORT;
		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
	}
}

/*
 * Setup a SHORT directory entry
 */
static void
TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_count = 1;
	dir->tdir_type = (short) TIFF_SHORT;
	dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
}
#undef MakeShortDirent

#ifndef TIFFWriteRational
/*
 * Setup a RATIONAL directory entry and
 * write the associated indirect value.
 */
static int
TIFFWriteRational(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v)
{
	return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v));
}
#endif

#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
/*
 * Setup a directory entry that references a
 * samples/pixel array of SHORT values and
 * (potentially) write the associated indirect
 * values.
 */
static int
TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
{
	uint16 buf[10], v;
	uint16* w = buf;
	int i, status, samples = tif->tif_dir.td_samplesperpixel;

	if (samples > NITEMS(buf)) {
		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
		if (w == NULL) {
			TIFFError(tif->tif_name,
			    "No space to write per-sample shorts");
			return (0);
		}
	}
	TIFFGetField(tif, tag, &v);
	for (i = 0; i < samples; i++)
		w[i] = v;
	status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
	if (w != buf)
		_TIFFfree((char*) w);
	return (status);
}

/*
 * Setup a directory entry that references a samples/pixel array of ``type''
 * values and (potentially) write the associated indirect values.  The source
 * data from TIFFGetField() for the specified tag must be returned as double.
 */
static int
TIFFWritePerSampleAnys(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
{
	double buf[10], v;
	double* w = buf;
	int i, status;
	int samples = (int) tif->tif_dir.td_samplesperpixel;

	if (samples > NITEMS(buf)) {
		w = (double*) _TIFFmalloc(samples * sizeof (double));
		if (w == NULL) {
			TIFFError(tif->tif_name,
			    "No space to write per-sample values");
			return (0);
		}
	}
	TIFFGetField(tif, tag, &v);
	for (i = 0; i < samples; i++)
		w[i] = v;
	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
	if (w != buf)
		_TIFFfree(w);
	return (status);
}
#undef NITEMS

/*
 * Setup a pair of shorts that are returned by
 * value, rather than as a reference to an array.
 */
static int
TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
{
	uint16 v[2];

	TIFFGetField(tif, tag, &v[0], &v[1]);
	return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
}

/*
 * Setup a directory entry for an NxM table of shorts,
 * where M is known to be 2**bitspersample, and write
 * the associated indirect data.
 */
static int
TIFFWriteShortTable(TIFF* tif,
    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
{
	uint32 i, off;

	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (short) TIFF_SHORT;
	/* XXX -- yech, fool TIFFWriteData */
	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
	off = tif->tif_dataoff;
	for (i = 0; i < n; i++)
		if (!TIFFWriteData(tif, dir, (char *)table[i]))
			return (0);
	dir->tdir_count *= n;
	dir->tdir_offset = off;
	return (1);
}

/*
 * Write/copy data associated with an ASCII or opaque tag value.
 */
static int
TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
{
	if (dir->tdir_count > 4) {
		if (!TIFFWriteData(tif, dir, cp))
			return (0);
	} else
		_TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
	return (1);
}

/*
 * Setup a directory entry of an array of SHORT
 * or SSHORT and write the associated indirect values.
 */
static int
TIFFWriteShortArray(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (short) type;
	dir->tdir_count = n;
	if (n <= 2) {
		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
			dir->tdir_offset = (uint32) ((long) v[0] << 16);
			if (n == 2)
				dir->tdir_offset |= v[1] & 0xffff;
		} else {
			dir->tdir_offset = v[0] & 0xffff;
			if (n == 2)
				dir->tdir_offset |= (long) v[1] << 16;
		}
		return (1);
	} else
		return (TIFFWriteData(tif, dir, (char*) v));
}

/*
 * Setup a directory entry of an array of LONG
 * or SLONG and write the associated indirect values.
 */
static int
TIFFWriteLongArray(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (short) type;
	dir->tdir_count = n;
	if (n == 1) {
		dir->tdir_offset = v[0];
		return (1);
	} else
		return (TIFFWriteData(tif, dir, (char*) v));
}

/*
 * Setup a directory entry of an array of RATIONAL
 * or SRATIONAL and write the associated indirect values.

⌨️ 快捷键说明

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