Support for custom tags, passed by value.

This commit is contained in:
Andrey Kiselev 2005-03-17 14:43:14 +00:00
parent ca3bdcae22
commit 6ba5a639fc

View File

@ -1,4 +1,4 @@
/* $Id: tif_dir.c,v 1.43 2004-12-03 13:16:55 dron Exp $ */ /* $Id: tif_dir.c,v 1.44 2005-03-17 14:43:14 dron Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -498,8 +498,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
* between compression schemes and codec-specific tags * between compression schemes and codec-specific tags
* are blindly copied. * are blindly copied.
*/ */
if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
{
TIFFError(module, TIFFError(module,
"%s: Invalid %stag \"%s\" (not supported by codec)", "%s: Invalid %stag \"%s\" (not supported by codec)",
tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
@ -512,13 +511,11 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
* Find the existing entry for this custom value. * Find the existing entry for this custom value.
*/ */
tv = NULL; tv = NULL;
for( iCustom = 0; iCustom < td->td_customValueCount; iCustom++ ) for(iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
{ if(td->td_customValues[iCustom].info == fip) {
if( td->td_customValues[iCustom].info == fip )
{
tv = td->td_customValues + iCustom; tv = td->td_customValues + iCustom;
if( tv->value != NULL ) if(tv->value != NULL)
_TIFFfree( tv->value ); _TIFFfree(tv->value);
break; break;
} }
} }
@ -526,8 +523,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
/* /*
* Grow the custom list if the entry was not found. * Grow the custom list if the entry was not found.
*/ */
if( tv == NULL ) if(tv == NULL) {
{
TIFFTagValue *new_customValues; TIFFTagValue *new_customValues;
td->td_customValueCount++; td->td_customValueCount++;
@ -553,83 +549,82 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
/* /*
* Set custom value ... save a copy of the custom tag value. * Set custom value ... save a copy of the custom tag value.
*/ */
switch (fip->field_type) { tv_size = _TIFFDataSize(fip->field_type);
/* if (tv_size == 0) {
* XXX: We can't use TIFFDataWidth() to determine the status = 0;
* space needed to store the value. For TIFF_RATIONAL TIFFError(module, "%s: Bad field type %d for \"%s\"",
* values TIFFDataWidth() returns 8, but we use 4-byte tif->tif_name, fip->field_type,
* float to represent rationals. fip->field_name);
*/ goto end;
case TIFF_BYTE:
case TIFF_ASCII:
case TIFF_SBYTE:
case TIFF_UNDEFINED:
tv_size = 1;
break;
case TIFF_SHORT:
case TIFF_SSHORT:
tv_size = 2;
break;
case TIFF_LONG:
case TIFF_SLONG:
case TIFF_FLOAT:
case TIFF_IFD:
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
tv_size = 4;
break;
case TIFF_DOUBLE:
tv_size = 8;
break;
default:
status = 0;
TIFFError(module, "%s: Bad field type %d for \"%s\"",
tif->tif_name, fip->field_type,
fip->field_name);
goto end;
} }
if(fip->field_passcount) {
if (fip->field_writecount == TIFF_VARIABLE2)
tv->count = (uint32) va_arg(ap, uint32);
else
tv->count = (int) va_arg(ap, int);
}
else if (fip->field_writecount == TIFF_VARIABLE
|| fip->field_writecount == TIFF_VARIABLE2)
tv->count = 1;
else if (fip->field_writecount == TIFF_SPP)
tv->count = td->td_samplesperpixel;
else
tv->count = fip->field_writecount;
if(fip->field_passcount)
tv->count = (int) va_arg(ap, int); if (fip->field_type == TIFF_ASCII) {
else const char *value = va_arg(ap, const char *);
tv->count = 1; tv->count = strlen(value) + 1;
tv->value = _TIFFmalloc(tv->count);
if (fip->field_passcount) {
tv->value = _TIFFmalloc(tv_size * tv->count);
if ( !tv->value ) {
status = 0;
goto end;
}
_TIFFmemcpy(tv->value, (void *) va_arg(ap,void*),
tv->count * tv_size);
} else if (fip->field_type == TIFF_ASCII) {
const char *value = (const char *) va_arg(ap,const char *);
tv->count = strlen(value)+1;
tv->value = _TIFFmalloc(tv->count);
if (!tv->value) { if (!tv->value) {
status = 0; status = 0;
goto end; goto end;
} }
strcpy(tv->value, value); strcpy(tv->value, value);
} else { } else {
/* not supporting "pass by value" types yet */ tv->value = _TIFFmalloc(tv_size * tv->count);
TIFFError(module, if (!tv->value) {
"%s: Pass by value is not implemented.", status = 0;
tif->tif_name); goto end;
}
tv->value = _TIFFmalloc(tv_size * tv->count); if (fip->field_passcount
if (!tv->value) { || fip->field_writecount == TIFF_VARIABLE
status = 0; || fip->field_writecount == TIFF_VARIABLE2
goto end; || fip->field_writecount == TIFF_SPP) {
_TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size);
} else {
switch (fip->field_type) {
case TIFF_BYTE:
case TIFF_SBYTE:
case TIFF_SHORT:
case TIFF_SSHORT:
{
int v = va_arg(ap, int);
_TIFFmemcpy(tv->value, &v, tv_size*tv->count);
}
break;
case TIFF_LONG:
{
uint32 v32 = va_arg(ap, uint32);
_TIFFmemcpy(tv->value, &v32, tv_size*tv->count);
}
break;
case TIFF_SLONG:
{
int32 v32 = va_arg(ap, int32);
_TIFFmemcpy(tv->value, &v32, tv_size*tv->count);
}
break;
default:
_TIFFmemset(tv->value, 0, tv->count * tv_size);
status = 0;
break;
}
} }
_TIFFmemset(tv->value, 0, tv->count * tv_size); }
status = 0;
}
} }
} }
if (status) { if (status) {
@ -997,8 +992,7 @@ _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
** Do we have a custom value? ** Do we have a custom value?
*/ */
ret_val = 0; ret_val = 0;
for (i = 0; i < td->td_customValueCount; i++) for (i = 0; i < td->td_customValueCount; i++) {
{
TIFFTagValue *tv = td->td_customValues + i; TIFFTagValue *tv = td->td_customValues + i;
if (tv->info->field_tag != tag) if (tv->info->field_tag != tag)
@ -1012,15 +1006,46 @@ _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
*va_arg(ap, void **) = tv->value; *va_arg(ap, void **) = tv->value;
ret_val = 1; ret_val = 1;
break; break;
} else if (fip->field_type == TIFF_ASCII) {
*va_arg(ap, void **) = tv->value;
ret_val = 1;
break;
} else { } else {
TIFFError("_TIFFVGetField", switch (fip->field_type) {
"%s: Pass by value is not implemented.", case TIFF_BYTE:
tif->tif_name); *va_arg(ap, uint8*) =
break; *(uint8 *)tv->value;
ret_val = 1;
break;
case TIFF_SBYTE:
*va_arg(ap, int8*) =
*(int8 *)tv->value;
ret_val = 1;
break;
case TIFF_SHORT:
*va_arg(ap, uint16*) =
*(uint16 *)tv->value;
ret_val = 1;
break;
case TIFF_SSHORT:
*va_arg(ap, int16*) =
*(int16 *)tv->value;
ret_val = 1;
break;
case TIFF_LONG:
*va_arg(ap, uint32*) =
*(uint32 *)tv->value;
ret_val = 1;
break;
case TIFF_SLONG:
*va_arg(ap, int32*) =
*(int32 *)tv->value;
ret_val = 1;
break;
case TIFF_ASCII:
*va_arg(ap, void **) = tv->value;
ret_val = 1;
break;
default:
ret_val = 0;
break;
}
} }
} }
} }