Example #1
0
static void EraseGpsTags(Exiv2::ExifData &ExifInfo)
{
	// Search through, find the keys that we want, and wipe them
	// Code below submitted by Marc Horowitz
	Exiv2::ExifData::iterator Iter;
	for (Exiv2::ExifData::iterator Iter = ExifInfo.begin();
		Iter != ExifInfo.end(); )
	{
		if (Iter->key().find("Exif.GPSInfo") == 0)
			Iter = ExifInfo.erase(Iter);
		else
			Iter++;
	}
}
Example #2
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 #3
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;
}