示例#1
0
bool
TIFFOutput::write_exif_data ()
{
#if defined(TIFF_VERSION_BIG) && TIFFLIB_VERSION >= 20120922
    // Older versions of libtiff do not support writing Exif directories

    if (m_spec.get_int_attribute ("tiff:write_exif", 1) == 0) {
        // The special metadata "tiff:write_exif", if present and set to 0
        // (the default is 1), will cause us to skip outputting Exif data.
        // This is useful in cases where we think the TIFF file will need to
        // be read by an app that links against an old version of libtiff
        // that will have trouble reading the Exif directory.
        return true;
    }

    // First, see if we have any Exif data at all
    bool any_exif = false;
    for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) {
        const ImageIOParameter &p (m_spec.extra_attribs[i]);
        int tag, tifftype, count;
        if (exif_tag_lookup (p.name(), tag, tifftype, count) &&
                tifftype != TIFF_NOTYPE) {
            if (tag == EXIFTAG_SECURITYCLASSIFICATION ||
                tag == EXIFTAG_IMAGEHISTORY ||
                tag == EXIFTAG_ISOSPEEDRATINGS)
                continue;   // libtiff doesn't understand these
            any_exif = true;
            break;
        }
    }
    if (! any_exif)
        return true;

    if (m_compression == COMPRESSION_JPEG) {
        // For reasons we don't understand, JPEG-compressed TIFF seems
        // to not output properly without a directory checkpoint here.
        TIFFCheckpointDirectory (m_tif);
    }

    // First, finish writing the current directory
    if (! TIFFWriteDirectory (m_tif)) {
        error ("failed TIFFWriteDirectory()");
        return false;
    }

    // Create an Exif directory
    if (TIFFCreateEXIFDirectory (m_tif) != 0) {
        error ("failed TIFFCreateEXIFDirectory()");
        return false;
    }

    for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) {
        const ImageIOParameter &p (m_spec.extra_attribs[i]);
        int tag, tifftype, count;
        if (exif_tag_lookup (p.name(), tag, tifftype, count) &&
                tifftype != TIFF_NOTYPE) {
            if (tag == EXIFTAG_SECURITYCLASSIFICATION ||
                tag == EXIFTAG_IMAGEHISTORY ||
                tag == EXIFTAG_ISOSPEEDRATINGS)
                continue;   // libtiff doesn't understand these
            bool ok = false;
            if (tifftype == TIFF_ASCII) {
                ok = TIFFSetField (m_tif, tag, *(char**)p.data());
            } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) &&
                       p.type() == TypeDesc::SHORT) {
                ok = TIFFSetField (m_tif, tag, (int)*(short *)p.data());
            } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) &&
                       p.type() == TypeDesc::INT) {
                ok = TIFFSetField (m_tif, tag, *(int *)p.data());
            } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) &&
                       p.type() == TypeDesc::FLOAT) {
                ok = TIFFSetField (m_tif, tag, *(float *)p.data());
            } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) &&
                       p.type() == TypeDesc::DOUBLE) {
                ok = TIFFSetField (m_tif, tag, *(double *)p.data());
            }
            if (! ok) {
                // std::cout << "Unhandled EXIF " << p.name() << " " << p.type() << "\n";
            }
        }
    }

    // Now write the directory of Exif data
    uint64 dir_offset = 0;
    if (! TIFFWriteCustomDirectory (m_tif, &dir_offset)) {
        error ("failed TIFFWriteCustomDirectory() of the Exif data");
        return false;
    }
    // Go back to the first directory, and add the EXIFIFD pointer. 
    // std::cout << "diffdir = " << tiffdir << "\n";
    TIFFSetDirectory (m_tif, 0);
    TIFFSetField (m_tif, TIFFTAG_EXIFIFD, dir_offset);
#endif

    return true;  // all is ok
}
bool
TIFFOutput::write_exif_data ()
{
#if defined(TIFF_VERSION_BIG) && TIFFLIB_VERSION >= 20120922
    // Older versions of libtiff do not support writing Exif directories

    // First, see if we have any Exif data at all
    bool any_exif = false;
    for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) {
        const ImageIOParameter &p (m_spec.extra_attribs[i]);
        int tag, tifftype, count;
        if (exif_tag_lookup (p.name(), tag, tifftype, count) &&
                tifftype != TIFF_NOTYPE) {
            if (tag == EXIFTAG_SECURITYCLASSIFICATION ||
                tag == EXIFTAG_IMAGEHISTORY ||
                tag == EXIFTAG_ISOSPEEDRATINGS)
                continue;   // libtiff doesn't understand these
            any_exif = true;
            break;
        }
    }
    if (! any_exif)
        return true;

    // First, finish writing the current directory
    if (! TIFFWriteDirectory (m_tif)) {
        error ("failed TIFFWriteDirectory()");
        return false;
    }

    // Create an Exif directory
    if (TIFFCreateEXIFDirectory (m_tif) != 0) {
        error ("failed TIFFCreateEXIFDirectory()");
        return false;
    }

    for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) {
        const ImageIOParameter &p (m_spec.extra_attribs[i]);
        int tag, tifftype, count;
        if (exif_tag_lookup (p.name(), tag, tifftype, count) &&
                tifftype != TIFF_NOTYPE) {
            if (tag == EXIFTAG_SECURITYCLASSIFICATION ||
                tag == EXIFTAG_IMAGEHISTORY ||
                tag == EXIFTAG_ISOSPEEDRATINGS)
                continue;   // libtiff doesn't understand these
            bool ok = false;
            if (tifftype == TIFF_ASCII) {
                ok = TIFFSetField (m_tif, tag, *(char**)p.data());
            } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) &&
                       p.type() == TypeDesc::SHORT) {
                ok = TIFFSetField (m_tif, tag, (int)*(short *)p.data());
            } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) &&
                       p.type() == TypeDesc::INT) {
                ok = TIFFSetField (m_tif, tag, *(int *)p.data());
            } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) &&
                       p.type() == TypeDesc::FLOAT) {
                ok = TIFFSetField (m_tif, tag, *(float *)p.data());
            } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) &&
                       p.type() == TypeDesc::DOUBLE) {
                ok = TIFFSetField (m_tif, tag, *(double *)p.data());
            }
            if (! ok) {
                // std::cout << "Unhandled EXIF " << p.name() << " " << p.type() << "\n";
            }
        }
    }

    // Now write the directory of Exif data
    uint64 dir_offset = 0;
    if (! TIFFWriteCustomDirectory (m_tif, &dir_offset)) {
        error ("failed TIFFWriteCustomDirectory() of the Exif data");
        return false;
    }
    // Go back to the first directory, and add the EXIFIFD pointer. 
    // std::cout << "diffdir = " << tiffdir << "\n";
    TIFFSetDirectory (m_tif, 0);
    TIFFSetField (m_tif, TIFFTAG_EXIFIFD, dir_offset);
#endif

    return true;  // all is ok
}