Example #1
0
void ExifTools::copyExif(const QString &sourceStr, const QString &destStr)
{
        Exiv2::Image::AutoPtr sourceImageData =
                Exiv2::ImageFactory::open(QFile::encodeName(sourceStr).data());
        sourceImageData->readMetadata();

        Exiv2::ExifData exifData = sourceImageData->exifData();
        Exiv2::IptcData iptcData = sourceImageData->iptcData();

        Exiv2::ExifThumb exifThumb(exifData);
        exifThumb.erase();

        Exiv2::Image::AutoPtr destImageData =
                Exiv2::ImageFactory::open(QFile::encodeName(destStr).data());
        destImageData->setExifData(exifData);
        destImageData->setIptcData(iptcData);
        destImageData->writeMetadata();
}
Example #2
0
static gfloat
expcombine_get_file_ev (const gchar *path)
{
  /* Open the file and read in the metadata */
  Exiv2::Image::AutoPtr image;
  try 
    {
      image = Exiv2::ImageFactory::open (path);
      image->readMetadata ();
    }
  catch (Exiv2::Error ex)
    {
      g_print ("Error: unable to read metadata from path: '%s'\n", path);
      exit (EXIT_FAILURE);
    }

  Exiv2::ExifData &exifData = image->exifData ();
  if (exifData.empty ())
      return NAN;

  /* Calculate the APEX brightness / EV */
  gfloat time, aperture, gain = 1.0f;

  time     = exifData["Exif.Photo.ExposureTime"].value().toFloat();
  aperture = exifData["Exif.Photo.FNumber"     ].value().toFloat();

  /* iso */
  try
    {
      gain = exifData["Exif.Photo.ISOSpeedRatings"].value().toLong() / 100.0f;
    }
  catch (Exiv2::Error ex)
    {
      // Assume ISO is set at 100. It's reasonably likely that the ISO is the
      // same across all images anyway, and for our purposes the relative
      // values can be sufficient.

      gain = 1.0f;
    }

  return log2f (aperture * aperture) + log2f (1 / time) + log2f (gain);
}
// tries to find a specified exif tag in a specified file
QString ExifScout::getExifData(QString fname, QString etag){
    std::string filename = fname.toAscii().data();
    std::string exiftag = etag.toAscii().data();

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filename);
    assert(image.get() != 0);
    image->readMetadata();
    Exiv2::ExifData exifData = image->exifData();
    if (!exifData.empty()) {
        Exiv2::ExifData::const_iterator end = exifData.end();
        QString output;
        for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
            if(i->tagName()==exiftag){
                std::ostringstream oss;
                oss << i->value();
                return (QString)oss.str().c_str();
            }
        }
    }
    return NULL;
}
Example #4
0
    bool Exiv2ReadingWorker::readMetadata(Models::ArtworkMetadata *artwork, ImportDataResult &importResult) {
        const QString &filepath = artwork->getFilepath();

#if defined(Q_OS_WIN)
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath.toStdWString());
#else
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath.toStdString());
#endif
        Q_ASSERT(image.get() != NULL);
        image->readMetadata();

        Exiv2::XmpData &xmpData = image->xmpData();
        Exiv2::ExifData &exifData = image->exifData();
        Exiv2::IptcData &iptcData = image->iptcData();

        QString iptcEncoding = getIptcCharset(iptcData).toUpper();
        bool isIptcUtf8 = (iptcEncoding == QLatin1String("UTF-8")) || (iptcEncoding == QLatin1String("UTF8"));

        importResult.FilePath = filepath;
        importResult.Description = retrieveDescription(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.Title = retrieveTitle(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.Keywords = retrieveKeywords(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.DateTimeOriginal = retrieveDateTime(xmpData, exifData, iptcData, isIptcUtf8);

        MetadataSavingCopy copy;
        if (copy.readFromFile(filepath)) {
            importResult.BackupDict = copy.getInfo();
        }

        QFileInfo fi(filepath);
        importResult.FileSize = fi.size();

        Models::ImageArtwork *imageArtwork = dynamic_cast<Models::ImageArtwork*>(artwork);
        if (imageArtwork != NULL) {
            QImageReader reader(filepath);
            importResult.ImageSize = reader.size();
        }

        return true;
    }
Example #5
0
void ImageResolution::readexiv(char const *fn) {
  Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(fn);
  if (!image.get())
    return;

  image->readMetadata();
  Exiv2::ExifData &exifData = image->exifData();
  if (exifData.empty())
    return;

  Exiv2::ExifData::const_iterator end = exifData.end();
  bool havex = false;
  bool havey = false;
  bool haveunit = false;
  int unit;
  for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
    if (ok_)
      break;
    if (i->tag()==0x011a) {
      // X Resolution
      x_ = i->toFloat();
      havex = true;
    } else if (i->tag()==0x011b) {
      // Y Resolution
      y_ = i->toFloat();
      havey = true;
    } else if (i->tag()==0x0128) {
      unit = i->toLong();
    }
    ok_ = havex && havey && haveunit;
  }
  if (haveunit) {
    if (unit==3) {
      x_ *= 2.54;
      y_ *= 2.54;
    }
  }
  ok_ = havex && havey;
}
Example #6
0
int main(int argc, char* const argv[])
try {

    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
    if (image.get() == 0) {
        std::string error(argv[1]);
        error += " : Could not read file or unknown image type";
        throw Exiv2::Error(error);
    }

    // Load existing metadata
    int rc = image->readMetadata();
    if (rc) {
        std::string error = Exiv2::Image::strError(rc, argv[1]);
        throw Exiv2::Error(error);
    }

    Exiv2::ExifData &exifData = image->exifData();
    Exiv2::ExifData::const_iterator end = exifData.end();
    for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
        std::cout << std::setw(53) << std::setfill(' ') << std::left
                  << i->key() << " "
                  << "0x" << std::setw(4) << std::setfill('0') << std::right
                  << std::hex << i->tag() << "  " 
                  << std::dec << i->value() 
                  << "\n";
    }

    return rc;
}
catch (Exiv2::Error& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
Example #7
0
int main(int argc, char ** argv) {
    logging::core::get()->set_filter
    (
       logging::trivial::severity >= logging::trivial::info
    );
    if(argc <= 4) {
        BOOST_LOG_TRIVIAL(info) << "Invalid arguments for test";
        return 2;
    }
    string description = argv[1];
    Mat input = imread(argv[2], cv::IMREAD_COLOR);
    BOOST_LOG_TRIVIAL(info) << "Reading " << argv[2] << " of size " << input.rows << "x" << input.cols;
    vector<Point> * contour = new vector<Point>();
    for(int i = 3; i + 1 < argc; i++){
        stringstream ss;
        int x, y;
        ss << argv[i] << " " << argv[i+1];
        ss >> x >> y;
        contour->push_back(Point(x,y));
    }
    

    /************************************************ERIC's SHIT*/	
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[2]);
    image->readMetadata();
    Exiv2::ExifData &exifData = image->exifData();
  
    exifData["Exif.Photo.UserComment"] = "50,-90,90,180,1:23:45";
    image->writeMetadata();
    std::cout << "wrote it";

    /****************************************************/
   
    BOOST_LOG_TRIVIAL(info) << "Read Contour: " << contour; // TODO: figure out why defining operator<< doesn't affect boost logs
    Frame f(&input, "blah", Metadata());
    TargetTest test("Target Identification using KMeans + Canny");
    double result = test.do_test(f, description, contour, 10);
    return !(result < 10 && result > -10); // arbitrary bounds for success of test (false indicates success)
}
Exiv2::ExifData getExifFromPath(char* filename) {
    qDebug() << "Trying to read EXIF for" << filename;
    try {
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filename);
        assert(image.get() != 0);
        image->readMetadata();

        Exiv2::ExifData &exifData = image->exifData();
        if (exifData.empty()) {
            std::string error(filename);
            error += ": No Exif data found in the file";
        }
        return exifData;
    } catch (Exiv2::Error& e) {
        Exiv2::ExifData exifData;
        qCritical() << "Caught Exiv2 exception '" << e.what();
        //TODO Translate
        return exifData;
    }


}
Example #9
0
void print(const std::string& file)
{
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
    assert (image.get() != 0);
    image->readMetadata();

    Exiv2::ExifData &ed = image->exifData();
    Exiv2::ExifData::const_iterator end = ed.end();
    for (Exiv2::ExifData::const_iterator i = ed.begin(); i != end; ++i) {
        std::cout << std::setw(45) << std::setfill(' ') << std::left
                  << i->key() << " "
                  << "0x" << std::setw(4) << std::setfill('0') << std::right
                  << std::hex << i->tag() << " "
                  << std::setw(12) << std::setfill(' ') << std::left
                  << i->ifdName() << " "
                  << std::setw(9) << std::setfill(' ') << std::left
                  << i->typeName() << " "
                  << std::dec << std::setw(3)
                  << std::setfill(' ') << std::right
                  << i->count() << " "
                  << std::dec << i->value()
                  << "\n";
    }
}
Example #10
0
void ExifReaderWriter::readExif(QString pictureName)
{
    Exiv2::Image::AutoPtr image = openExif(pictureName);
    if(image.get() == 0)
        return;
    Exiv2::ExifData &exifData = image->exifData();
    if (exifData.empty()) {
        //qDebug() << "nejsou exif data";
        emit(finished());
        return;
    }

    //cteniGPS souradnic
    double lat = readLatLon("Exif.GPSInfo.GPSLatitude", exifData);
    double lon = readLatLon("Exif.GPSInfo.GPSLongitude", exifData);
    double alt = readAltitude("Exif.GPSInfo.GPSAltitude", exifData);

    if(lat < 1000 && lon<1000)
    {
        emit(setGps(lat, lon, alt));
    }

    ////////////////////////////

    QDateTime *dateTime = NULL;
    //cteni data
    if((dateTime = readExifDate(exifData,"Exif.Photo.DateTimeOriginal")) == NULL)
        if((dateTime = readExifDate(exifData,"Exif.Image.DateTimeOriginal")) == NULL)
            if((dateTime = readExifDate(exifData,"Exif.Photo.DateTimeDigitized")) == NULL)
                dateTime = readExifDate(exifData,"Exif.Image.DateTime");

    if(dateTime != NULL)
        emit(setDateTime(*dateTime));
    emit(finished());
    return;
}
Example #11
0
void geotag_worker(wc_work_queue &wq, std::vector<GPXPoint> &gpxData) {
    std::string fname;
    // Grab a file from the work queue
    while ((fname = wq.getFile()) != "") {
        try {
            Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(fname.c_str());
            if (image.get() == 0) continue;
            image->readMetadata();

            Exiv2::ExifData &exifData = image->exifData();
            if (exifData.empty()) {
                std::string error = fname;
                error += ": No Exif data found in the file";
                throw Exiv2::Error(1, error);
            }
            std::string tmpTime = exifData["Exif.Photo.DateTimeOriginal"].toString();
            auto tstamp = getImageTimeStamp(tmpTime);

            size_t idx = 0;
            bool foundIt = findClosest(gpxData, tstamp, idx);

            if (!foundIt) {
                std::cout << fname << " is not on the GPX track!\n";
                continue;
            } else {
                std::cout << fname << " was at ("  << std::setprecision(10) << gpxData[idx].lat << ", " << std::setprecision(10) << gpxData[idx].lon << ")\n";
            }
            clearGPSFields(exifData);

            exifData["Exif.GPSInfo.GPSMapDatum"] = "WGS-84";

            exifData["Exif.GPSInfo.GPSAltitude"] = Exiv2::Rational(gpxData[idx].ele * 1000, 1000);
            exifData["Exif.GPSInfo.GPSAltitudeRef"] = Exiv2::byte(0);

            // Convert the latitude to DDD*MM'SS.SSS" and set
            int dd, mm;
            double ss;
            convertToDDMMSS(gpxData[idx].lat, dd, mm, ss);
            if (gpxData[idx].lat<0) {
                exifData["Exif.GPSInfo.GPSLatitudeRef"] = "S";
            } else {
                exifData["Exif.GPSInfo.GPSLatitudeRef"] = "N";
            }

            Exiv2::URationalValue::AutoPtr latitude(new Exiv2::URationalValue);
            latitude->value_.push_back(std::make_pair(dd,1));
            latitude->value_.push_back(std::make_pair(mm,1));
            latitude->value_.push_back(std::make_pair(std::trunc(ss*10000)-1,10000));
            auto latKey = Exiv2::ExifKey("Exif.GPSInfo.GPSLatitude");
            exifData.add(latKey, latitude.get());

            convertToDDMMSS(gpxData[idx].lon, dd, mm, ss);
            Exiv2::URationalValue::AutoPtr longitude(new Exiv2::URationalValue);
            if (gpxData[idx].lon<0) {
                exifData["Exif.GPSInfo.GPSLongitudeRef"] = "W";
            } else {
                exifData["Exif.GPSInfo.GPSLongitudeRef"] = "E";
            }
            longitude->value_.push_back(std::make_pair(dd,1));
            longitude->value_.push_back(std::make_pair(mm,1));
            longitude->value_.push_back(std::make_pair(int(ss*10000)-1,10000));
            auto longKey = Exiv2::ExifKey("Exif.GPSInfo.GPSLongitude");
            exifData.add(longKey, longitude.get());


            Exiv2::URationalValue::AutoPtr timestamp(new Exiv2::URationalValue);
            timestamp->value_.push_back(std::make_pair(gpxData[idx].hour,1));
            timestamp->value_.push_back(std::make_pair(gpxData[idx].minute,1));
            timestamp->value_.push_back(std::make_pair(gpxData[idx].second,1));

            auto timeKey = Exiv2::ExifKey("Exif.GPSInfo.GPSTimeStamp");
            exifData.add(timeKey, timestamp.get());
            
            exifData["Exif.GPSInfo.GPSDateStamp"] = gpxData[idx].dateStamp.c_str();

            image->setExifData(exifData);
            image->writeMetadata();
        }
        catch (Exiv2::AnyError& e) {
            std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
            continue;
        }
    }
}
Example #12
0
int WriteFixedDatestamp(const char* File, time_t Time)
{
	// Write the GPS data to the file...

	struct stat statbuf;
	struct stat statbuf2;
	struct utimbuf utb;
	stat(File, &statbuf);

	Exiv2::Image::AutoPtr Image;

	try {
		Image = Exiv2::ImageFactory::open(File);
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to open file %s.\n", File);
		return 0;
	}
	Image->readMetadata();
	if (Image.get() == NULL)
	{
		// It failed if we got here.
		DEBUGLOG("Failed to read file %s %s.\n",
			 File, Exiv2::strError().c_str());
		return 0;
	}
	
	Exiv2::ExifData &ExifToWrite = Image->exifData();
	
	const struct tm TimeStamp = *gmtime(&Time);
	char ScratchBuf[100];

	snprintf(ScratchBuf, sizeof(ScratchBuf), "%04d:%02d:%02d",
			TimeStamp.tm_year + 1900,
			TimeStamp.tm_mon + 1,
			TimeStamp.tm_mday);
	ExifToWrite.erase(ExifToWrite.findKey(Exiv2::ExifKey("Exif.GPSInfo.GPSDateStamp")));
	ExifToWrite["Exif.GPSInfo.GPSDateStamp"] = ScratchBuf;

	Exiv2::Value::AutoPtr Value = Exiv2::Value::create(Exiv2::unsignedRational);
	snprintf(ScratchBuf, sizeof(ScratchBuf), "%d/1 %d/1 %d/1",
			TimeStamp.tm_hour, TimeStamp.tm_min,
			TimeStamp.tm_sec);
	Value->read(ScratchBuf);
	ExifToWrite.erase(ExifToWrite.findKey(Exiv2::ExifKey("Exif.GPSInfo.GPSTimeStamp")));
	ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSTimeStamp"), Value.get());
	
	try {
		Image->writeMetadata();
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to write to file %s.\n", File);
		return 0;
	}
	
	// Reset the mtime.
	stat(File, &statbuf2);
	utb.actime = statbuf2.st_atime;
	utb.modtime = statbuf.st_mtime;
	utime(File, &utb);

	return 1;
}
Example #13
0
int WriteGPSData(const char* File, const struct GPSPoint* Point,
		 const char* Datum, int NoChangeMtime, int DegMinSecs)
{
	// Write the GPS data to the file...

	struct stat statbuf;
	struct stat statbuf2;
	struct utimbuf utb;
	if (NoChangeMtime)
		stat(File, &statbuf);
	Exiv2::Image::AutoPtr Image;

	try {
		Image = Exiv2::ImageFactory::open(File);
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to open file %s.\n", File);
		return 0;
	}
	Image->readMetadata();
	if (Image.get() == NULL)
	{
		// It failed if we got here.
		DEBUGLOG("Failed to read file %s %s.\n",
			 File, Exiv2::strError().c_str());
		return 0;
	}
	
	Exiv2::ExifData &ExifToWrite = Image->exifData();

	// Make sure we're starting from a clean GPS IFD.
	// There might be lots of GPS tags existing here, since only the
	// presence of the GPSLatitude tag causes correlation to stop with
	// "GPS Already Present" error.
	EraseGpsTags(ExifToWrite);

	char ScratchBuf[100];

	// Do all the easy constant ones first.
	// GPSVersionID tag: standard says it should be four bytes: 02 02 00 00
	//  (and, must be present).
	Exiv2::Value::AutoPtr Value = Exiv2::Value::create(Exiv2::unsignedByte);
	Value->read("2 2 0 0");
	ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSVersionID"), Value.get());
	// Datum: the datum of the measured data. The default is WGS-84.
	if (*Datum)
		ExifToWrite["Exif.GPSInfo.GPSMapDatum"] = Datum;
	
	// Now start adding data.
	// ALTITUDE.
	// If no altitude was found in the GPX file, ElevDecimals will be -1
	if (Point->ElevDecimals >= 0) {
		// Altitude reference: byte "00" meaning "sea level".
		// Or "01" if the altitude value is negative.
		Value = Exiv2::Value::create(Exiv2::unsignedByte);
		if (Point->Elev >= 0)
		{
			Value->read("0");
		} else {
			Value->read("1");
		}
		ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitudeRef"), Value.get());
		// And the actual altitude.
		Value = Exiv2::Value::create(Exiv2::unsignedRational);
		// 3 decimal points is beyond the limit of current GPS technology
		int Decimals = MIN(Point->ElevDecimals, 3);
		ConvertToRational(fabs(Point->Elev), Decimals, ScratchBuf, sizeof(ScratchBuf));

		/* printf("Altitude: %f -> %s\n", Point->Elev, ScratchBuf); */
		Value->read(ScratchBuf);
		ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitude"), Value.get());
	}
	
	// LATITUDE
	// Latitude reference: "N" or "S".
	if (Point->Lat < 0)
	{
		// Less than Zero: ie, minus: means
		// Southern hemisphere. Where I live.
		ExifToWrite["Exif.GPSInfo.GPSLatitudeRef"] = "S";
	} else {
		// More than Zero: ie, plus: means
		// Northern hemisphere.
		ExifToWrite["Exif.GPSInfo.GPSLatitudeRef"] = "N";
	}
	// Now the actual latitude itself.
	// The original comment read:
	// This is done as three rationals.
	// I choose to do it as:
	//   dd/1 - degrees.
	//   mmmm/100 - minutes
	//   0/1 - seconds
	// Exif standard says you can do it with minutes
	// as mm/1 and then seconds as ss/1, but its
	// (slightly) more accurate to do it as
	//  mmmm/100 than to split it.
	// We also absolute the value (with fabs())
	// as the sign is encoded in LatRef.
	// Further note: original code did not translate between
	//   dd.dddddd to dd mm.mm - that's why we now multiply
	//   by 60*N - x60 to get minutes, xN to get to mmmm/N.
	//   N is 10^S where S is the number of significant decimal
	//   places.
	//
	// Rereading the EXIF standard, it's quite ok to do DD MM SS.SS
	// Which is much more accurate. This is the new default, unless otherwise
	// set.
	Value = Exiv2::Value::create(Exiv2::unsignedRational);

	if (DegMinSecs)
	{
		ConvertToLatLongRational(Point->Lat, Point->LatDecimals, ScratchBuf, sizeof(ScratchBuf));
	} else {
		ConvertToOldLatLongRational(Point->Lat, ScratchBuf, sizeof(ScratchBuf));
	}
	Value->read(ScratchBuf);
	ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLatitude"), Value.get());
	
	// LONGITUDE
	// Longitude reference: "E" or "W".
	if (Point->Long < 0)
	{
		// Less than Zero: ie, minus: means
		// Western hemisphere.
		ExifToWrite["Exif.GPSInfo.GPSLongitudeRef"] = "W";
	} else {
		// More than Zero: ie, plus: means
		// Eastern hemisphere. Where I live.
		ExifToWrite["Exif.GPSInfo.GPSLongitudeRef"] = "E";
	}
	// Now the actual longitude itself, in the same way as latitude
	Value = Exiv2::Value::create(Exiv2::unsignedRational);

	if (DegMinSecs)
	{
		ConvertToLatLongRational(Point->Long, Point->LongDecimals, ScratchBuf, sizeof(ScratchBuf));
	} else {
		ConvertToOldLatLongRational(Point->Long, ScratchBuf, sizeof(ScratchBuf));
	}
	Value->read(ScratchBuf);
	ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLongitude"), Value.get());

	// The timestamp.
	// Make up the timestamp...
	// The timestamp is taken as the UTC time of the photo.
	// If interpolation occurred, then this time is the time of the photo.
	struct tm TimeStamp = *gmtime(&(Point->Time));

	Value = Exiv2::Value::create(Exiv2::unsignedRational);
	snprintf(ScratchBuf, sizeof(ScratchBuf), "%d/1 %d/1 %d/1",
			TimeStamp.tm_hour, TimeStamp.tm_min,
			TimeStamp.tm_sec);
	Value->read(ScratchBuf);
	ExifToWrite.add(Exiv2::ExifKey("Exif.GPSInfo.GPSTimeStamp"), Value.get());

	// And we should also do a datestamp.
	snprintf(ScratchBuf, sizeof(ScratchBuf), "%04d:%02d:%02d",
			TimeStamp.tm_year + 1900,
			TimeStamp.tm_mon + 1,
			TimeStamp.tm_mday);
	ExifToWrite["Exif.GPSInfo.GPSDateStamp"] = ScratchBuf;

	// Write the data to file.
	try {
		Image->writeMetadata();
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to write to file %s.\n", File);
		return 0;
	}

	if (NoChangeMtime)
	{
		stat(File, &statbuf2);
		utb.actime = statbuf2.st_atime;
		utb.modtime = statbuf.st_mtime;
		utime(File, &utb);
	}

	return 1;
	
}
Example #14
0
// This function is for the --fix-datestamp option.
// DateStamp and TimeStamp should be 12-char strings.
char* ReadGPSTimestamp(const char* File, char* DateStamp, char* TimeStamp, int* IncludesGPS)
{
	// This function varies in that it reads
	// much more data than the last, specifically
	// for display purposes. For the GUI version.
	// Open and read the file.
	Exiv2::Image::AutoPtr Image;

	try {
		Image = Exiv2::ImageFactory::open(File);
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to open file %s.\n", File);
		return NULL;
	}
	Image->readMetadata();
	if (Image.get() == NULL)
	{
		DEBUGLOG("Failed to read file %s %s.\n",
			 File, Exiv2::strError().c_str());
		return NULL;
	}
	
	Exiv2::ExifData &ExifRead = Image->exifData();

	// Read the tag out.
	Exiv2::Exifdatum& Tag = ExifRead["Exif.Photo.DateTimeOriginal"];

	// Check that the tag is not blank.
	std::string Value = Tag.toString();

	if (Value.length() == 0)
	{
		// No date/time stamp.
		// Not good.
		// Just return - above us will handle it.
		return NULL;
	}

	// Copy the tag and return that.
	char* Copy = strdup(Value.c_str());
	
	// Check if we have GPS tags.
	Exiv2::Exifdatum& GPSData = ExifRead["Exif.GPSInfo.GPSVersionID"];

	Value = GPSData.toString();

	if (Value.length() == 0)
	{
		// No GPS data.
		// Just return.
		*IncludesGPS = 0;
	} else {
		// Seems to include GPS data...
		*IncludesGPS = 1;

		Exiv2::URational RatNum1;
		Exiv2::URational RatNum2;
		Exiv2::URational RatNum3;

		// Read out the Time and Date stamp, for correction.
		GPSData = ExifRead["Exif.GPSInfo.GPSTimeStamp"];
		if (GPSData.count() < 3) {
			*IncludesGPS = 0;
			return Copy;
		}
		RatNum1 = GPSData.toRational(0);
		RatNum2 = GPSData.toRational(1);
		RatNum3 = GPSData.toRational(2);
		snprintf(TimeStamp, 12, "%02d:%02d:%02d",
				RatNum1.first, RatNum2.first, RatNum3.first);
		
		GPSData = ExifRead["Exif.GPSInfo.GPSDateStamp"];
		if (GPSData.count() < 3) {
			*IncludesGPS = 0;
			return Copy;
		}
		if (GPSData.typeId() == Exiv2::signedRational) {
			// bad type written by old gpscorrelate versions
			RatNum1 = GPSData.toRational(0);
			RatNum2 = GPSData.toRational(1);
			RatNum3 = GPSData.toRational(2);
			snprintf(DateStamp, 12, "%04d:%02d:%02d",
				 RatNum1.first, RatNum2.first, RatNum3.first);
		} else
			snprintf(DateStamp, 12, "%s", GPSData.toString().c_str());
	}

	return Copy;
}
Example #15
0
char* ReadExifData(const char* File, double* Lat, double* Long, double* Elev, int* IncludesGPS)
{
	// This function varies in that it reads
	// much more data than the last, specifically
	// for display purposes. For the GUI version.
	// Open and read the file.
	Exiv2::Image::AutoPtr Image;

	try {
		Image = Exiv2::ImageFactory::open(File);
	} catch (Exiv2::Error e) {
		DEBUGLOG("Failed to open file %s.\n", File);
		return NULL;
	}
	Image->readMetadata();
	if (Image.get() == NULL)
	{
		DEBUGLOG("Failed to read file %s %s.\n",
			 File, Exiv2::strError().c_str());
		return NULL;
	}
	
	Exiv2::ExifData &ExifRead = Image->exifData();

	// Read the tag out.
	Exiv2::Exifdatum& Tag = ExifRead["Exif.Photo.DateTimeOriginal"];

	// Check that the tag is not blank.
	std::string Value = Tag.toString();

	if (Value.length() == 0)
	{
		// No date/time stamp.
		// Not good.
		// Just return - above us will handle it.
		return NULL;
	}

	// Copy the tag and return that.
	char* Copy = strdup(Value.c_str());
	
	// Check if we have GPS tags.
	Exiv2::Exifdatum GPSData = ExifRead["Exif.GPSInfo.GPSVersionID"];

	Value = GPSData.toString();

	if (Value.length() == 0)
	{
		// No GPS data.
		// Just return.
		*IncludesGPS = 0;
	} else {
		// Seems to include GPS data...
		*IncludesGPS = 1;
		// Read it out and send it up!
		// What we are trying to do here is convert the
		// three rationals:
		//    dd/v mm/v ss/v
		// To a decimal
		//    dd.dddddd...
		// dd/v is easy: result = dd/v.
		// mm/v is harder:
		//    mm
		//    -- / 60 = result.
		//     v
		// ss/v is sorta easy.
		//     ss   
		//     -- / 3600 = result
		//      v   
		// Each part is added to the final number.
		Exiv2::URational RatNum;

		GPSData = ExifRead["Exif.GPSInfo.GPSLatitude"];
		if (GPSData.count() < 3)
			*Lat = nan("invalid");
		else {
			RatNum = GPSData.toRational(0);
			*Lat = (double)RatNum.first / (double)RatNum.second;
			RatNum = GPSData.toRational(1);
			*Lat = *Lat + (((double)RatNum.first / (double)RatNum.second) / 60);
			RatNum = GPSData.toRational(2);
			*Lat = *Lat + (((double)RatNum.first / (double)RatNum.second) / 3600);

			GPSData = ExifRead["Exif.GPSInfo.GPSLatitudeRef"];
			if (strcmp(GPSData.toString().c_str(), "S") == 0)
			{
				// Negate the value - Western Hemisphere.
				*Lat = -*Lat;
			}
		}
		
		GPSData = ExifRead["Exif.GPSInfo.GPSLongitude"];
		if (GPSData.count() < 3)
			*Long = nan("invalid");
		else {
			RatNum = GPSData.toRational(0);
			*Long = (double)RatNum.first / (double)RatNum.second;
			RatNum = GPSData.toRational(1);
			*Long = *Long + (((double)RatNum.first / (double)RatNum.second) / 60);
			RatNum = GPSData.toRational(2);
			*Long = *Long + (((double)RatNum.first / (double)RatNum.second) / 3600);

			GPSData = ExifRead["Exif.GPSInfo.GPSLongitudeRef"];
			if (strcmp(GPSData.toString().c_str(), "W") == 0)
			{
				// Negate the value - Western Hemisphere.
				*Long = -*Long;
			}
		}

		// Finally, read elevation out. This one is simple.
		GPSData = ExifRead["Exif.GPSInfo.GPSAltitude"];
		if (GPSData.count() < 1)
			*Elev = nan("invalid");
		else {
			RatNum = GPSData.toRational(0);
			*Elev = (double)RatNum.first / (double)RatNum.second;
		}

		// Is the altitude below sea level? If so, negate the value.
		GPSData = ExifRead["Exif.GPSInfo.GPSAltitudeRef"];
		if (GPSData.count() >= 1 && GPSData.toLong() == 1)
		{
			// Negate the elevation.
			*Elev = -*Elev;
		}
	}


	// Now return, passing a pointer to the date string.
	return Copy; // It's up to the caller to free this.
}
void ThreadRemoveExifDatas::run() {
    QTableWidgetItem *item;
 
    Exiv2::ExifData::iterator keyIteratorRemove;
    Exiv2::ExifKey *keyRemove;

    QVector<QString> listErrorRemoveFile;
    QVector<int> listErrorRemoveFilePosition;

    connect(this, SIGNAL(progressBarValue(int)), progressBar, SLOT(setValue(int)));
    connect(this, SIGNAL(progressBarSetVisible(bool)), progressBar, SLOT(setVisible(bool)));
    emit progressBarSetVisible(true);
    progressBar->setRange(0, tableWidgetJpeg->rowCount());

    for (int i = 0; i < tableWidgetJpeg->rowCount(); i++) {
        try {
            emit progressBarValue(i);
            Exiv2::Image::AutoPtr image;

            image = Exiv2::ImageFactory::open(tableWidgetJpeg->item(i, 7)->text().toStdString().c_str());

            if (tableWidgetJpeg->item(i, 3) != 0 || tableWidgetJpeg->item(i, 4) != 0 || tableWidgetJpeg->item(i, 5) != 0) {
                bool exifRemovido = false;
                assert(image.get() != 0);
                image->readMetadata();
                Exiv2::ExifData &exifData = image->exifData();

                Exiv2::ExifKey keyLatitude = Exiv2::ExifKey("Exif.GPSInfo.GPSLatitude");
                keyIteratorRemove = exifData.findKey(keyLatitude);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSTimeStamp");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSDateStamp");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSVersionID");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSMapDatum");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSLatitudeRef");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSLongitude");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSLongitudeRef");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSAltitude");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSAltitudeRef");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSImgDirectionRef");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }
                
                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSImgDirection");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }

                keyRemove = new Exiv2::ExifKey("Exif.GPSInfo.GPSProcessingMethod");
                keyIteratorRemove = exifData.findKey(*keyRemove);
                if (keyIteratorRemove != exifData.end()) {
                    exifData.erase(keyIteratorRemove);
                    exifRemovido = true;
                }                
                
                if (exifRemovido) {
                    QString softwareTag = QApplication::applicationName();
                    softwareTag += " ";
                    softwareTag += QApplication::applicationVersion();
                    exifData["Exif.Image.Software"] = softwareTag.toStdString();
                }
                image->setExifData(exifData);
                image->writeMetadata();
                QString itemStatus = QString::fromUtf8("Dados Removidos");
                item = new QTableWidgetItem();
                item->setText(itemStatus);
                delete tableWidgetJpeg->takeItem(i, 3);
                delete tableWidgetJpeg->takeItem(i, 4);
                delete tableWidgetJpeg->takeItem(i, 5);
                tableWidgetJpeg->setItem(i, 6, item);
            } else {
                QString itemStatus = QString::fromUtf8("Não Há Dados Para Remover");
                item = new QTableWidgetItem();
                item->setText(itemStatus);
                tableWidgetJpeg->setItem(i, 6, item);
            }
        }
        catch (Exiv2::AnyError& e) {
            QString itemMsg;
            switch (e.code()) {
                case 2:
                    itemMsg = QString::fromUtf8("Erro ao Remover Arquivo");
                    // Quando ocorrer erro na remoção do arquivo, ele será colocado numa lista para
                    // que ao fim da execução seja tentado mais uma vez a sua remoção.
                    listErrorRemoveFile.push_back(tableWidgetJpeg->item(i, 7)->text());
                    listErrorRemoveFilePosition.push_back(i);
                    break;
                case 9:
                    itemMsg = QString::fromUtf8("Erro de Acesso ao Arquivo");
                    break;
                case 10:
                    itemMsg = QString::fromUtf8("Arquivo Somente Leitura");
                    break;
                case 11:
                    itemMsg = QString::fromUtf8("Arquivo Inválido");
                    break;
            }
            item = new QTableWidgetItem();
            item->setForeground(QColor(255, 0, 0));
            item->setText(itemMsg);
            tableWidgetJpeg->setItem(i, 6, item);
        }
    }

    for (int i = 0; i < listErrorRemoveFile.size(); i++) {
        //precisa pesquisar no disco se tem outro arquivo com o nome igual mas com a extensão diferente
        // se achar, tem que remover o atual e renomear o outro arquivo.
        QString fileName;
        QString filePath;
        QString itemMsg;
        int pos;

        pos = listErrorRemoveFile.at(i).lastIndexOf("/");
        fileName.operator =(QString::fromUtf8(listErrorRemoveFile.at(i).right(listErrorRemoveFile.at(i).size() - pos - 1).toStdString().c_str()));
        filePath = listErrorRemoveFile.at(i).left(pos);
        QDir directory(filePath);
        QStringList filesOnDirectory = directory.entryList(QDir::Files);
        QString regularExpression(fileName);
        regularExpression.append("[0-9]{1,4}");
        QRegExp fileRegExp(regularExpression, Qt::CaseSensitive, QRegExp::RegExp);
        QStringList filesLocated = filesOnDirectory.filter(fileRegExp);
        for (int j = 0; j < filesLocated.size(); j++) {
            itemMsg = QString::fromUtf8("Não Foi Possível Corrigir o Arquivo, Verifique Manualmente");
            QFileInfo fileTemp(directory, filesLocated.at(j));
            QFileInfo fileCurrent(directory, fileName);
            if (fileTemp.size() > fileCurrent.size()) {
                if (directory.remove(fileName)) {
                    if (directory.rename(filesLocated.at(j), fileName)) {
                        itemMsg = QString::fromUtf8("O Erro no Arquivo foi Corrigido");
                        delete tableWidgetJpeg->takeItem(listErrorRemoveFilePosition.at(i), 3);
                        delete tableWidgetJpeg->takeItem(listErrorRemoveFilePosition.at(i), 4);
                        delete tableWidgetJpeg->takeItem(listErrorRemoveFilePosition.at(i), 5);
                    }
                }
            } else {
                if (directory.remove(filesLocated.at(j)))
                    itemMsg = QString::fromUtf8("O Erro no Arquivo foi Corrigido");
            }
            item = new QTableWidgetItem();
            item->setForeground(QColor(0, 110, 0));
            item->setText(itemMsg);
            tableWidgetJpeg->setItem(listErrorRemoveFilePosition.at(i), 6, item);
        }
    }
    emit progressBarValue(tableWidgetJpeg->rowCount());
    sleep(1);
    emit progressBarSetVisible(false);
}
Example #17
0
int main(int argc,const char* argv[])
{
    int result=0;
    const char* program = argv[0];

    const char* types[typeMax];
    types[typeUnknown  ] = "unknown";
    types[typeDirectory] = "directory";
    types[typeImage    ] = "image";
    types[typeXML      ] = "xml";
    types[typeDoc      ] = "doc";
    types[typeCode     ] = "code";
    types[typeFile     ] = "file";

    char const* keywords[kwMAX];
    memset(keywords,0,sizeof(keywords));
    keywords[kwHELP    ] = "help";
    keywords[kwVERSION ] = "version";
    keywords[kwVERBOSE ] = "verbose";
    keywords[kwDRYRUN  ] = "dryrun";
    keywords[kwDST     ] = "dst";
    keywords[kwADJUST  ] = "adjust";
    keywords[kwTZ      ] = "tz";
    keywords[kwDELTA   ] = "delta";

    map<std::string,string> shorts;
    shorts["-?"] = "-help";
    shorts["-h"] = "-help";
    shorts["-v"] = "-verbose";
    shorts["-V"] = "-version";
    shorts["-d"] = "-dst";
    shorts["-a"] = "-adjust";
    shorts["-t"] = "-tz";
    shorts["-D"] = "-delta";
    shorts["-s"] = "-delta";
    shorts["-X"] = "-dryrun";

    Options options ;
    options.help    = sina(keywords[kwHELP   ],argv) || argc < 2;
    options.verbose = sina(keywords[kwVERBOSE],argv);
    options.dryrun  = sina(keywords[kwDRYRUN ],argv);
    options.version = sina(keywords[kwVERSION],argv);
    options.dst     = sina(keywords[kwDST    ],argv);
    options.dryrun  = sina(keywords[kwDRYRUN ],argv);

    for ( int i = 1 ; !result && i < argc ; i++ ) {
        const char* arg   = argv[i++];
        if ( shorts.count(arg) ) arg = shorts[arg].c_str();

        const char* value = argv[i  ];
        int        ivalue = ::atoi(value?value:"0");
        int         key   = ::find(arg,keywords,kwMAX);
        int         needv = key < kwMAX && key > (-kwNOVALUE);

        if (!needv ) i--;
        if ( needv && !value) key = kwNEEDVALUE;

        switch ( key ) {
            case kwDST      : options.dst     = true ; break;
            case kwHELP     : options.help    = true ; break;
            case kwVERSION  : options.version = true ; break;
            case kwDRYRUN   : options.dryrun  = true ; break;
            case kwVERBOSE  : options.verbose = true ; break;
            case kwTZ       : Position::tz_      = parseTZ(value);break;
            case kwADJUST   : Position::adjust_  = ivalue;break;
            case kwDELTA    : Position::deltaMax_= ivalue;break;
            case kwNEEDVALUE: fprintf(stderr,"error: %s requires a value\n",arg); result = resultSyntaxError ; break ;
            case kwSYNTAX   : default:
            {
                int  type   = getFileType(arg,options) ;
                if ( options.verbose ) printf("%s %s ",arg,types[type]) ;
                if ( type == typeImage ) {
                    time_t t    = readImageTime(std::string(arg)) ;
                    char*  path = realpath(arg,NULL);
                    if  ( t && path ) {
                        if ( options.verbose) printf("%s %ld %s",path,(long int)t,asctime(localtime(&t)));
                        gFiles.push_back(path);
                    }
                    if ( path ) :: free((void*) path);
                }
                if ( type == typeUnknown ) {
                    fprintf(stderr,"error: illegal syntax %s\n",arg);
                    result = resultSyntaxError ;
                }
                if ( options.verbose ) printf("\n") ;
            }break;
        }
    }

    if ( options.help    ) ::help(program,keywords,kwMAX,options.verbose);
    if ( options.version ) ::version(program);

    if ( !result ) {
        sort(gFiles.begin(),gFiles.end(),mySort);
        if ( options.dst ) Position::dst_ = 3600;
        if ( options.verbose ) {
            int t = Position::tz();
            int d = Position::dst();
            int a = Position::adjust();
            int A = Position::Adjust();
            int s = A     ;
            int h = s/3600;
                s-= h*3600;
                s = abs(s);
            int m = s/60  ;
                s-= m*60  ;
            printf("tz,dsl,adjust = %d,%d,%d total = %dsecs (= %d:%d:%d)\n",t,d,a,A,h,m,s);
        }
        for ( size_t p = 0 ; !options.dryrun && p < gFiles.size() ; p++ ) {
            std::string arg = gFiles[p] ;
            std::string stamp ;
            try {
                time_t t       = readImageTime(arg,&stamp) ;
                Position* pPos = searchTimeDict(gTimeDict,t,Position::deltaMax_);
                Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(gFiles[p]);
                if ( image.get() ) {
                    image->readMetadata();
                    Exiv2::ExifData& exifData = image->exifData();
#if 0
                    /*
					char* keys[]={ "Exif.Image.GPSTag"
						         , "Exif.GPSInfo.GPSProcessingMethod"
					             , "Exif.GPSInfo.GPSAltitudeRef"
							     , "Exif.GPSInfo.GPSVersionID"
                                 , "Exif.GPSInfo.GPSProcessingMethod"
                                 , "Exif.GPSInfo.GPSVersionID"
                                 , "Exif.GPSInfo.GPSMapDatum"
                                 , "Exif.GPSInfo.GPSLatitude"
                                 , "Exif.GPSInfo.GPSLongitude"
                                 , "Exif.GPSInfo.GPSAltitude"
                                 , "Exif.GPSInfo.GPSAltitudeRef"
                                 , "Exif.GPSInfo.GPSLatitudeRef"
                                 , "Exif.GPSInfo.GPSLongitudeRef"
                                 , "Exif.GPSInfo.GPSDateStamp"
                                 , "Exif.GPSInfo.GPSTimeStamp"
					};
					static int bPrint = true ;
					for ( int k = 0 ; k < 15 ;   k++ ) {
						try {
							if ( bPrint ) printf("erasing %s\n",keys[k]);
							Exiv2::ExifKey  key = Exiv2::ExifKey(keys[k]);
							Exiv2::ExifData::iterator kk = exifData.findKey(key);
							if ( kk != exifData.end() ) exifData.erase(kk);
						} catch (...) {};
					}
					bPrint = false;
                    */
#endif
#if 0
					Exiv2::ExifData::const_iterator end = exifData.end();
					for (Exiv2::ExifData::iterator i = exifData.begin(); i != end; ++i) {
						char name[100];
						strcpy(name,i->key().c_str());
						// std::cout << "sniff " << i->key() << std::endl;
						if ( strstr(name,"GPS") )  {
							Exiv2::ExifData::iterator pos;
							Exiv2::ExifKey exifKey = Exiv2::ExifKey(name);
							pos = exifData.findKey(exifKey);
							while( pos != exifData.end()) {
								exifData.erase(pos);
							}
						}
					}
#endif
					if ( pPos ) {
						/*
						   struct _stat buf;
   int result;
   char timebuf[26];
   char* filename = "crt_stat.c";
   errno_t err;

   // Get data associated with "crt_stat.c":
   result = _stat( filename, &buf );

   int _utime(
   const char *filename,
   struct _utimbuf *times
);
   */

                        exifData["Exif.GPSInfo.GPSProcessingMethod" ] = "65 83 67 73 73 0 0 0 72 89 66 82 73 68 45 70 73 88"; // ASCII HYBRID-FIX
                        exifData["Exif.GPSInfo.GPSVersionID"        ] = "2 2 0 0";
                        exifData["Exif.GPSInfo.GPSMapDatum"         ] = "WGS-84";

                        exifData["Exif.GPSInfo.GPSLatitude"         ] = Position::toExifString(pPos->lat(),true,true);
                        exifData["Exif.GPSInfo.GPSLongitude"        ] = Position::toExifString(pPos->lon(),true,false);
                        exifData["Exif.GPSInfo.GPSAltitude"         ] = Position::toExifString(pPos->ele());

                        exifData["Exif.GPSInfo.GPSAltitudeRef"      ] = pPos->ele()<0.0?"1":"0";
						exifData["Exif.GPSInfo.GPSLatitudeRef"      ] = pPos->lat()>0?"N":"S";
						exifData["Exif.GPSInfo.GPSLongitudeRef"     ] = pPos->lon()>0?"E":"W";

                        exifData["Exif.GPSInfo.GPSDateStamp"        ] = stamp;
                        exifData["Exif.GPSInfo.GPSTimeStamp"        ] = Position::toExifTimeStamp(stamp);
						exifData["Exif.Image.GPSTag"                ] = 4908;

						printf("%s %s % 2d\n",arg.c_str(),pPos->toString().c_str(),pPos->delta());
                    } else {
                        printf("%s *** not in time dict ***\n",arg.c_str());
                    }
                    image->writeMetadata();
				}
            } catch ( ... ) {};
        }
    }

    return result ;
}
Example #18
0
/** \fn     ImageUtils::GetAllExifValues(const QString &)
 *  \brief  Reads and returns all non empty tags from the given file
 *  \param  fileName The filename that holds the exif data
 *  \return The list of exif tag names and values
 */
QList<QStringList> ImageUtils::GetAllExifValues(const QString &fileName)
{
    // default value, an empty list means no
    // exif tags were found or an error occured
    QList<QStringList> valueList;

    try
    {
        Exiv2::Image::AutoPtr image =
                Exiv2::ImageFactory::open(fileName.toLocal8Bit().constData());

        if (image.get())
        {
            image->readMetadata();
            Exiv2::ExifData &exifData = image->exifData();
            if (!exifData.empty())
            {
                LOG(VB_GENERAL, LOG_DEBUG,
                    QString("Found %1 tag(s) for file %2")
                    .arg(exifData.count())
                    .arg(fileName));

                Exiv2::ExifData::const_iterator end = exifData.end();
                Exiv2::ExifData::const_iterator i = exifData.begin();
                for (; i != end; ++i)
                {
                    QString value = QString::fromStdString(i->value().toString());

                    // Do not add empty tags to the list
                    if (!value.isEmpty())
                    {
                        QStringList values;

                        // These three are the same as i->key()
                        values.append(QString::fromStdString(i->familyName()));
                        values.append(QString::fromStdString(i->groupName()));
                        values.append(QString::fromStdString(i->tagName()));
                        values.append(QString::fromStdString(i->key()));
                        values.append(QString::fromStdString(i->tagLabel()));
                        values.append(QString::fromStdString(i->value().toString()));

                        // Add the exif information to the list
                        valueList.append(values);
                    }
                }
            }
            else
            {
                LOG(VB_GENERAL, LOG_ERR,
                    QString("Exiv2 error: No header, file %1")
                    .arg(fileName));
            }
        }
        else
        {
            LOG(VB_GENERAL, LOG_ERR,
                QString("Exiv2 error: Could not open file, file %1")
                .arg(fileName));
        }
    }
    catch (Exiv2::Error& e)
    {
        LOG(VB_GENERAL, LOG_ERR,
            QString("Exiv2 exception %1, file %2")
            .arg(e.what()).arg(fileName));
    }

    return valueList;
}
Example #19
0
int RenameMePhotos::openDirectory(std::string p, std::vector<std::pair<boost::filesystem::path, time_t> > &vec, bool recursive, bool clear)
{
	if(clear)
	{
		vec.clear();
	}
	// Var Declaration
	struct tm t;
	std::vector<boost::filesystem::path> vecTmp;
	std::pair<boost::filesystem::path, time_t> file;
	std::string strTmp;
	time_t timestamp;
	boost::filesystem::path path(p);

	Exiv2::ExifData exifData;
	Exiv2::Image::AutoPtr image;
	
	// Body
	if(exists(path))
	{
		if(is_directory(path))
		{		
			if(recursive)
			{
				std::copy(boost::filesystem::recursive_directory_iterator(path), boost::filesystem::recursive_directory_iterator(), std::back_inserter(vecTmp));
			}
			else
			{
				std::copy(boost::filesystem::directory_iterator(path), boost::filesystem::directory_iterator(), std::back_inserter(vecTmp));
			}

			for(std::vector<boost::filesystem::path>::const_iterator it(vecTmp.begin()); it != vecTmp.end(); it++)
			{
				if(!is_directory(*it))
				{
					image = Exiv2::ImageFactory::open((*it).c_str());
					if(image.get() != 0)
					{
						image->readMetadata();
						exifData = image->exifData();
						if(!exifData.empty())
						{
							strTmp = exifData["Exif.Photo.DateTimeOriginal"].toString();
							strptime(strTmp.c_str(), "%Y:%m:%d %H:%M:%S", &t);
							t.tm_isdst = -1;
							timestamp = mktime(&t);
							file = std::make_pair(*it, timestamp);
							vec.push_back(file);
						}
						else
						{
							// Error for at least an image in metadata
						}
					}
				}
			}
		}
		else
		{
			// Error 2: The selected path is not a directory
		}
	}
	else
	{
		// Error 1: There is no such path
	}
	return 1;
}
Example #20
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
    // Handle command line arguments
    Params params;
    if (params.getopt(argc, argv)) {
        params.usage();
        return 1;
    }
    if (params.help_) {
        params.help();
        return 2;
    }

    // Use MemIo to increase test coverage.
    Exiv2::BasicIo::AutoPtr fileIo(new Exiv2::FileIo(params.read_));
    Exiv2::BasicIo::AutoPtr memIo(new Exiv2::MemIo);

    if (memIo->transfer(*fileIo) != 0) {
        std::cerr << params.progname() << 
            ": Could not read file (" << params.read_ << ")\n";
        return 4;
    }
    
    Exiv2::Image::AutoPtr readImg 
        = Exiv2::ImageFactory::open(memIo);
    if (readImg.get() == 0) {
        std::cerr << params.progname() << 
            ": Could not read file (" << params.read_ << ")\n";
        return 4;
    }
    if (readImg->readMetadata()) {
        std::cerr << params.progname() << 
            ": Could not read metadata from (" << params.read_ << ")\n";
        return 5;
    }

    Exiv2::Image::AutoPtr writeImg 
        = Exiv2::ImageFactory::open(params.write_);
    if (writeImg.get() == 0) {
        std::cerr << params.progname() << 
            ": Could not read file (" << params.write_ << ")\n";
        return 6;
    }

    if (params.preserve_) {
        if (writeImg->readMetadata()) {
            std::cerr << params.progname() << 
                ": Could not read metadata from (" << params.write_ << ")\n";
            return 7;
        }
    }
    if (params.iptc_) {
        writeImg->setIptcData(readImg->iptcData());
    }
    if (params.exif_) {
        writeImg->setExifData(readImg->exifData());
    }
    if (params.comment_) {
        writeImg->setComment(readImg->comment());
    }

    if (writeImg->writeMetadata()) {
        std::cerr << params.progname() << 
            ": Could not write metadata to (" << params.write_ << ")\n";
        return 8;
    }

    return 0;
}
catch (Exiv2::Error& e) {
    std::cerr << "Caught Exiv2 exception '" << e << "'\n";
    return 10;
}
}
Example #21
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
try {

    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
    if (image.get() == 0) {
        std::string error(argv[1]);
        error += " : Could not read file or unknown image type";
        throw Exiv2::Error(error);
    }

    // Load existing metadata
    int rc = image->readMetadata();
    if (rc) {
        std::string error = Exiv2::Image::strError(rc, argv[1]);
        throw Exiv2::Error(error);
    }

    Exiv2::ExifData &exifData = image->exifData();

    /*
      There are two pitfalls that we need to consider when setting the Exif user
      comment (Exif.Photo.UserComment) of an image:

      First, the type of the Exif user comment tag is "undefined" (and not
      ASCII) according to the Exif standard. This means that in Exiv2, we have
      to deal with a DataValue (and not an AsciiValue). DataValue has the usual
      two read methods, however, the one taking a const std::string& buf expects
      the string to contain a series of integers (e.g., "0 1 2") and not a text
      string. Thus, we need to use the read function that reads the value from a
      character buffer of a given length.

      Second, the Exif comment field starts with an eight character area that
      identifies the used character set. For ASCII, these eight characters are
      "ASCII\0\0\0". The actual comment follows after this code.

      Note: There is a more simple Exif tag for the title of an image. It is a
      20 byte string (type ASCII) and does not store two-byte characters.
      (Exif.Image.ImageDescription)
     */

    // Initialise a data value with the character set and comment
    std::string charset("ASCII\0\0\0", 8);
    std::string comment("A comment added to the Exif metadata through Exiv2");
    Exiv2::DataValue value;
    value.read(reinterpret_cast<const Exiv2::byte*>((charset + comment).data()), 
                8 + static_cast<long>(comment.size()));

    // Set the Exif comment
    Exiv2::ExifKey key("Exif.Photo.UserComment");
    Exiv2::ExifData::iterator pos = exifData.findKey(key);
    if (pos != exifData.end()) {
        // Use the existing Exif UserComment metadatum if there is one
        pos->setValue(&value);
    }
    else {
        // Otherwise add a new UserComment metadatum
        exifData.add(key, &value);
        pos = exifData.findKey(key);
    }

    // Now we should have a valid iterator in any case. We use the metadatum
    // output operator to print the formatted value
    std::cout << "Writing user comment '" << *pos << "' back to the image\n";

    rc = image->writeMetadata();
    if (rc) {
        std::string error = Exiv2::Image::strError(rc, argv[1]);
        throw Exiv2::Error(error);
    }

    return rc;
}
catch (Exiv2::Error& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
Example #22
0
bool KExiv2::Private::saveOperations(const QFileInfo& finfo, Exiv2::Image::AutoPtr image) const
{
    try
    {
        Exiv2::AccessMode mode;
        bool wroteComment = false, wroteEXIF = false, wroteIPTC = false, wroteXMP = false;

        // We need to load target file metadata to merge with new one. It's mandatory with TIFF format:
        // like all tiff file structure is based on Exif.
        image->readMetadata();

        // Image Comments ---------------------------------

        mode = image->checkMode(Exiv2::mdComment);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setComment(imageComments());
            wroteComment = true;
        }

        // Exif metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdExif);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            if (image->mimeType() == "image/tiff")
            {
                Exiv2::ExifData orgExif = image->exifData();
                Exiv2::ExifData newExif;
                QStringList     untouchedTags;

                // With tiff image we cannot overwrite whole Exif data as well, because
                // image data are stored in Exif container. We need to take a care about
                // to not lost image data.
                untouchedTags << "Exif.Image.ImageWidth";
                untouchedTags << "Exif.Image.ImageLength";
                untouchedTags << "Exif.Image.BitsPerSample";
                untouchedTags << "Exif.Image.Compression";
                untouchedTags << "Exif.Image.PhotometricInterpretation";
                untouchedTags << "Exif.Image.FillOrder";
                untouchedTags << "Exif.Image.SamplesPerPixel";
                untouchedTags << "Exif.Image.StripOffsets";
                untouchedTags << "Exif.Image.RowsPerStrip";
                untouchedTags << "Exif.Image.StripByteCounts";
                untouchedTags << "Exif.Image.XResolution";
                untouchedTags << "Exif.Image.YResolution";
                untouchedTags << "Exif.Image.PlanarConfiguration";
                untouchedTags << "Exif.Image.ResolutionUnit";

                for (Exiv2::ExifData::iterator it = orgExif.begin(); it != orgExif.end(); ++it)
                {
                    if (untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = orgExif[it->key().c_str()];
                    }
                }

                Exiv2::ExifData readedExif = exifMetadata();

                for (Exiv2::ExifData::iterator it = readedExif.begin(); it != readedExif.end(); ++it)
                {
                    if (!untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = readedExif[it->key().c_str()];
                    }
                }

                image->setExifData(newExif);
            }
            else
            {
                image->setExifData(exifMetadata());
            }

            wroteEXIF = true;
        }

        // Iptc metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdIptc);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setIptcData(iptcMetadata());
            wroteIPTC = true;
        }

        // Xmp metadata -----------------------------------

        mode = image->checkMode(Exiv2::mdXmp);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
#ifdef _XMP_SUPPORT_
            image->setXmpData(xmpMetadata());
            wroteXMP = true;
#endif
        }

        if (!wroteComment && !wroteEXIF && !wroteIPTC && !wroteXMP)
        {
            kDebug() << "Writing metadata is not supported for file" << finfo.fileName();
            return false;
        }
        else if (!wroteEXIF || !wroteIPTC || !wroteXMP)
        {
            kDebug() << "Support for writing metadata is limited for file" << finfo.fileName()
                     << "EXIF" << wroteEXIF << "IPTC" << wroteIPTC << "XMP" << wroteXMP;
        }

        if (!updateFileTimeStamp)
        {
            // Don't touch access and modification timestamp of file.
            struct stat st;
            ::stat(QFile::encodeName(filePath), &st);

            struct utimbuf ut;
            ut.modtime = st.st_mtime;
            ut.actime  = st.st_atime;

            image->writeMetadata();

            ::utime(QFile::encodeName(filePath), &ut);
        }
        else
        {
            image->writeMetadata();
        }

        return true;
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError("Cannot save metadata using Exiv2 ", e);
    }

    return false;
}
Example #23
0
SlideShowWindow::SlideShowWindow(QWidget *parent)
	: QWidget(parent)
	, m_group(0)
	, m_scene(0)
	, m_oldScene(0)
	, m_useGLWidget(true)
	, m_glWidget(0)
	, m_graphicsView(0)
	, m_xfadeSpeed(300)
{
	QVBoxLayout *layout = new QVBoxLayout(this);
	layout->setContentsMargins(0,0,0,0);
	
	bool verbose = true;
	QString configFile = "player.ini";
	
	if(verbose)
		qDebug() << "SlideShowWindow: Reading settings from "<<configFile;
		
	QSettings settings(configFile,QSettings::IniFormat);
	
	QString str;
	QStringList parts;
	QPoint point;
	
	QString activeGroup = settings.value("config").toString();
	
	str = settings.value("verbose").toString();
	if(!str.isEmpty())
		verbose = str == "true";
	
	if(verbose && !activeGroup.isEmpty())
		qDebug() << "SlideShowWindow: Using config:"<<activeGroup;
	
	#define READ_STRING(key,default) \
		(!activeGroup.isEmpty() ? \
			(!(str = settings.value(QString("%1/%2").arg(activeGroup).arg(key)).toString()).isEmpty() ?  str : \
				settings.value(key,default).toString()) : \
			settings.value(key,default).toString())
			
	#define READ_POINT(key,default) \
		str = READ_STRING(key,default); \
		parts = str.split("x"); \
		point = QPoint(parts[0].toInt(),parts[1].toInt()); \
		if(verbose) qDebug() << "SlideShowWindow: " key ": " << point; 
		
	m_useGLWidget = READ_STRING("compat","false") == "false";
	if(m_useGLWidget)
	{
		m_glWidget = new GLWidget(this);
		layout->addWidget(m_glWidget);
		qDebug() << "SlideShowWindow: Using OpenGL to provide high-quality graphics.";
		
		m_glWidget->setCursor(Qt::BlankCursor);
	}
	else
	{
		m_graphicsView = new ScaledGraphicsView();
		m_graphicsScene = new QGraphicsScene();
		m_graphicsView->setScene(m_graphicsScene);
		m_graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
		m_graphicsScene->setSceneRect(QRectF(0,0,1000.,750.));
		m_graphicsView->setBackgroundBrush(Qt::black);
		layout->addWidget(m_graphicsView);
		
		qDebug() << "SlideShowWindow: Using vendor-provided stock graphics engine for compatibility with older hardware.";
		
		m_graphicsView->setCursor(Qt::BlankCursor);
	}
	
	
	// Window position and size
	READ_POINT("window-pos","10x10");
	QPoint windowPos = point;
	
	READ_POINT("window-size","640x480");
	QPoint windowSize = point;
	//windowSize = QPoint(3120,1050);
	
	if(verbose)
		qDebug() << "SlideShowWindow: pos:"<<windowPos<<", size:"<<windowSize;
	
	resize(windowSize.x(),windowSize.y());
	move(windowPos.x(),windowPos.y());
	
	bool frameless = READ_STRING("frameless","true") == "true";
	if(frameless)
		setWindowFlags(Qt::FramelessWindowHint);// | Qt::ToolTip);
	
	if(m_useGLWidget)
	{
		
		// Keystoning / Corner Translations
		READ_POINT("key-tl","0x0");
		m_glWidget->setTopLeftTranslation(point);
		
		READ_POINT("key-tr","0x0");
		m_glWidget->setTopRightTranslation(point);
		
		READ_POINT("key-bl","0x0");
		m_glWidget->setBottomLeftTranslation(point);
		
		READ_POINT("key-br","0x0");
		m_glWidget->setBottomRightTranslation(point);
		
		// Brightness/Contrast, Hue/Sat
		m_glWidget->setBrightness(READ_STRING("brightness","0").toInt());
		m_glWidget->setContrast(READ_STRING("contrast","0").toInt());
		m_glWidget->setHue(READ_STRING("hue","0").toInt());
		m_glWidget->setSaturation(READ_STRING("saturation","0").toInt());
		
		// Flip H/V
		bool fliph = READ_STRING("flip-h","false") == "true";
		if(verbose)
			qDebug() << "SlideShowWindow: flip-h: "<<fliph;
		m_glWidget->setFlipHorizontal(fliph);
		
		bool flipv = READ_STRING("flip-v","false") == "true";
		if(verbose)
			qDebug() << "SlideShowWindow: flip-v: "<<flipv;
		m_glWidget->setFlipVertical(flipv);
		
		// Rotate
		int rv = READ_STRING("rotate","0").toInt();
		if(verbose)
			qDebug() << "SlideShowWindow: rotate: "<<rv;
		
		if(rv != 0)
			m_glWidget->setCornerRotation(rv == -1 ? GLRotateLeft  : 
						      rv ==  1 ? GLRotateRight : 
							         GLRotateNone);
		
		// Aspet Ratio Mode
		m_glWidget->setAspectRatioMode(READ_STRING("ignore-ar","false") == "true" ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio);
		
		// Alpha Mask
		QString alphaFile = READ_STRING("alphamask","");
		if(!alphaFile.isEmpty())
		{
			QImage alphamask(alphaFile);
			if(alphamask.isNull())
				qDebug() << "SlideShowWindow: Error loading alphamask "<<alphaFile;
			else
				m_glWidget->setAlphaMask(alphamask);
		}
		
// 		GLWidgetSubview *sub1 = m_glWidget->defaultSubview();
// 		sub1->setRight(1680./3120.);
// 		
// 		GLWidgetSubview *sub2 = new GLWidgetSubview();
// 		sub2->setLeft(sub1->right());
// 		sub2->setBrightness(75);
// 		sub2->setFlipVertical(true);
// 		sub2->setFlipHorizontal(true);
// 		
// 		m_glWidget->addSubview(sub2);
	}
	
	// Canvas Size
	READ_POINT("canvas-size","1000x750");
	QSizeF canvasSize((qreal)point.x(),(qreal)point.y());
	//canvasSize = QSizeF(2000,750);
	canvasSize = QSizeF(3120,1050);
	if(m_useGLWidget)
	{
		m_glWidget->setCanvasSize(canvasSize);
	}
	else
	{
		m_graphicsScene->setSceneRect(QRectF(QPointF(0,0),canvasSize));
	}
	
	m_xfadeSpeed = READ_STRING("xfade-speed",300).toInt();
	//qDebug() << "SlideShowWindow: Crossfade speed: "<<m_xfadeSpeed;
	
// 	QString loadGroup = READ_STRING("load-group","");
// 	if(!loadGroup.isEmpty())
// 	{
// 		QFile file(loadGroup);
// 		if (!file.open(QIODevice::ReadOnly)) 
// 		{
// 			qDebug() << "SlideShowWindow: Unable to read group file: "<<loadGroup;
// 		}
// 		else
// 		{
// 			QByteArray array = file.readAll();
// 			
// 			GLSceneGroup *group = new GLSceneGroup();
// 			group->fromByteArray(array);
// 			setGroup(group);
// 			
// 			GLScene *scene = group->at(0);
// 			if(scene)
// 			{
// 				//scene->setGLWidget(this);
// 				setScene(scene);
// 				qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<group->groupId()<<", SceneID: "<< scene->sceneId();
// 				
// 				if(m_outputEncoder && 
// 				  !m_outputEncoder->encodingStarted())
// 					m_outputEncoder->startEncoder();
// 
// 			}
// 			else
// 			{
// 				qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<group->groupId()<<" - no scenes found at index 0";
// 			}
// 		}	
// 	}
// 	else
// 	{
// 		QString loadGroup = READ_STRING("collection","");
// 		if(!loadGroup.isEmpty())
// 		{
// 			QFile file(loadGroup);
// 			if (!file.open(QIODevice::ReadOnly)) 
// 			{
// 				qDebug() << "SlideShowWindow: Unable to read group file: "<<loadGroup;
// 			}
// 			else
// 			{
// 				QByteArray array = file.readAll();
// 				
// 				GLSceneGroupCollection *collection = new GLSceneGroupCollection();
// 				collection->fromByteArray(array);
// 				setGroup(collection->at(0));
// 				
// 				if(m_group)
// 				{
// 					GLScene *scene = m_group->at(0);
// 					if(scene)
// 					{
// 						//scene->setGLWidget(this);
// 						setScene(scene);
// 						qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<m_group->groupId()<<", SceneID: "<< scene->sceneId();
// 						
// 						GLDrawableList list = scene->drawableList();
// 						foreach(GLDrawable *gld, list)
// 							if(gld->playlist()->size() > 0)
// 								gld->playlist()->play();	
// 						
// 						if(m_outputEncoder && 
// 						!m_outputEncoder->encodingStarted())
// 							m_outputEncoder->startEncoder();
// 		
// 					}
// 					else
// 					{
// 						qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<m_group->groupId()<<" - no scenes found at index 0";
// 					}
// 				}
// 			}	
// 		}
// 	}


	QStringList argList = qApp->arguments();
	if(argList.size() > 1)
	{
		QString dirName = argList.at(1);
		QDir dir(dirName);
		dir.setNameFilters(QStringList() << "*.jpg" << "*.JPG" << "*.jpeg" << "*.png" << "*.PNG");
		QFileInfoList list = dir.entryInfoList(QDir::Files, QDir::Name);
		
		if(m_glWidget)
			m_glWidget->setFboEnabled(false);
		
		int spinSize = 28;
			
			
		//QStringList list = dir.entryList();
		//foreach(QString file, list)
		foreach(QFileInfo info, list)
		{
			//QFileInfo info(QString("%1/%2").arg(dirName,file));
			//if(!info.isFile())
			//	continue;
			//QString ext = info.suffix().toLower();
			//if(ext != "jpg" || ext != "png" || ext != "jpeg")
			//	continue;
			
			bool flipText = true;
			
			QString fullFile = info.absoluteFilePath();
			qDebug() << "SlideShowWindow: Loading "<<fullFile;//<<" (ext:"<<ext<<")";
			GLScene *scene = new GLScene();
			{
				QString comment = "";
				QString datetime = "";
				try
				{
					Exiv2::Image::AutoPtr exiv = Exiv2::ImageFactory::open(fullFile.toStdString()); 
					if(exiv.get() != 0)
					{
						exiv->readMetadata();
						Exiv2::ExifData& exifData = exiv->exifData();
						if (exifData.empty()) 
						{
							qDebug() << fullFile << ": No Exif data found in the file";
						}
		
						comment = exifData["Exif.Image.ImageDescription"].toString().c_str();
						comment = GLTextDrawable::htmlToPlainText(comment);
						
						datetime = exifData["Exif.Photo.DateTimeOriginal"].toString().c_str();
			
						if(comment.trimmed().isEmpty())
						{
							Exiv2::IptcData& iptcData = exiv->iptcData();
							comment = iptcData["Iptc.Application2.Caption"].toString().c_str();
							comment = GLTextDrawable::htmlToPlainText(comment);
							
							if (exifData.empty()) 
							{
								qDebug() << fullFile << ": No IPTC data found in the file";
							}
							else
							{
								qDebug() << "SlideShowWindow: IPTC Caption:"<<comment;
							}
						}
						else
						{
							qDebug() << "SlideShowWindow: EXIF Caption:"<<comment;
						}
						
						
					}
				}
				catch (Exiv2::AnyError& e) 
				{
					std::cout << "Caught Exiv2 exception '" << e << "'\n";
					//return -1;
				}
				
				GLImageDrawable *image = new GLImageDrawable(fullFile);
				
				if(canvasSize.width() > 1000)
				{
					image->setRect(QRectF(QPointF(0,0),QSize(1680,canvasSize.height())));
				}
				else
				{
					image->setRect(QRectF(QPointF(0,0),canvasSize));
				}
				//image->setCrossFadeMode(GLVideoDrawable::JustFront);
				scene->addDrawable(image);
				
				if(!comment.isEmpty())
				{
					comment = comment.replace(QRegExp("^\\s*\"([^\"]+)\"\\s*-\\s*"), "<center>\"\\1\"</center><br>");
					 
					GLTextDrawable *text = new GLTextDrawable();
					QString ptSize = "36";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						+ comment +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					if(canvasSize.width() > 1000)
					{
						QSize size = text->findNaturalSize(1400);
						
						QRectF targetRect = QRectF(0, 0, size.width(), size.height());
						targetRect.moveCenter(QRectF(1680,0,1440,900).center());
		
						text->setRect(targetRect);
						
						if(flipText)
						{
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
					}
					else
					{
						int w = (int)canvasSize.width();
						QSize size = text->findNaturalSize(w);
						
						double x = (canvasSize.width() - size.width()) / 2;
						double y = canvasSize.height() - size.height() - 2;
						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
					
					qDebug() << "Loaded caption:"<<comment;
				}
				
				QFileInfo fileInfo(fullFile);
				QString fileName = fileInfo.baseName().toLower();
				fileName = fileName.replace(QRegExp("\\d{2,6}-\\{\\d\\}"),"");
				fileName = fileName.replace(QRegExp("(dsc_|sdc)"), "");
				
				if(!fileName.isEmpty())
				{
					GLTextDrawable *text = new GLTextDrawable();
					//QString html = QString("<span style='font-color:white;font-size:20px'>%1</font>").arg(fileName);
					
					QString ptSize = "24";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						"Photograph # "+ fileName +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					int w = (int)canvasSize.width();
					QSize size = text->findNaturalSize(w);
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					
					if(flipText)
					{
						if(canvasSize.width() > 1000)
						{
							int spinSpace = spinSize + 10;
							
							size = text->findNaturalSize(1440);
							
							//QRectF targetRect = QRectF(0, 0, size.width(), size.height());
							//targetRect.moveCenter(QRectF(1680,0,1440,900).center());
							double x = 1680 + 10 + spinSpace;
							double y =  900 - 10 - size.height();
							QRectF rect(QPointF(x,y),size);
							//qDebug() << "Rect: "<<rect;
							text->setRect(rect);
							
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
						else
						{
							// TODO flip here too
							double x = canvasSize.width() - size.width() - 2;
							double y = 2;
							text->setRect(QRectF(QPointF(x,y),size));
						}
					}
					else
					{
						double x = canvasSize.width() - size.width() - 2;
						double y = 2;
						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
				}
				
				if(!datetime.isEmpty())
				{
					GLTextDrawable *text = new GLTextDrawable();
					//QString html = QString("<span style='font-color:white;font-size:20px'>%1</font>").arg(fileName);
					
					// 2009:10:25 12:13:34
					QDateTime parsedDate = QDateTime::fromString(datetime, "yyyy:MM:dd hh:mm:ss");
					QString dateString = "Photographed " + parsedDate.toString("dddd, MMMM d, yyyy");
					
					QString ptSize = "24";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						+ dateString +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					int w = (int)canvasSize.width();
					QSize size = text->findNaturalSize(w);
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					
					if(flipText)
					{
						if(canvasSize.width() > 1000)
						{
							//int spinSpace = spinSize + 10;
							
							size = text->findNaturalSize(1440);
							
							//QRectF targetRect = QRectF(0, 0, size.width(), size.height());
							//targetRect.moveCenter(QRectF(1680,0,1440,900).center());
							double x = 1680 + (1440 - size.width()) / 2;
							double y =  10; //900 - 10 - size.height();
							QRectF rect(QPointF(x,y),size);
							//qDebug() << "Rect: "<<rect;
							text->setRect(rect);
							
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
						else
						{
							// TODO 
// 							double x = canvasSize.width() - size.width() - 2;
// 							double y = 2;
// 							text->setRect(QRectF(QPointF(x,y),size));
						}
					}
					else
					{
						// TODO
// 						double x = canvasSize.width() - size.width() - 2;
// 						double y = 2;
// 						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
				}
			}
			
			
			m_scenes << scene;
		}
Example #24
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }
    std::string file(argv[1]);

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
    assert (image.get() != 0);
    image->readMetadata();

    Exiv2::ExifData &ed = image->exifData();
    if (ed.empty()) {
        std::string error = file + ": No Exif data found in the file";
        throw Exiv2::Error(1, error);
    }

    std::cout << "Copy construction, non-intrusive changes\n";
    Exiv2::ExifData ed1(ed);
    ed1["Exif.Image.DateTime"] = "Sunday, 11am";
    ed1["Exif.Image.Orientation"] = uint16_t(2);
    ed1["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am";
    ed1["Exif.Photo.MeteringMode"] = uint16_t(1);
    ed1["Exif.Iop.InteroperabilityIndex"] = "123";
//    ed1["Exif.Thumbnail.Orientation"] = uint16_t(2);
    write(file, ed1);
    print(file);
    std::cout << "----------------------------------------------\n";

    std::cout << "Copy construction, intrusive changes\n";
    Exiv2::ExifData ed2(ed);
    ed2["Exif.Image.DateTime"] = "Sunday, 11am and ten minutes";
    ed2["Exif.Image.Orientation"] = "2 3 4 5";
    ed2["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am and ten minutes";
    ed2["Exif.Photo.MeteringMode"] = "1 2 3 4 5 6";
    ed2["Exif.Iop.InteroperabilityIndex"] = "1234";
    ed2["Exif.Thumbnail.Orientation"] = "2 3 4 5 6";
    write(file, ed2);
    print(file);
    std::cout << "----------------------------------------------\n";

    std::cout << "Assignment, non-intrusive changes\n";
    Exiv2::ExifData ed3;
    ed3["Exif.Iop.InteroperabilityVersion"] = "Test 6 Iop tag";
    ed3["Exif.Thumbnail.Artist"] = "Test 6 Ifd1 tag";
    ed3 = ed;
    ed3["Exif.Image.DateTime"] = "Sunday, 11am";
    ed3["Exif.Image.Orientation"] = uint16_t(2);
    ed3["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am";
    ed3["Exif.Photo.MeteringMode"] = uint16_t(1);
    ed3["Exif.Iop.InteroperabilityIndex"] = "123";
    ed3["Exif.Thumbnail.Orientation"] = uint16_t(2);
    write(file, ed3);
    print(file);
    std::cout << "----------------------------------------------\n";

    std::cout << "Assignment, intrusive changes\n";
    Exiv2::ExifData ed4;
    ed4["Exif.Iop.InteroperabilityVersion"] = "Test 6 Iop tag";
    ed4["Exif.Thumbnail.Artist"] = "Test 6 Ifd1 tag";
    ed4 = ed;
    ed4["Exif.Image.DateTime"] = "Sunday, 11am and ten minutes";
    ed4["Exif.Image.Orientation"] = "2 3 4 5";
    ed4["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am and ten minutes";
    ed4["Exif.Photo.MeteringMode"] = uint16_t(1);
    ed4["Exif.Iop.InteroperabilityIndex"] = "123";
    ed4["Exif.Thumbnail.Orientation"] = uint16_t(2);
    write(file, ed4);
    print(file);

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
}
Example #25
0
QPixmap MediaBrowser::iconForImage(const QString & file, const QSize & size)
{
	QPixmap cache;
	QDir path(QString("%1/%2").arg(AppSettings::cachePath()).arg(CACHE_DIR));
	if(!path.exists())
		QDir(AppSettings::cachePath()).mkdir(CACHE_DIR);

	QString cacheFile = QString("%1/%2/%3-%4x%5")
				.arg(AppSettings::cachePath())
				.arg(CACHE_DIR)
				.arg(MD5::md5sum(file))
				.arg(size.width())
				.arg(size.height());


	//QPixmap orig(file);
	//orig = orig.scaled(size,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
	//orig.detach();

	//return orig;

	bool cacheFileModified = !QFile(cacheFile).exists() || QFileInfo(file).lastModified() >= QFileInfo(cacheFile).lastModified();
	//qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", size:"<<size<<", cacheFile: "<<cacheFile<<", cacheModified:"<<cacheFileModified;
	
	if(!QPixmapCache::find(cacheFile,cache) || cacheFileModified)
	{
		if(QFile(cacheFile).exists() && !cacheFileModified)
		{
			cache.load(cacheFile);
			QPixmapCache::insert(cacheFile,cache);
// 			qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", size:"<<size<<": hit DISK (loaded scaled from disk cache)";
		}
		else
		{
			bool gotThumb = false;
			try
			{
				Exiv2::Image::AutoPtr exiv = Exiv2::ImageFactory::open(file.toStdString()); 
				if(exiv.get() != 0)
				{
					exiv->readMetadata();
					Exiv2::ExifData& exifData = exiv->exifData();
					if (exifData.empty()) 
					{
// 						qDebug() << file << ": No Exif data found in the file";
					}
					Exiv2::ExifThumb exifThumb(exifData);
					std::string thumbExt = exifThumb.extension();
					if (thumbExt.empty()) 
					{
// 						qDebug() << file << ": Image does not contain an Exif thumbnail";
					}
					else
					{
						Exiv2::DataBuf buf = exifThumb.copy();
						if (buf.size_ != 0) 
						{
							qDebug() << file << ": Attempting to load thumnail (" << exifThumb.mimeType() << ", "
								<< buf.size_ << " Bytes)";
							
							QPixmap thumb;
							if(!thumb.loadFromData(buf.pData_, buf.size_))
							{
								qDebug() << file << "QPixmap::fromData() failed";
							}
							else
							{
								QString rotateSensor = exifData["Exif.Image.Orientation"].toString().c_str();
								int rotationFlag = rotateSensor.toInt(); 
								int rotateDegrees = rotationFlag == 1 ||
										rotationFlag == 2 ? 0 :
										rotationFlag == 7 ||
										rotationFlag == 8 ? -90 :
										rotationFlag == 3 ||
										rotationFlag == 4 ? -180 :
										rotationFlag == 5 ||
										rotationFlag == 6 ? -270 :
										0;
								QTransform t = QTransform().rotate(rotateDegrees);
								thumb = thumb.transformed(t);
										
								cache = thumb.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation);
								
								if(abs(rotateDegrees) == 90 || abs(rotateDegrees) == 270)
								{
									QPixmap centeredCache(size);
									centeredCache.fill(Qt::transparent);
									int pos = size.width() /2 - cache.width() / 2;
									QPainter painter(&centeredCache);
									painter.drawPixmap(pos,0,cache);
									cache = centeredCache;
									qDebug() << file << " * Centered rotated pixmap in frame";
								}
								
								cache.save(cacheFile,"PNG");
								//qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", image file: caching to:"<<cacheFile<<" for "<<file;
								QPixmapCache::insert(cacheFile,cache);
								
								gotThumb = true;
								
// 								qDebug() << file << ": Succesfully loaded Exiv thumnail and scaled to size, wrote to: "<<cacheFile;
							}
						}
					}
				}
			}
			catch (Exiv2::AnyError& e) 
			{
				//std::cout << "Caught Exiv2 exception '" << e << "'\n";
				//return -1;
				gotThumb = false;
			}
			
			if(!gotThumb)
			{
				QPixmap orig(file);
				if(orig.isNull())
				{
					cache = QPixmap();
					QPixmapCache::insert(cacheFile,cache);
					qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", size:"<<size<<": load INVALID (Can't load original)";
				}
				else
				{
					cache = orig.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation);
					cache.save(cacheFile,"PNG");
					////qDebug() << "MyQFileIconProvider::icon(): image file: caching to:"<<cacheFile<<" for "<<file;
					QPixmapCache::insert(cacheFile,cache);
// 					qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", size:"<<size<<": load GOOD (loaded original and scaled)";
					//QApplication::processEvents();
				}
			}
		}
	}
	else
	{
		//qDebug() << "MediaBrowser::iconForImage: file:"<<file<<", size:"<<size<<": hit RAM (scaled image already in ram)";
	}

	//qDebug() << "MediaBrowser::data: iconForImage: file:"<<file<<", cacheKey:"<<cache.cacheKey();

	return cache;
}
Example #26
0
bool KExiv2::load(const QString& filePath) const
{
    if (filePath.isEmpty())
    {
        return false;
    }

    d->filePath      = filePath;
    bool hasLoaded   = false;

    try
    {
        Exiv2::Image::AutoPtr image;

        image        = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(filePath)).constData());

        image->readMetadata();

        // Size and mimetype ---------------------------------

        d->pixelSize = QSize(image->pixelWidth(), image->pixelHeight());
        d->mimeType  = QString::fromLatin1(image->mimeType().c_str());

        // Image comments ---------------------------------

        d->imageComments() = image->comment();

        // Exif metadata ----------------------------------

        d->exifMetadata() = image->exifData();

        // Iptc metadata ----------------------------------

        d->iptcMetadata() = image->iptcData();

#ifdef _XMP_SUPPORT_

        // Xmp metadata -----------------------------------
        d->xmpMetadata() = image->xmpData();

#endif // _XMP_SUPPORT_

        hasLoaded = true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot load metadata from file "), e);
    }
    catch(...)
    {
        qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
    }

#ifdef _XMP_SUPPORT_
    try
    {
        if (d->useXMPSidecar4Reading)
        {
            QString xmpSidecarPath = sidecarFilePathForFile(filePath);
            QFileInfo xmpSidecarFileInfo(xmpSidecarPath);

            Exiv2::Image::AutoPtr xmpsidecar;

            if (xmpSidecarFileInfo.exists() && xmpSidecarFileInfo.isReadable())
            {
                // Read sidecar data
                xmpsidecar = Exiv2::ImageFactory::open(QFile::encodeName(xmpSidecarPath).constData());
                xmpsidecar->readMetadata();

                // Merge
                d->loadSidecarData(xmpsidecar);
                hasLoaded = true;
            }
        }
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot load XMP sidecar"), e);
    }
    catch(...)
    {
        qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
    }

#endif // _XMP_SUPPORT_

    return hasLoaded;
}
Example #27
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }
    std::string file(argv[1]);

    std::cout <<"----- Some IFD0 tags\n";
    Exiv2::ExifData ed1;
    ed1["Exif.Image.Model"] = "Test 1";

    Exiv2::Value::AutoPtr v1 = Exiv2::Value::create(Exiv2::unsignedShort);
    v1->read("160 161 162 163");
    ed1.add(Exiv2::ExifKey("Exif.Image.SamplesPerPixel"), v1.get());

    Exiv2::Value::AutoPtr v2 = Exiv2::Value::create(Exiv2::signedLong);
    v2->read("-2 -1 0 1");
    ed1.add(Exiv2::ExifKey("Exif.Image.XResolution"), v2.get());

    Exiv2::Value::AutoPtr v3 = Exiv2::Value::create(Exiv2::signedRational);
    v3->read("-2/3 -1/3 0/3 1/3");
    ed1.add(Exiv2::ExifKey("Exif.Image.YResolution"), v3.get());

    Exiv2::Value::AutoPtr v4 = Exiv2::Value::create(Exiv2::undefined);
    v4->read("255 254 253 252");
    ed1.add(Exiv2::ExifKey("Exif.Image.WhitePoint"), v4.get());

    write(file, ed1);
    print(file);

    std::cout <<"\n----- One Exif tag\n";
    Exiv2::ExifData ed2;
    ed2["Exif.Photo.DateTimeOriginal"] = "Test 2";
    write(file, ed2);
    print(file);

    std::cout <<"\n----- Canon MakerNote tags\n";
    Exiv2::ExifData edMn1;
    edMn1["Exif.Image.Make"]   = "Canon";
    edMn1["Exif.Image.Model"]  = "Canon PowerShot S40";
    edMn1["Exif.Canon.0xabcd"] = "A Canon makernote tag";
    edMn1["Exif.CanonCs.0x0002"] = uint16_t(41);
    edMn1["Exif.CanonSi.0x0005"] = uint16_t(42);
    edMn1["Exif.CanonCf.0x0001"] = uint16_t(43);
    edMn1["Exif.CanonPi.0x0001"] = uint16_t(44);
    edMn1["Exif.CanonPa.0x0001"] = uint16_t(45);
    write(file, edMn1);
    print(file);

    std::cout <<"\n----- Non-intrusive writing of special Canon MakerNote tags\n";
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
    assert(image.get() != 0);
    image->readMetadata();

    Exiv2::ExifData& rEd = image->exifData();
    rEd["Exif.CanonCs.0x0001"] = uint16_t(88);
    rEd["Exif.CanonSi.0x0004"] = uint16_t(99);
    image->writeMetadata();
    print(file);

    std::cout <<"\n----- One Fujifilm MakerNote tag\n";
    Exiv2::ExifData edMn2;
    edMn2["Exif.Image.Make"]      = "FUJIFILM";
    edMn2["Exif.Image.Model"]     = "FinePixS2Pro";
    edMn2["Exif.Fujifilm.0x1000"] = "A Fujifilm QUALITY tag";
    write(file, edMn2);
    print(file);

    std::cout <<"\n----- One Sigma/Foveon MakerNote tag\n";
    Exiv2::ExifData edMn3;
    edMn3["Exif.Image.Make"]   = "SIGMA";
    edMn3["Exif.Image.Model"]  = "SIGMA SD10";
    edMn3["Exif.Sigma.0x0018"] = "Software? Exiv2!";
    write(file, edMn3);
    print(file);

    std::cout <<"\n----- One Nikon1 MakerNote tag\n";
    Exiv2::ExifData edMn4;
    edMn4["Exif.Image.Make"]    = "NIKON";
    edMn4["Exif.Image.Model"]   = "E990";
    edMn4["Exif.Nikon1.0x0080"] = "ImageAdjustment by Exiv2";
    write(file, edMn4);
    print(file);

    std::cout <<"\n----- One Nikon2 MakerNote tag\n";
    Exiv2::ExifData edMn5;
    edMn5["Exif.Image.Make"]    = "NIKON";
    edMn5["Exif.Image.Model"]   = "E950";
    edMn5["Exif.Nikon2.0xffff"] = "An obscure Nikon2 tag";
    write(file, edMn5);
    print(file);

    std::cout <<"\n----- One Nikon3 MakerNote tag\n";
    Exiv2::ExifData edMn6;
    edMn6["Exif.Image.Make"]    = "NIKON CORPORATION";
    edMn6["Exif.Image.Model"]   = "NIKON D70";
    edMn6["Exif.Nikon3.0x0004"] = "A boring Nikon3 Quality tag";
    write(file, edMn6);
    print(file);

    std::cout <<"\n----- One Olympus MakerNote tag\n";
    Exiv2::ExifData edMn7;
    edMn7["Exif.Image.Make"]      = "OLYMPUS CORPORATION";
    edMn7["Exif.Image.Model"]     = "C8080WZ";
    edMn7["Exif.Olympus.0x0201"] = uint16_t(1);
    write(file, edMn7);
    print(file);

    std::cout <<"\n----- One Panasonic MakerNote tag\n";
    Exiv2::ExifData edMn8;
    edMn8["Exif.Image.Make"]      = "Panasonic";
    edMn8["Exif.Image.Model"]     = "DMC-FZ5";
    edMn8["Exif.Panasonic.0x0001"] = uint16_t(1);
    write(file, edMn8);
    print(file);

    std::cout <<"\n----- One Sony1 MakerNote tag\n";
    Exiv2::ExifData edMn9;
    edMn9["Exif.Image.Make"]      = "SONY";
    edMn9["Exif.Image.Model"]     = "DSC-W7";
    edMn9["Exif.Sony1.0x2000"] = "0 1 2 3 4 5";
    write(file, edMn9);
    print(file);

    std::cout <<"\n----- Minolta MakerNote tags\n";
    Exiv2::ExifData edMn10;
    edMn10["Exif.Image.Make"]   = "Minolta";
    edMn10["Exif.Image.Model"]  = "A fancy Minolta camera";
    edMn10["Exif.Minolta.ColorMode"] = uint32_t(1);
    edMn10["Exif.MinoltaCsNew.WhiteBalance"] = uint32_t(2);
    edMn10["Exif.MinoltaCs5D.WhiteBalance"] = uint16_t(3);
    edMn10["Exif.MinoltaCs5D.ColorTemperature"] = int16_t(-1);
    edMn10["Exif.MinoltaCs7D.WhiteBalance"] = uint16_t(4);
    edMn10["Exif.MinoltaCs7D.ExposureCompensation"] = int16_t(-2);
    edMn10["Exif.MinoltaCs7D.ColorTemperature"] = int16_t(-3);
    write(file, edMn10);
    print(file);

    std::cout <<"\n----- One IOP tag\n";
    Exiv2::ExifData ed3;
    ed3["Exif.Iop.InteroperabilityIndex"] = "Test 3";
    write(file, ed3);
    print(file);

    std::cout <<"\n----- One GPS tag\n";
    Exiv2::ExifData ed4;
    ed4["Exif.GPSInfo.GPSVersionID"] = "19 20";
    write(file, ed4);
    print(file);

    std::cout <<"\n----- One IFD1 tag\n";
    Exiv2::ExifData ed5;
    ed5["Exif.Thumbnail.Artist"] = "Test 5";
    write(file, ed5);
    print(file);

    std::cout <<"\n----- One IOP and one IFD1 tag\n";
    Exiv2::ExifData ed6;
    ed6["Exif.Iop.InteroperabilityIndex"] = "Test 6 Iop tag";
    ed6["Exif.Thumbnail.Artist"] = "Test 6 Ifd1 tag";
    write(file, ed6);
    print(file);

    std::cout <<"\n----- One IFD0 and one IFD1 tag\n";
    Exiv2::ExifData ed7;
    ed7["Exif.Thumbnail.Artist"] = "Test 7";
    Exiv2::Value::AutoPtr v5 = Exiv2::Value::create(Exiv2::unsignedShort);
    v5->read("160 161 162 163");
    ed7.add(Exiv2::ExifKey("Exif.Image.SamplesPerPixel"), v5.get());
    write(file, ed7);
    print(file);

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
}
Example #28
0
bool imread(std::string input_image_filename, matrix<float> &returnmatrix,
            Exiv2::ExifData &exifData, int highlights, bool caEnabled, bool lowQuality)
{
    //Create image processor for reading raws.
    LibRaw image_processor;

    //Open the file.
    const char *cstr = input_image_filename.c_str();
    if (0 != image_processor.open_file(cstr))
    {
        cerr << "imread: Could not read input file!" << endl;
        return true;
    }
     //Make abbreviations for brevity in accessing data.
#define SIZES image_processor.imgdata.sizes
#define PARAM image_processor.imgdata.params
#define IMAGE image_processor.imgdata.image
#define COLOR image_processor.imgdata.color

    //Now we'll set demosaic and other processing settings.
    PARAM.user_qual = 10;//9;//10 is AMaZE; -q[#] in dcraw
    PARAM.no_auto_bright = 1;//Don't autoadjust brightness (-W)
    PARAM.output_bps = 16;//16 bits per channel (-6)
    PARAM.gamm[0] = 1;
    PARAM.gamm[1] = 1;//Linear gamma (-g 1 1)
    PARAM.ca_correc = caEnabled;//Turn on CA auto correction
    PARAM.cared = 0;
    PARAM.cablue = 0;
    PARAM.output_color = 1;//1: Use sRGB regardless.
    PARAM.use_camera_wb = 1;//1: Use camera WB setting (-w)
    PARAM.highlight = highlights;//Set highlight recovery (-H #)
    PARAM.med_passes = 1;//median filter

    if (lowQuality)
    {
        //PARAM.half_size = 1;//half-size output, should dummy down demosaic.
        /* The above sometimes read out a dng thumbnail instead of the image itself. */
        PARAM.user_qual = 0;//nearest-neighbor demosaic
        PARAM.ca_correc = 0;//turn off auto CA correction.
    }

    //This makes IMAGE contains the sensel value and 3 blank values at every
    //location.
    image_processor.unpack();

    //This calls the dcraw processing on the raw sensel data.
    //Now, it contains 3 color values and one blank value at every location.
    //We will ignore the last blank value.
    image_processor.dcraw_process();

    long rSum = 0, gSum = 0, bSum = 0;
    returnmatrix.set_size(SIZES.iheight, SIZES.iwidth*3);
    for (int row = 0; row < SIZES.iheight; row++)
    {
        //IMAGE is an (width*height) by 4 array, not width by height by 4.
        int rowoffset = row*SIZES.iwidth;
        for (int col = 0; col < SIZES.iwidth; col++)
        {
            returnmatrix(row, col*3    ) = IMAGE[rowoffset + col][0];//R
            returnmatrix(row, col*3 + 1) = IMAGE[rowoffset + col][1];//G
            returnmatrix(row, col*3 + 2) = IMAGE[rowoffset + col][2];//B
            rSum += IMAGE[rowoffset + col][0];
            gSum += IMAGE[rowoffset + col][1];
            bSum += IMAGE[rowoffset + col][2];
        }
    }
    image_processor.recycle();
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(input_image_filename);
    assert(image.get() != 0);
    image->readMetadata();
    exifData = image->exifData();

    return false;
}
Example #29
0
void scan_exiv2(const class scanner_params &sp,const recursion_control_block &rcb)
{
    assert(sp.sp_version==scanner_params::CURRENT_SP_VERSION);
    if(sp.phase==scanner_params::PHASE_STARTUP){
        assert(sp.info->si_version==scanner_info::CURRENT_SI_VERSION);
	sp.info->name  = "exiv2";
        sp.info->author         = "Simson L. Garfinkel";
        sp.info->description    = "Searches for EXIF information using exiv2";
        sp.info->scanner_version= "1.0";
	sp.info->feature_names.insert("exif");
	sp.info->feature_names.insert("gps");
	sp.info->flags = scanner_info::SCANNER_DISABLED; // disabled because we have be_exif
	return;
    }
    if(sp.phase==scanner_params::PHASE_SHUTDOWN) return;
    if(sp.phase==scanner_params::PHASE_SCAN){

	const sbuf_t &sbuf = sp.sbuf;
	feature_recorder *exif_recorder = sp.fs.get_name("exif");
	feature_recorder *gps_recorder  = sp.fs.get_name("gps");

#ifdef HAVE_EXIV2__LOGMSG__SETLEVEL
	/* New form to suppress error messages on exiv2 */
	Exiv2::LogMsg::setLevel(Exiv2::LogMsg::mute);
#endif    

	size_t pos_max = 1;		// by default, just scan 1 byte
	if(sbuf.bufsize > min_exif_size){
	    pos_max = sbuf.bufsize - min_exif_size; //  we can scan more!
	}
    
	/* Loop through all possible locations in the buffer */
	for(size_t pos=0;pos<pos_max;pos++){
	    size_t count = exif_gulp_size;
	    count = min(count,sbuf.bufsize-pos);
	    //size_t count = sbuf.bufsize-pos; // use all to end

	    /* Explore the beginning of each 512-byte block as well as the starting location
	     * of any JPEG on any boundary. This will cause processing of any multimedia file
	     * that Exiv2 recognizes (for which I do not know all the headers.
	     */
	    if(pos%512==0 || jpeg_start(sbuf+pos)){
		try {
		    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(sbuf.buf+pos,count);
		    if(image->good()){
			image->readMetadata();
		    
			Exiv2::ExifData &exifData = image->exifData();
			if (exifData.empty()) continue;
		    
			/*
			 * Create the MD5 of the first 4K to use as a unique identifier.
			 */
			sbuf_t tohash(sbuf,0,4096);
			string md5_hex = exif_recorder->fs.hasher.func(tohash.buf,tohash.bufsize);

			char xmlbuf[1024];
			snprintf(xmlbuf,sizeof(xmlbuf),
				 "<exiv2><width>%d</width><height>%d</height>",
				 image->pixelWidth(),image->pixelHeight());

			/* Scan through the fields reported by exiv2.
			 * Create XML for each and extract GPS information if present.
			 */
			string photo_time;	// use this when gps_time is not available
			string gps_time;
			string gps_date;
			string gps_lat_ref;
			string gps_lat;
			string gps_lon_ref;
			string gps_lon;
			string gps_ele;
			string gps_speed;
			string gps_course;

                        bool has_gps = false;
                        bool has_gps_date = false;

			string xml = xmlbuf;
			for (Exiv2::ExifData::const_iterator i = exifData.begin();
			    i != exifData.end(); ++i) {

			    if(i->count()>1000) continue;	// ignore long ones

			    string key = string(i->key());
			    xml.append("<"+key+">"+dfxml_writer::xmlescape(i->value().toString())+"</"+key+">");

                            // use Date from Photo unless date from GPS is available
			    if(key=="Exif.Photo.DateTimeOriginal"){
				photo_time = i->value().toString();

				/* change "2011/06/25 12:20:11" to "2011-06-25 12:20:11" */
				std::transform(photo_time.begin(),photo_time.end(),photo_time.begin(),slash_to_dash);

				/* change "2011:06:25 12:20:11" to "2011-06-25 12:20:11" */
                                if (photo_time[4] == ':') {
                                    photo_time[4] = '-';
                                }
                                if (photo_time[7] == ':') {
                                    photo_time[7] = '-';
                                }

				/* Change "2011-06-25 12:20:11" to "2011-06-25T12:20:11" */
				size_t first_space = photo_time.find(' ');
				if(first_space!=string::npos) {
                                   photo_time.replace(first_space,1,"T");
                                }
			    } else if(key=="Exif.GPSInfo.GPSTimeStamp") {
                        	has_gps = true;
                                has_gps_date = true;
				gps_time = i->value().toString();
                                // reformat timestamp to standard ISO8601
                                // change "12 20 11" to "12:20:11"
                                if (gps_time.length() == 8) {
                                    if (gps_time[4] == ' ') {
                                        gps_time[4] = ':';
                                    }
                                    if (gps_time[7] == ' ') {
                                        gps_time[7] = ':';
                                    }
                                }
			    } else if(key=="Exif.GPSInfo.GPSDateStamp") {
                        	has_gps = true;
                                has_gps_date = true;
				gps_date = i->value().toString();
                                // reformat timestamp to standard ISO8601
                                // change "2011:06:25" to "2011-06-25"
                                if (gps_date.length() == 10) {
                                    if (gps_date[4] == ':') {
                                        gps_date[4] = '-';
                                    }
                                    if (gps_date[7] == ':') {
                                        gps_date[7] = '-';
                                    }
                                }

			    } else if(key=="Exif.GPSInfo.GPSLongitudeRef"){
                                has_gps = true;
				gps_lon_ref = fix_gps_ref(i->value().toString());
			    } else if(key=="Exif.GPSInfo.GPSLongitude"){
                                has_gps = true;
				gps_lon = fix_gps(i->value().toString());
			    } else if(key=="Exif.GPSInfo.GPSLatitudeRef"){
                                has_gps = true;
				gps_lat_ref = fix_gps_ref(i->value().toString());
			    } else if(key=="Exif.GPSInfo.GPSLatitude"){
                                has_gps = true;
				gps_lat = fix_gps(i->value().toString());
			    } else if(key=="Exif.GPSInfo.GPSAltitude"){
                                has_gps = true;
				gps_ele   = dtos(rational(i->value().toString()));
			    } else if(key=="Exif.GPSInfo.GPSSpeed"){
                                has_gps = true;
				gps_speed = dtos(rational(i->value().toString()));
			    } else if(key=="Exif.GPSInfo.GPSTrack"){
                                has_gps = true;
				gps_course = i->value().toString();
			    }
			}
			xml.append("</exiv2>");

                        // record EXIF
			exif_recorder->write(sp.sbuf.pos0+pos,md5_hex,xml);

                        // record GPS
                        if (has_gps) {
                            if (has_gps_date) {
                                // record the GPS entry using the GPS date
                                gps_recorder->write(sp.sbuf.pos0+pos,md5_hex,
					    gps_date+"T"+gps_time+","+gps_lat_ref+gps_lat+","
					    +gps_lon_ref+gps_lon+","
					    +gps_ele+","+gps_speed+","+gps_course);

                            } else {
                                // record the GPS entry using the date obtained from Photo
                                gps_recorder->write(sp.sbuf.pos0+pos,md5_hex,
					    photo_time+","+gps_lat_ref+gps_lat+","
					    +gps_lon_ref+gps_lon+","
					    +gps_ele+","+gps_speed+","+gps_course);
			    }
			}
		    }
		}
		catch (Exiv2::AnyError &e) { }
		catch (std::exception &e) { }
	    }
	}
    }
}
bool tag_location( const std::string &filename, const location &loc)
{
    bool result = false;
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open( filename);
    if (!image.get()) throw std::runtime_error( "could not open image file " + filename + " for metadata tags\n");
    image->readMetadata();
    Exiv2::ExifData data = image->exifData();

    if (data.findKey( Exiv2::ExifKey("Exif.GPSInfo.GPSLatitude")) == data.end())
    {
        add_exif_coordinate( data, "Exif.GPSInfo.GPSLatitude", std::abs( loc.latitude));
        add_exif_coordinate( data, "Exif.GPSInfo.GPSLongitude", std::abs( loc.longitude));
        data["Exif.GPSInfo.GPSLatitudeRef"] = loc.latitude < 0 ? "S":"N";
        data["Exif.GPSInfo.GPSLongitudeRef"] = loc.longitude < 0 ? "W":"E";
        Exiv2::byte version[] = { 2, 0, 0, 0};
        data["Exif.GPSInfo.GPSVersionID"].getValue()->read( version, 4, Exiv2::invalidByteOrder);
        image->setExifData( data);
        image->writeMetadata();
        result = true;
    }

    return result;
}