int exiv2_metadata_file_open(plugin_info* plugin, const char* fileName) { try { Image::AutoPtr image = Exiv2::ImageFactory::open(fileName); if(!image->good()) { // cerr << "Image could not be read by Exiv2: " << fileName << endl; return -1; } image->readMetadata(); if(image->exifData().empty()) // && image->iptcData().empty()) { // cout << "Image had no EXIF/IPTC metadata: " << fileName << endl; return -1; } plugin->user_data = new Image::AutoPtr(image); } catch(...) { cerr << "Exception in Exiv2 Metadata plugin" << endl; return -1; } return 0; }
Image::AutoPtr ImageFactory::open(const byte* data, long size) { BasicIo::AutoPtr io(new MemIo(data, size)); Image::AutoPtr image = open(io); // may throw if (image.get() == 0) throw Error(12); return image; }
// ***************************************************************************** // Main int main(int argc, char* const argv[]) { try { if (argc != 2) { std::cout << "Usage: " << argv[0] << " image\n"; std::cout << "Commands read from stdin.\n"; return 1; } Image::AutoPtr image = ImageFactory::open(argv[1]); assert (image.get() != 0); image->readMetadata(); // Process commands std::string line; int num = 0; std::getline(std::cin, line); while (line.length() && processLine(line, ++num, image->iptcData())) { std::getline(std::cin, line); } // Save any changes image->writeMetadata(); return 0; } catch (AnyError& e) { std::cout << "Caught Exiv2 exception '" << e << "'\n"; return -1; } }
/* Read the EXIF metadata into the struct * A non-zero return code indicates some data could not be read, * which may require further action. */ int exiv2ReadExif(plugin_info* plugin, metadata_t* metadata) { int errors = 0; try { Image::AutoPtr image = *(Image::AutoPtr*)(plugin->user_data); const ExifData& exif = image->exifData(); const ExifData::const_iterator noValue = exif.end(); ExifData::const_iterator value; errors += set_width(exif, metadata->width); errors += set_height(exif, metadata->height); errors += set_date(exif, metadata->date); } catch(Exiv2::Error& err) { cerr << "Exiv2::Error: " << err.what() << endl; return 1; } catch(...) { cerr << "Exception in Exiv2 metadata plugin" << endl; return 1; } return errors; // Non-zero indicates at least one field could not be read }
Image::AutoPtr ImageFactory::create(int type) { BasicIo::AutoPtr io(new MemIo); Image::AutoPtr image = create(type, io); if (image.get() == 0) throw Error(13, type); return image; }
Image::AutoPtr ImageFactory::open(const std::wstring& wpath) { BasicIo::AutoPtr io(new FileIo(wpath)); Image::AutoPtr image = open(io); // may throw if (image.get() == 0) throw WError(11, wpath); return image; }
Image::AutoPtr newCrwInstance(BasicIo::AutoPtr io, bool create) { Image::AutoPtr image = Image::AutoPtr(new CrwImage(io, create)); if (!image->good()) { image.reset(); } return image; }
Image::AutoPtr newExvInstance(BasicIo::AutoPtr io, bool create) { Image::AutoPtr image; if (create) { image = Image::AutoPtr(new ExvImage(io, true)); } else { image = Image::AutoPtr(new ExvImage(io, false)); } if (!image->good()) image.reset(); return image; }
Image::AutoPtr ImageFactory::create(int type, const std::string& path) { std::auto_ptr<FileIo> fileIo(new FileIo(path)); // Create or overwrite the file, then close it if (fileIo->open("w+b") != 0) { throw Error(10, path, "w+b", strError()); } fileIo->close(); BasicIo::AutoPtr io(fileIo); Image::AutoPtr image = create(type, io); if (image.get() == 0) throw Error(13, type); return image; }
int IptcData::erase(const std::string& path) const { if (!fileExists(path, true)) return -1; Image::AutoPtr image = ImageFactory::instance().open(path); if (image.get() == 0) return -2; // Read all metadata then erase only Iptc data int rc = image->readMetadata(); if (rc == 0) { image->clearIptcData(); rc = image->writeMetadata(); } return rc; } // IptcData::erase
bool readImage(const char* path,Options& /* options */) { using namespace Exiv2; bool bResult = false ; try { Image::AutoPtr image = ImageFactory::open(path); if ( image.get() ) { image->readMetadata(); ExifData &exifData = image->exifData(); bResult = !exifData.empty(); } } catch ( ... ) {}; return bResult ; }
void PgfImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::PgfImage::readMetadata: Reading PGF file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isPgfType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "PGF"); } clearMetadata(); readPgfMagicNumber(*io_); uint32_t headerSize = readPgfHeaderSize(*io_); readPgfHeaderStructure(*io_, &pixelWidth_, &pixelHeight_); // And now, the most interresting, the user data byte array where metadata are stored as small image. long size = 8 + headerSize - io_->tell(); #ifdef DEBUG std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; #endif if (size < 0) throw Error(20); if (size == 0) return; DataBuf imgData(size); std::memset(imgData.pData_, 0x0, imgData.size_); long bufRead = io_->read(imgData.pData_, imgData.size_); if (io_->error()) throw Error(14); if (bufRead != imgData.size_) throw Error(20); Image::AutoPtr image = Exiv2::ImageFactory::open(imgData.pData_, imgData.size_); image->readMetadata(); exifData() = image->exifData(); iptcData() = image->iptcData(); xmpData() = image->xmpData(); } // PgfImage::readMetadata
int IptcData::write(const std::string& path) { // Remove the Iptc section from the file if there is no metadata if (count() == 0) return erase(path); if (!fileExists(path, true)) return -1; Image::AutoPtr image = ImageFactory::instance().open(path); if (image.get() == 0) return -2; DataBuf buf(copy()); // Read all metadata to preserve non-Iptc data int rc = image->readMetadata(); if (rc == 0) { image->setIptcData(buf.pData_, buf.size_); rc = image->writeMetadata(); } return rc; } // IptcData::write
int IptcData::read(const std::string& path) { if (!fileExists(path, true)) return -1; Image::AutoPtr image = ImageFactory::instance().open(path); if (image.get() == 0) { // We don't know this type of file return -2; } int rc = image->readMetadata(); if (rc == 0) { if (image->sizeIptcData() > 0) { rc = read(image->iptcData(), image->sizeIptcData()); } else { rc = 3; } } return rc; }
void PgfImage::doWriteMetadata(BasicIo& outIo) { if (!io_->isopen()) throw Error(20); if (!outIo.isopen()) throw Error(21); #ifdef DEBUG std::cout << "Exiv2::PgfImage::doWriteMetadata: Writing PGF file " << io_->path() << "\n"; std::cout << "Exiv2::PgfImage::doWriteMetadata: tmp file created " << outIo.path() << "\n"; #endif // Ensure that this is the correct image type if (!isPgfType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(20); throw Error(22); } // Ensure PGF version. byte mnb = readPgfMagicNumber(*io_); readPgfHeaderSize(*io_); int w, h; DataBuf header = readPgfHeaderStructure(*io_, w, h); Image::AutoPtr img = ImageFactory::create(ImageType::png); img->setExifData(exifData_); img->setIptcData(iptcData_); img->setXmpData(xmpData_); img->writeMetadata(); int imgSize = img->io().size(); DataBuf imgBuf = img->io().read(imgSize); #ifdef DEBUG std::cout << "Exiv2::PgfImage::doWriteMetadata: Creating image to host metadata (" << imgSize << " bytes)\n"; #endif //--------------------------------------------------------------- // Write PGF Signature. if (outIo.write(pgfSignature, 3) != 3) throw Error(21); // Write Magic number. if (outIo.putb(mnb) == EOF) throw Error(21); // Write new Header size. uint32_t newHeaderSize = header.size_ + imgSize; DataBuf buffer(4); memcpy (buffer.pData_, &newHeaderSize, 4); byteSwap_(buffer,0,bSwap_); if (outIo.write(buffer.pData_, 4) != 4) throw Error(21); #ifdef DEBUG std::cout << "Exiv2::PgfImage: new PGF header size : " << newHeaderSize << " bytes\n"; printf("%x\n", buffer.pData_[0]); printf("%x\n", buffer.pData_[1]); printf("%x\n", buffer.pData_[2]); printf("%x\n", buffer.pData_[3]); #endif // Write Header data. if (outIo.write(header.pData_, header.size_) != header.size_) throw Error(21); // Write new metadata byte array. if (outIo.write(imgBuf.pData_, imgBuf.size_) != imgBuf.size_) throw Error(21); // Copy the rest of PGF image data. DataBuf buf(4096); long readSize = 0; while ((readSize=io_->read(buf.pData_, buf.size_))) { if (outIo.write(buf.pData_, readSize) != readSize) throw Error(21); } if (outIo.error()) throw Error(21); } // PgfImage::doWriteMetadata
void Rw2Image::readMetadata() { #ifdef DEBUG std::cerr << "Reading RW2 file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isRw2Type(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "RW2"); } clearMetadata(); std::ofstream devnull; printStructure(devnull, kpsRecursive, 0); ByteOrder bo = Rw2Parser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size()); setByteOrder(bo); // A lot more metadata is hidden in the embedded preview image // Todo: This should go into the Rw2Parser, but for that it needs the Image PreviewManager loader(*this); PreviewPropertiesList list = loader.getPreviewProperties(); // Todo: What if there are more preview images? if (list.size() > 1) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "RW2 image contains more than one preview. None used.\n"; #endif } if (list.size() != 1) return; ExifData exifData; PreviewImage preview = loader.getPreviewImage(*list.begin()); Image::AutoPtr image = ImageFactory::open(preview.pData(), preview.size()); if (image.get() == 0) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to open RW2 preview image.\n"; #endif return; } image->readMetadata(); ExifData& prevData = image->exifData(); if (!prevData.empty()) { // Filter duplicate tags for (ExifData::const_iterator pos = exifData_.begin(); pos != exifData_.end(); ++pos) { if (pos->ifdId() == panaRawId) continue; ExifData::iterator dup = prevData.findKey(ExifKey(pos->key())); if (dup != prevData.end()) { #ifdef DEBUG std::cerr << "Filtering duplicate tag " << pos->key() << " (values '" << pos->value() << "' and '" << dup->value() << "')\n"; #endif prevData.erase(dup); } } } // Remove tags not applicable for raw images static const char* filteredTags[] = { "Exif.Photo.ComponentsConfiguration", "Exif.Photo.CompressedBitsPerPixel", "Exif.Panasonic.ColorEffect", "Exif.Panasonic.Contrast", "Exif.Panasonic.NoiseReduction", "Exif.Panasonic.ColorMode", "Exif.Panasonic.OpticalZoomMode", "Exif.Panasonic.Contrast", "Exif.Panasonic.Saturation", "Exif.Panasonic.Sharpness", "Exif.Panasonic.FilmMode", "Exif.Panasonic.SceneMode", "Exif.Panasonic.WBRedLevel", "Exif.Panasonic.WBGreenLevel", "Exif.Panasonic.WBBlueLevel", "Exif.Photo.ColorSpace", "Exif.Photo.PixelXDimension", "Exif.Photo.PixelYDimension", "Exif.Photo.SceneType", "Exif.Photo.CustomRendered", "Exif.Photo.DigitalZoomRatio", "Exif.Photo.SceneCaptureType", "Exif.Photo.GainControl", "Exif.Photo.Contrast", "Exif.Photo.Saturation", "Exif.Photo.Sharpness", "Exif.Image.PrintImageMatching", "Exif.Image.YCbCrPositioning" }; for (unsigned int i = 0; i < EXV_COUNTOF(filteredTags); ++i) { ExifData::iterator pos = prevData.findKey(ExifKey(filteredTags[i])); if (pos != prevData.end()) { #ifdef DEBUG std::cerr << "Exif tag " << pos->key() << " removed\n"; #endif prevData.erase(pos); } } // Add the remaining tags for (ExifData::const_iterator pos = prevData.begin(); pos != prevData.end(); ++pos) { exifData_.add(*pos); } } // Rw2Image::readMetadata
gboolean exiv2_load_meta_interface(const gchar *service, RAWFILE *rawfile, guint offset, RSMetadata *meta) { try { Image::AutoPtr img = ImageFactory::open((byte*)raw_get_map(rawfile), raw_get_filesize(rawfile)); img->readMetadata(); ExifData &exifData = img->exifData(); #if EXIV2_TEST_VERSION(0,17,0) /* We perfer XMP data, so copy it to EXIF */ XmpData &xmpData = img->xmpData(); if (!xmpData.empty()) copyXmpToExif(xmpData, exifData); #endif /* Parse Exif Data */ if (!exifData.empty()) { ExifData::const_iterator i; i = exifData.findKey(ExifKey("Exif.Image.Make")); if (i != exifData.end()) set_metadata_maker(i->toString(), meta); i = exifData.findKey(ExifKey("Exif.Image.Model")); if (i != exifData.end()) meta->model_ascii = g_strdup(i->toString().c_str()); #if EXIV2_TEST_VERSION(0,19,0) i = orientation(exifData); if (i != exifData.end()) { std::auto_ptr<Exiv2::Value> val = i->getValue(); if (val->count()) { switch (val->toLong()) { case 6: meta->orientation = 90; break; case 8: meta->orientation = 270; break; } } } #endif i = exifData.findKey(ExifKey("Exif.Image.DateTimeOriginal")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Image.DateTime")); if (i != exifData.end()) { meta->time_ascii = g_strdup(i->toString().c_str()); meta->timestamp = rs_exiftime_to_unixtime(meta->time_ascii); } i = exifData.findKey(ExifKey("Exif.Image.ExposureTime")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Photo.ExposureTime")); if (i != exifData.end()) meta->shutterspeed = 1.0 / i->getValue()->toFloat(); else { i = exifData.findKey(ExifKey("Exif.Image.ShutterSpeedValue")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Photo.ShutterSpeedValue")); if (i != exifData.end()) meta->shutterspeed = 1.0 / i->toFloat(); } i = exifData.findKey(ExifKey("Exif.Image.FNumber")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Photo.FNumber")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Image.ApertureValue")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Photo.ApertureValue")); if (i != exifData.end()) meta->aperture = i->toFloat(); i = exifData.findKey(ExifKey("Exif.Image.FocalLength")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.Photo.FocalLength")); if (i != exifData.end()) meta->focallength = i->toFloat()-0.01; #if EXIV2_TEST_VERSION(0,19,0) i = isoSpeed(exifData); if (i != exifData.end()) meta->iso = i->toLong(); /* Text based Lens Identifier */ i = lensName(exifData); if (i != exifData.end()) { TypeId type = i->typeId(); if (type == unsignedShort || type == unsignedLong || type == signedShort || type == signedLong || type == unsignedByte || type == signedByte) meta->lens_id = i->toLong(); else if (type == asciiString || type == string) meta->fixed_lens_identifier = g_strdup(i->toString().c_str()); } #endif /* Canon*/ i = exifData.findKey(ExifKey("Exif.CanonCs.Lens")); if (i != exifData.end() && i->value().count() >= 3 && i->value().typeId() == unsignedShort) { float fu = i->value().toFloat(2); if (fu != 0.0) { meta->lens_min_focal = i->toFloat(0) / fu; meta->lens_max_focal = i->toFloat(1) /fu; } } i = exifData.findKey(ExifKey("Exif.CanonCs.MinAperture")); if (i != exifData.end()) meta->lens_min_aperture = (gfloat) exp(CanonEv(i->toFloat())*log(2)/2); i = exifData.findKey(ExifKey("Exif.CanonCs.MaxAperture")); if (i != exifData.end()) meta->lens_max_aperture = (gfloat) exp(CanonEv(i->toFloat())*log(2)/2); /* Olympus */ i = exifData.findKey(ExifKey("Exif.OlympusEq.MinFocalLength")); if (i != exifData.end()) meta->lens_min_focal = i->toFloat(); i = exifData.findKey(ExifKey("Exif.OlympusEq.MaxFocalLength")); if (i != exifData.end()) meta->lens_max_focal = i->toFloat(); /* Nikon */ i = exifData.findKey(ExifKey("Exif.NikonLd1.MinFocalLength")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd2.MinFocalLength")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd3.MinFocalLength")); if (i != exifData.end()) meta->lens_min_focal = 5.0 * pow(2.0, i->toLong()/24.0); i = exifData.findKey(ExifKey("Exif.NikonLd1.MaxFocalLength")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd2.MaxFocalLength")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd3.MaxFocalLength")); if (i != exifData.end()) meta->lens_max_focal = 5.0 * pow(2.0, i->toLong()/24.0); i = exifData.findKey(ExifKey("Exif.NikonLd1.MaxApertureAtMinFocal")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd2.MaxApertureAtMinFocal")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd3.MaxApertureAtMinFocal")); if (i != exifData.end()) meta->lens_min_aperture = i->toLong()/12.0; i = exifData.findKey(ExifKey("Exif.NikonLd1.MaxApertureAtMaxFocal")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd2.MaxApertureAtMaxFocal")); if (i == exifData.end()) i = exifData.findKey(ExifKey("Exif.NikonLd3.MaxApertureAtMaxFocal")); if (i != exifData.end()) meta->lens_max_aperture = i->toLong()/12.0; /* Fuji */ i = exifData.findKey(ExifKey("Exif.Fujifilm.MinFocalLength")); if (i != exifData.end()) meta->lens_min_focal = i->toFloat(); i = exifData.findKey(ExifKey("Exif.Fujifilm.MaxFocalLength")); if (i != exifData.end()) meta->lens_max_focal = i->toFloat(); return TRUE; } } catch (Exiv2::Error& e) { g_debug("Exiv2 Metadata Loader:'%s'", e.what()); } return FALSE; }