예제 #1
0
QString MetaEngine::Private::convertCommentValue(const Exiv2::Exifdatum& exifDatum) const
{
    try
    {
        std::string comment;
        std::string charset;

        comment = exifDatum.toString();

        // libexiv2 will prepend "charset=\"SomeCharset\" " if charset is specified
        // Before conversion to QString, we must know the charset, so we stay with std::string for a while
        if (comment.length() > 8 && comment.substr(0, 8) == "charset=")
        {
            // the prepended charset specification is followed by a blank
            std::string::size_type pos = comment.find_first_of(' ');

            if (pos != std::string::npos)
            {
                // extract string between the = and the blank
                charset = comment.substr(8, pos-8);
                // get the rest of the string after the charset specification
                comment = comment.substr(pos+1);
            }
        }

        if (charset == "\"Unicode\"")
        {
            return QString::fromUtf8(comment.data());
        }
        else if (charset == "\"Jis\"")
        {
            QTextCodec* const codec = QTextCodec::codecForName("JIS7");
            return codec->toUnicode(comment.c_str());
        }
        else if (charset == "\"Ascii\"")
        {
            return QString::fromLatin1(comment.c_str());
        }
        else
        {
            return detectEncodingAndDecode(comment);
        }
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError(QString::fromLatin1("Cannot convert Comment using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
    }

    return QString();
}
예제 #2
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.
}
예제 #3
0
 //! Returns true if IFD id matches.
 bool operator()(const Exiv2::Exifdatum& md) const { return ifdId_ == md.ifdId(); }