const TIFFFieldInfo *
DECLARE1(TIFFFieldWithTag, u_short, tag)
{
	const TIFFFieldInfo *fip = TIFFFindFieldInfo(tag, TIFF_ANY);
	if (fip)
		return (fip);
	TIFFError("TIFFFieldWithTag", "Internal error, unknown tag 0x%x", tag);
	assert(fip != NULL);
	/*NOTREACHED*/
}
示例#2
0
TIFFFieldInfo const *
DECLARE1(TIFFFieldWithTag, u_short, tag)
{
	TIFFFieldInfo const *fip = TIFFFindFieldInfo(tag, TIFF_ANY);
	if (fip)
		return (fip);
	TIFFError("TIFFFieldWithTag", "Internal error, unknown tag 0x%x", tag);
	exit(-1);
	/*NOTREACHED*/
}
示例#3
0
const TIFFFieldInfo*
TIFFFieldWithTag(TIFF* tif, ttag_t tag)
{
	const TIFFFieldInfo* fip = TIFFFindFieldInfo(tif, tag, TIFF_ANY);
	if (!fip) {
		_TIFFError(tif, "TIFFFieldWithTag",
			  "Internal error, unknown tag 0x%x",
                          (unsigned int) tag);
		assert(fip != NULL);
		/*NOTREACHED*/
	}
	return (fip);
}
示例#4
0
const TIFFFieldInfo*
_TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )

{
    const TIFFFieldInfo *fld;

    fld = TIFFFindFieldInfo( tif, tag, dt );
    if( fld == NULL )
    {
        fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
        TIFFMergeFieldInfo( tif, fld, 1 );
    }

    return fld;
}
示例#5
0
    // Search for TIFF tag 'tagid' having type 'tifftype', and if found,
    // add it in the obvious way to m_spec under the name 'oiioname'.
    void find_tag (int tifftag, TIFFDataType tifftype, const char *oiioname) {
#ifdef TIFF_VERSION_BIG
        const TIFFField *info = TIFFFindField (m_tif, tifftag, tifftype);
#else
        const TIFFFieldInfo *info = TIFFFindFieldInfo (m_tif, tifftag, tifftype);
#endif
        if (! info) {
            // Something has gone wrong, libtiff doesn't think the field type
            // is the same as we do.
            return;
        }
        if (tifftype == TIFF_ASCII)
            get_string_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_SHORT)
            get_short_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_LONG)
            get_int_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL ||
                 tifftype == TIFF_FLOAT || tifftype == TIFF_DOUBLE)
            get_float_attribute (oiioname, tifftag);
    }
示例#6
0
/**
Read a single exif tag
*/
static BOOL
tiff_read_exif_tag(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib, TagLib& tagLib, TIFFDirectory *td, ttag_t tag) {
    const TIFFFieldInfo *fip;
    uint32 value_count;
    int mem_alloc = 0;
    void *raw_data = NULL;

    if(tag == TIFFTAG_EXIFIFD) {
        return TRUE;
    }

    // get the tag key - use NULL to avoid reading GeoTIFF tags
    const char *key = tagLib.getTagFieldName(md_model, (WORD)tag, NULL);
    if(key == NULL) {
        return TRUE;
    }

    fip = TIFFFieldWithTag(tif, tag);
    if(fip == NULL) {
        return TRUE;
    }

    // ### for some reason TIFFFieldWithTag returns wrong version (TIFF_LONG vs TIFF_SHORT) for some params, correct this
    if(fip->field_tag == TIFFTAG_IMAGEWIDTH && fip->field_type == TIFF_SHORT) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
    } else if(fip->field_tag == TIFFTAG_IMAGELENGTH && fip->field_type == TIFF_SHORT) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
    } else if(fip->field_tag == TIFFTAG_BITSPERSAMPLE && fip->field_type == TIFF_LONG) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
    } else if(fip->field_tag == TIFFTAG_COMPRESSION && fip->field_type == TIFF_LONG) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
    } else if(fip->field_tag == TIFFTAG_PHOTOMETRIC && fip->field_type == TIFF_LONG) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
    } else if(fip->field_tag == TIFFTAG_ROWSPERSTRIP && fip->field_type == TIFF_SHORT) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
    } else if(fip->field_tag == TIFFTAG_STRIPOFFSETS && fip->field_type == TIFF_SHORT) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
    } else if(fip->field_tag == TIFFTAG_STRIPBYTECOUNTS && fip->field_type == TIFF_SHORT) {
        fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
    }
    // ### the tags left unchecked are SGI, Pixar and DNG tags filtered by tagLib.getTagFieldName


    if(fip->field_passcount) { //<- "passcount" means "returns count"
        if (fip->field_readcount != TIFF_VARIABLE2) { //<- TIFF_VARIABLE2 means "uses LONG count"

            // assume TIFF_VARIABLE (uses SHORT count)
            uint16 value_count16;
            if(TIFFGetField(tif, tag, &value_count16, &raw_data) != 1) {
                return TRUE;
            }
            value_count = value_count16;
        } else {
            if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) {
                return TRUE;
            }
        }
    } else {

        // determine count

        if (fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE2) {
            value_count = 1;
        } else if (fip->field_readcount == TIFF_SPP) {
            value_count = td->td_samplesperpixel;
        } else {
            value_count = fip->field_readcount;
        }

        // access fields as pointers to data
        // (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code)

        if(fip->field_tag == TIFFTAG_TRANSFERFUNCTION) {
            // reading this tag cause a bug probably located somewhere inside libtiff
            return TRUE;
        }

        if ((fip->field_type == TIFF_ASCII
                || fip->field_readcount == TIFF_VARIABLE
                || fip->field_readcount == TIFF_VARIABLE2
                || fip->field_readcount == TIFF_SPP
                || value_count > 1)

                && fip->field_tag != TIFFTAG_PAGENUMBER
                && fip->field_tag != TIFFTAG_HALFTONEHINTS
                && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
                && fip->field_tag != TIFFTAG_DOTRANGE

                && fip->field_tag != TIFFTAG_BITSPERSAMPLE	//<- these two are tricky -
                && fip->field_tag != TIFFTAG_COMPRESSION	//<- they are defined as TIFF_VARIABLE but in reality return a single value
           ) {
            if(TIFFGetField(tif, tag, &raw_data) != 1) {
                return TRUE;
            }
        } else {

            // access fields as values

            const int value_size = _TIFFDataSize(fip->field_type);
            raw_data = _TIFFmalloc(value_size * value_count);
            mem_alloc = 1;
            int ok = FALSE;

            // ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE,
            // all off which are value_count == 2 (see tif_dirinfo.c)
            switch(value_count)
            {
            case 1:
                ok = TIFFGetField(tif, tag, raw_data);
                break;
            case 2:
                ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1);
                break;
            /* # we might need more in the future:
            				case 3:
            					ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2);
            					break;
            */
            default:
                FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", fip->field_name);
                break;
            }
            if(ok != 1) {
                _TIFFfree(raw_data);
                return TRUE;
            }
        }
    }

    // build FreeImage tag from Tiff Tag data we collected

    FITAG *fitag = FreeImage_CreateTag();
    if(!fitag) {
        if(mem_alloc) {
            _TIFFfree(raw_data);
        }
        return FALSE;
    }

    FreeImage_SetTagID(fitag, (WORD)tag);
    FreeImage_SetTagKey(fitag, key);

    switch(fip->field_type) {
    case TIFF_BYTE:
        FreeImage_SetTagType(fitag, FIDT_BYTE);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_UNDEFINED:
        FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_SBYTE:
        FreeImage_SetTagType(fitag, FIDT_SBYTE);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_SHORT:
        FreeImage_SetTagType(fitag, FIDT_SHORT);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_SSHORT:
        FreeImage_SetTagType(fitag, FIDT_SSHORT);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_LONG:
        FreeImage_SetTagType(fitag, FIDT_LONG);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_IFD:
        FreeImage_SetTagType(fitag, FIDT_IFD);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_SLONG:
        FreeImage_SetTagType(fitag, FIDT_SLONG);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_RATIONAL: {
        // LibTIFF converts rational to floats : reconvert floats to rationals
        DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
        for(uint32 i = 0; i < value_count; i++) {
            float *fv = (float*)raw_data;
            FIRational rational(fv[i]);
            rvalue[2*i] = rational.getNumerator();
            rvalue[2*i+1] = rational.getDenominator();
        }
        FreeImage_SetTagType(fitag, FIDT_RATIONAL);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, rvalue);
        free(rvalue);
    }
    break;

    case TIFF_SRATIONAL: {
        // LibTIFF converts rational to floats : reconvert floats to rationals
        LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
        for(uint32 i = 0; i < value_count; i++) {
            float *fv = (float*)raw_data;
            FIRational rational(fv[i]);
            rvalue[2*i] = rational.getNumerator();
            rvalue[2*i+1] = rational.getDenominator();
        }
        FreeImage_SetTagType(fitag, FIDT_RATIONAL);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, rvalue);
        free(rvalue);
    }
    break;

    case TIFF_FLOAT:
        FreeImage_SetTagType(fitag, FIDT_FLOAT);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    case TIFF_DOUBLE:
        FreeImage_SetTagType(fitag, FIDT_DOUBLE);
        FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
        FreeImage_SetTagCount(fitag, value_count);
        FreeImage_SetTagValue(fitag, raw_data);
        break;

    default: {
        size_t length = strlen((char*)raw_data) + 1;
        FreeImage_SetTagType(fitag, FIDT_ASCII);
        FreeImage_SetTagLength(fitag, (DWORD)length);
        FreeImage_SetTagCount(fitag, (DWORD)length);
        FreeImage_SetTagValue(fitag, raw_data);
    }
    break;
    }

    const char *description = tagLib.getTagDescription(md_model, (WORD)tag);
    if(description) {
        FreeImage_SetTagDescription(fitag, description);
    }
    // store the tag
    FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);

    // destroy the tag
    FreeImage_DeleteTag(fitag);

    if(mem_alloc) {
        _TIFFfree(raw_data);
    }
    return TRUE;
}