Blame samples/toexv.cpp

Packit 01d647
// ***************************************************************** -*- C++ -*-
Packit 01d647
/*
Packit 01d647
 * Copyright (C) 2004-2017 Andreas Huggel <ahuggel@gmx.net>
Packit 01d647
 *
Packit 01d647
 * This program is part of the Exiv2 distribution.
Packit 01d647
 *
Packit 01d647
 * This program is free software; you can redistribute it and/or
Packit 01d647
 * modify it under the terms of the GNU General Public License
Packit 01d647
 * as published by the Free Software Foundation; either version 2
Packit 01d647
 * of the License, or (at your option) any later version.
Packit 01d647
 *
Packit 01d647
 * This program is distributed in the hope that it will be useful,
Packit 01d647
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 01d647
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 01d647
 * GNU General Public License for more details.
Packit 01d647
 *
Packit 01d647
 * You should have received a copy of the GNU General Public License
Packit 01d647
 * along with this program; if not, write to the Free Software
Packit 01d647
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
Packit 01d647
 */
Packit 01d647
/*
Packit 01d647
  Abstract : Test application to extract metadata from image to exv file
Packit 01d647
 */
Packit 01d647
// *****************************************************************************
Packit 01d647
// included header files
Packit 01d647
#include <exiv2/exiv2.hpp>
Packit 01d647
Packit 01d647
#include <iostream>
Packit 01d647
#include <fstream>
Packit 01d647
#include <cassert>
Packit 01d647
Packit 01d647
#include "utils.hpp"
Packit 01d647
#include "toexv.hpp"
Packit 01d647
Packit 01d647
static size_t exifMetadataCount(Exiv2::Image::AutoPtr& image)
Packit 01d647
{
Packit 01d647
	size_t result = 0 ;
Packit 01d647
	Exiv2::ExifData&                  exif = image->exifData();
Packit 01d647
	Exiv2::ExifData::const_iterator    end = exif.end();
Packit 01d647
	for (Exiv2::ExifData::const_iterator i = exif.begin(); i != end; ++i) result++;
Packit 01d647
	return result;
Packit 01d647
}
Packit 01d647
Packit 01d647
// *****************************************************************************
Packit 01d647
// Main
Packit 01d647
int main(int argc, char* const argv[])
Packit 01d647
{
Packit 01d647
	try {
Packit 01d647
		// Handle command line arguments
Packit 01d647
		Params params(":iecCahsx");
Packit 01d647
		if (params.getopt(argc, argv)) return params.usage();
Packit 01d647
		if (params.help_             ) return params.help();
Packit 01d647
Packit 01d647
		Exiv2::Image::AutoPtr readImage = Exiv2::ImageFactory::open(params.read_);
Packit 01d647
		assert(readImage.get() != 0);
Packit 01d647
		readImage->readMetadata();
Packit 01d647
Packit 01d647
		if ( params.write_ == "+" ) {
Packit 01d647
			std::cout << "exifMetadataCount = " << exifMetadataCount(readImage) << std::endl;
Packit 01d647
Packit 01d647
			// create an in-memory file and write the metadata
Packit 01d647
			Exiv2::BasicIo::AutoPtr memIo   (new Exiv2::MemIo());
Packit 01d647
			Exiv2::Image::AutoPtr   memImage(new Exiv2::ExvImage(memIo,true));
Packit 01d647
			memImage->setMetadata  (*readImage);
Packit 01d647
			memImage->writeMetadata();
Packit 01d647
Packit 01d647
            // serialize the in-memory file into buff
Packit 01d647
            size_t       size = memImage->io().size();
Packit 01d647
			Exiv2::byte  buff[size];
Packit 01d647
			memImage->io().seek(0,Exiv2::BasicIo::beg);
Packit 01d647
			memImage->io().read(buff,size);
Packit 01d647
Packit 01d647
			std::cout << "size = " << size << std::endl;
Packit 01d647
Packit 01d647
			// create an in-memory file with buff and read the metadata into buffImage
Packit 01d647
			Exiv2::BasicIo::AutoPtr buffIo   (new Exiv2::MemIo(buff,size));
Packit 01d647
			Exiv2::Image::AutoPtr   buffImage(new Exiv2::ExvImage(buffIo,false));
Packit 01d647
			assert(buffImage.get() != 0);
Packit 01d647
			buffImage->readMetadata();
Packit 01d647
Packit 01d647
			std::cout << "exifMetadataCount = " << exifMetadataCount(buffImage) << std::endl;
Packit 01d647
Packit 01d647
		} else if ( params.write_ != "-" ) {
Packit 01d647
			// create a file and write the metadata
Packit 01d647
			Exiv2::Image::AutoPtr writeImage = Exiv2::ImageFactory::create(Exiv2::ImageType::exv,params.write_);
Packit 01d647
			params.copyMetadata(readImage,writeImage);
Packit 01d647
		} else {
Packit 01d647
			// create an in-memory file
Packit 01d647
			Exiv2::BasicIo::AutoPtr memIo   (new Exiv2::MemIo());
Packit 01d647
			Exiv2::Image::AutoPtr   memImage(new Exiv2::ExvImage(memIo,true));
Packit 01d647
			params.copyMetadata(readImage,memImage);
Packit 01d647
Packit 01d647
			// read a few bytes from the in-memory file
Packit 01d647
            size_t       size = memImage->io().size();
Packit 01d647
            if (size>32) size = 32;
Packit 01d647
			Exiv2::byte  data[size];
Packit 01d647
Packit 01d647
			memImage->io().seek(0,Exiv2::BasicIo::beg);
Packit 01d647
			memImage->io().read(data,size);
Packit 01d647
Packit 01d647
			// dump the bytes
Packit 01d647
			for ( size_t i = 0 ; i < size ; i++ ) {
Packit 01d647
				char c = (char) data[i] ;
Packit 01d647
				if ( !isascii(c) ) c = '.' ;
Packit 01d647
				std::cout << c ;
Packit 01d647
			}
Packit 01d647
			std::cout << std::endl;
Packit 01d647
		}
Packit 01d647
Packit 01d647
		return 0;
Packit 01d647
Packit 01d647
	} catch (Exiv2::AnyError& e) {
Packit 01d647
		std::cerr << "Caught Exiv2 exception '" << e << "'\n";
Packit 01d647
		return 3;
Packit 01d647
	}
Packit 01d647
}
Packit 01d647
Packit 01d647
Params::Params( const char* opts)
Packit 01d647
: optstring_(opts)
Packit 01d647
, first_(true)
Packit 01d647
, help_(false)
Packit 01d647
, iptc_(false)
Packit 01d647
, exif_(false)
Packit 01d647
, ICC_(false)
Packit 01d647
, all_(false)
Packit 01d647
, comment_(false)
Packit 01d647
, xmp_(false)
Packit 01d647
, size_(false)
Packit 01d647
, usage_(false)
Packit 01d647
{}
Packit 01d647
Packit 01d647
void Params::copyMetadata(Exiv2::Image::AutoPtr& readImage,Exiv2::Image::AutoPtr& writeImage)
Packit 01d647
{
Packit 01d647
	if (all_    ) writeImage->setMetadata  (*readImage);
Packit 01d647
	if (iptc_   ) writeImage->setIptcData  ( readImage->iptcData());
Packit 01d647
	if (exif_   ) writeImage->setExifData  ( readImage->exifData());
Packit 01d647
	if (ICC_    ) writeImage->setIccProfile(*readImage->iccProfile());
Packit 01d647
	if (comment_) writeImage->setComment   ( readImage->comment());
Packit 01d647
	if (xmp_    ) writeImage->setXmpData   ( readImage->xmpData());
Packit 01d647
Packit 01d647
	writeImage->writeMetadata();
Packit 01d647
	if ( size_ ) std::cout << write_ << " " << writeImage->io().size() << std::endl;
Packit 01d647
}
Packit 01d647
Packit 01d647
int Params::option(int opt, const std::string& /*optarg*/, int optopt)
Packit 01d647
{
Packit 01d647
    int rc = 0;
Packit 01d647
    switch (opt) {
Packit 01d647
    case 'h': help_     = true ; break;
Packit 01d647
    case 'i': iptc_     = true ; break;
Packit 01d647
    case 'e': exif_     = true ; break;
Packit 01d647
    case 'c': comment_  = true ; break;
Packit 01d647
    case 'C': ICC_      = true ; break;
Packit 01d647
    case 'x': xmp_      = true ; break;
Packit 01d647
    case 'a': all_      = true ; break;
Packit 01d647
    case 's': size_     = true ; break;
Packit 01d647
    case 'p': /* ignore for backwards compatibility */ ; break;
Packit 01d647
    case ':':
Packit 01d647
        std::cerr << progname() << ": Option -" << static_cast<char>(optopt)
Packit 01d647
                  << " requires an argument\n";
Packit 01d647
        rc = 1;
Packit 01d647
        break;
Packit 01d647
    case '?':
Packit 01d647
        std::cerr << progname() << ": Unrecognized option -"
Packit 01d647
                  << static_cast<char>(optopt) << "\n";
Packit 01d647
        rc = 1;
Packit 01d647
        break;
Packit 01d647
    default:
Packit 01d647
        std::cerr << progname()
Packit 01d647
                  << ": getopt returned unexpected character code " << (char) opt
Packit 01d647
                  << " 0x" << std::hex << opt << "\n";
Packit 01d647
        rc = 1;
Packit 01d647
        break;
Packit 01d647
    }
Packit 01d647
Packit 01d647
    return rc;
Packit 01d647
}
Packit 01d647
Packit 01d647
int Params::nonoption(const std::string& argv)
Packit 01d647
{
Packit 01d647
    if (!write_.empty()) {
Packit 01d647
        std::cerr << progname() << ": Unexpected extra argument (" << argv << ")\n";
Packit 01d647
        return 1;
Packit 01d647
    }
Packit 01d647
    if (first_) read_ = argv;
Packit 01d647
    else        write_ = argv;
Packit 01d647
    first_ = false;
Packit 01d647
    return 0;
Packit 01d647
}
Packit 01d647
Packit 01d647
int Params::getopt(int argc, char* const argv[])
Packit 01d647
{
Packit 01d647
    int rc = Util::Getopt::getopt(argc, argv, optstring_);
Packit 01d647
    if ( argc == 1 ) usage_ = true;
Packit 01d647
    // Further consistency checks
Packit 01d647
    if ( !help_ && !usage_ ) {
Packit 01d647
        if (rc==0 && read_.empty() ) {
Packit 01d647
            std::cerr << progname() << ": Read and write files must be specified\n";
Packit 01d647
            rc = 1;
Packit 01d647
        }
Packit 01d647
        if (rc==0 && write_.empty() ) {
Packit 01d647
            std::cerr << progname() << ": Write file must be specified\n";
Packit 01d647
            rc = 1;
Packit 01d647
        }
Packit 01d647
    }
Packit 01d647
    if ( argc == 3 ) { all_ = true; size_ = true; }
Packit 01d647
    if ( usage_ ) return 2 ;
Packit 01d647
    return rc;
Packit 01d647
}
Packit 01d647
Packit 01d647
int Params::usage(std::ostream& os) const
Packit 01d647
{
Packit 01d647
    os << "Reads and writes raw metadata. Use -h option for help.\n"
Packit 01d647
       << "Usage: " << progname()
Packit 01d647
       << " [-" << optstring_ << "]"
Packit 01d647
       << " readfile {-|+|writefile}\n";
Packit 01d647
    return 2;
Packit 01d647
}
Packit 01d647
Packit 01d647
int Params::help(std::ostream& os) const
Packit 01d647
{
Packit 01d647
    usage(os);
Packit 01d647
    os << "\nOptions:\n"
Packit 01d647
          "   -i      Read Iptc data from readfile and write to writefile.\n"
Packit 01d647
          "   -e      Read Exif data from readfile and write to writefile.\n"
Packit 01d647
          "   -c      Read Jpeg comment from readfile and write to writefile.\n"
Packit 01d647
          "   -C      Read ICC profile from readfile and write to writefile.\n"
Packit 01d647
          "   -x      Read XMP data from readfile and write to writefile.\n"
Packit 01d647
          "   -a      Read all metadata from readfile and write to writefile.\n"
Packit 01d647
          "   -s      Print size of writefile.\n"
Packit 01d647
          "   -h      Display this help and exit.\n";
Packit 01d647
    return 1;
Packit 01d647
}