Beispiel #1
0
void XMPMetadataSource::saveSchema(const MetaString& schemaName, const MetadataStream& stream)
{
    shared_ptr<MetadataSchema> thisSchemaDescription = stream.getSchema(schemaName);

    MetaString thisSchemaPath = findSchema(schemaName);

    if (thisSchemaPath.empty())
    {
        xmp->AppendArrayItem(VMF_NS, VMF_GLOBAL_SCHEMAS_ARRAY, kXMP_PropValueIsArray, NULL, kXMP_PropValueIsStruct);
        SXMPUtils::ComposeArrayItemPath(VMF_NS, VMF_GLOBAL_SCHEMAS_ARRAY, kXMP_ArrayLastItem, &thisSchemaPath);
        xmp->SetStructField(VMF_NS, thisSchemaPath.c_str(), VMF_NS, SCHEMA_NAME, schemaName);
        xmp->SetStructField(VMF_NS, thisSchemaPath.c_str(), VMF_NS, SCHEMA_SET, nullptr, kXMP_PropValueIsArray);
    }

    MetadataSet thisSchemaSet = stream.queryBySchema(schemaName);
    vector< shared_ptr<MetadataDesc> > thisSchemaProperties = thisSchemaDescription->getAll();
    for(auto descIter = thisSchemaProperties.begin(); descIter != thisSchemaProperties.end(); ++descIter)
    {
        MetaString metadataName = (*descIter)->getMetadataName();
        MetadataSet currentPropertySet(thisSchemaSet.queryByName(metadataName));
        saveProperty(currentPropertySet, thisSchemaPath, metadataName);
    }
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    initialize();

    string appPath = argv[0];
#ifdef WIN32
    char delim = '\\';
#else
    char delim = '/';
#endif
    size_t pos = appPath.find_last_of(delim);

    if (pos != string::npos)
    {
        workingPath = appPath.substr(0, pos + 1);
    }

    // Copy test video file to another location.
    copyFile(VIDEO_FILE, "global_test.avi");

    cout << "VMF sample: read/write GPS location and time" << endl << endl;

    const string FILE_NAME = "global_test.avi";
    const string META_SOURCE_NAME = "test-id";
    const string GPS_DESC = "gps";
    const string GPS_COORD_FIELD = "GPS";
    const string GPS_TIME_FIELD = "Time";
    const string GPS_SCHEMA_NAME = "gps_schema";
    const string GPS_METADATA_ITEM1 = "lat=53.78,lng=132.46";
    const string GPS_METADATA_ITEM2 = "lat=53.28,lng=131.87";
    const string GPS_METADATA_ITEM3 = "lat=52.95,lng=131.41";
    const string GPS_METADATA_ITEM4 = "lat=52.49,lng=130.98";

    cout << "Adding metadata..." << endl;
    cout << "Opening file name '" << FILE_NAME << "'" << endl;

    // Open metadata stream
    MetadataStream mdStream;
    if (!mdStream.open(FILE_NAME, MetadataStream::ReadWrite))
    {
        cerr << "Can't open file " << FILE_NAME << endl;
        exit(1);
    }

    // Create a GPS metadata field descriptions
    vector<FieldDesc> fieldDesc;

    fieldDesc.push_back(FieldDesc(GPS_COORD_FIELD)); // GPS coordinate as string
    fieldDesc.push_back(FieldDesc(GPS_TIME_FIELD)); // Associated time as string

    // Create GPS metadata description
    shared_ptr<MetadataDesc> gpsDesc(new MetadataDesc(GPS_DESC, fieldDesc));

    // Create GPS metadata schema
    shared_ptr<MetadataSchema> gpsSchema(new MetadataSchema(GPS_SCHEMA_NAME));

    // Add description to the schema
    gpsSchema->add(gpsDesc);

    string t = "21.02.2013 18:35";
    cout << "Add metadata schema '" << GPS_SCHEMA_NAME << "'" << endl;

    // Add schema to metadata stream
    mdStream.addSchema(gpsSchema);

    shared_ptr<Metadata> gpsMetadata;

    t = "21.02.2013 18:45";
    cout << "Adding metadata's item '" << GPS_METADATA_ITEM1 << "' with associated time " << t << endl;

    // Create a metadata item
    gpsMetadata = shared_ptr<Metadata>(new Metadata(gpsDesc));

    // Fill item fields
    gpsMetadata->push_back(FieldValue(GPS_COORD_FIELD, GPS_METADATA_ITEM1));
    gpsMetadata->push_back(FieldValue(GPS_TIME_FIELD, t));

    // Add to metadata a new item
    mdStream.add(gpsMetadata);

    t = "21.02.2013 19:28";
    cout << "Adding metadata's item '" << GPS_METADATA_ITEM2 << "' with associated time " << t << endl;

    gpsMetadata = shared_ptr<Metadata>(new Metadata(gpsDesc));
    gpsMetadata->push_back(FieldValue(GPS_COORD_FIELD, GPS_METADATA_ITEM2));
    gpsMetadata->push_back(FieldValue(GPS_TIME_FIELD, t));
    mdStream.add(gpsMetadata);

    t = "21.02.2013 21:02";
    cout << "Adding metadata's item '" << GPS_METADATA_ITEM3 << "' with associated time " << t << endl;

    gpsMetadata = shared_ptr<Metadata>(new Metadata(gpsDesc));
    gpsMetadata->push_back(FieldValue(GPS_COORD_FIELD, GPS_METADATA_ITEM3));
    gpsMetadata->push_back(FieldValue(GPS_TIME_FIELD, t));
    mdStream.add(gpsMetadata);

    t = "21.02.2013 23:19";
    cout << "Adding metadata's item '" << GPS_METADATA_ITEM4 << "' with associated time " << t << endl;

    gpsMetadata = shared_ptr<Metadata>(new Metadata(gpsDesc));
    gpsMetadata->push_back(FieldValue(GPS_COORD_FIELD, GPS_METADATA_ITEM4));
    gpsMetadata->push_back(FieldValue(GPS_TIME_FIELD, t));
    mdStream.add(gpsMetadata);

    cout << "Save metadata" << endl << endl;

    // Save metadata to video file and close metadata stream
    mdStream.save();
    mdStream.close();

    cout << "Loading metadata..." << endl;
    cout << "Opening file name '" << FILE_NAME << "'" << endl;

    // Open new metadata stream to load and print saved metadata
    MetadataStream loadStream;
    if (!loadStream.open(FILE_NAME, MetadataStream::ReadOnly))
    {
        cerr << "Can't open file " << FILE_NAME << endl;
        exit(1);
    }

    cout << "Loading schema '" << GPS_SCHEMA_NAME << "'" << endl;
    if (!loadStream.load(GPS_SCHEMA_NAME))
    {
        cerr << "Can't load schema " << GPS_SCHEMA_NAME << endl;
        exit(1);
    }

    // Select all metadata items from loaded schema
    auto dataSet = loadStream.queryBySchema(GPS_SCHEMA_NAME);

    // and print them to console
    for (size_t i = 0; i < dataSet.size(); i++)
    {
        cout << "Getting item " << i << endl;
        auto metadataItem = dataSet[i];

        string coord = metadataItem->getFieldValue(GPS_COORD_FIELD);
        cout << "\tGPS coordinates are: " << coord << endl;

        string time = metadataItem->getFieldValue(GPS_TIME_FIELD);
        cout << "\tAssociated time is: " << time << endl;
    }

    // Close metadata stream
    loadStream.close();

    // Uninitialize VMF library to free allocated resources
    vmf::terminate();

    return 0;
}
Beispiel #3
0
void XMPDataSource::loadXMPstructs()
{
    std::shared_ptr<SXMPMeta> tmpXMP = make_shared<SXMPMeta>();
    xmpFile.GetXMP(tmpXMP.get());

    std::shared_ptr<XMPMetadataSource> tmpMetaSource;
    std::shared_ptr<XMPSchemaSource> tmpSchemaSource;
    std::shared_ptr<XMPStatSource> tmpStatSource;
    tmpSchemaSource = make_shared<XMPSchemaSource>(tmpXMP);
    tmpMetaSource = make_shared<XMPMetadataSource>(tmpXMP);
    tmpStatSource = make_shared<XMPStatSource>(tmpXMP);
    if(!tmpMetaSource || !tmpSchemaSource || !tmpStatSource)
    {
        VMF_EXCEPTION(DataStorageException, "Failed to create metadata source or schema source");
    }

    //load standard VMF metadata and decompress them if there is a corresponding schema
    //or pass them further
    try
    {
        //load standard VMF metadata and decrypt them if there is a corresponding schema
        //or pass them further
        std::map<vmf_string, std::shared_ptr<MetadataSchema> > eSchemas;
        tmpSchemaSource->load(eSchemas);
        auto itEncryption = eSchemas.find(ENCRYPTED_DATA_SCHEMA_NAME);
        if(itEncryption != eSchemas.end())
        {
            MetadataStream eStream;
            eStream.addSchema(itEncryption->second);
            tmpMetaSource->loadSchema(ENCRYPTED_DATA_SCHEMA_NAME, eStream);
            MetadataSet eSet = eStream.queryBySchema(ENCRYPTED_DATA_SCHEMA_NAME);
            std::shared_ptr<Metadata> eItem = eSet[0];
            vmf_string hint      = eItem->getFieldValue(ENCRYPTION_HINT_PROP_NAME);
            vmf_string encodedB64 = eItem->getFieldValue(ENCRYPTED_DATA_PROP_NAME);
            bool ignoreBad = (openMode & MetadataStream::OpenModeFlags::IgnoreUnknownEncryptor) != 0;
            if(!encryptor)
            {
                if(!ignoreBad)
                {
                    VMF_EXCEPTION(IncorrectParamException,
                                  "No decryption algorithm provided for encrypted data");
                }
            }
            else
            {
                string decodedFromB64;
                XMPUtils::DecodeFromBase64(encodedB64.data(), encodedB64.length(), &decodedFromB64);
                vmf_rawbuffer encrypted(decodedFromB64.c_str(), decodedFromB64.size());
                string theData;
                try
                {
                    encryptor->decrypt(encrypted, theData);
                }
                catch(Exception& ee)
                {
                    //if we've failed with decryption (whatever the reason was)
                    //and we're allowed to ignore that
                    if(!ignoreBad)
                    {
                        string message = "Decryption failed: " + string(ee.what()) + ", hint: " + hint;
                        VMF_EXCEPTION(IncorrectParamException, message);
                    }
                }
                //replace tmp XMP entities
                tmpXMP->ParseFromBuffer(theData.c_str(), theData.size(), 0);
                tmpSchemaSource = make_shared<XMPSchemaSource>(tmpXMP);
                tmpMetaSource = make_shared<XMPMetadataSource>(tmpXMP);
                tmpStatSource = make_shared<XMPStatSource>(tmpXMP);
                if(!tmpMetaSource || !tmpSchemaSource || !tmpStatSource)
                {
                    VMF_EXCEPTION(DataStorageException,
                                  "Failed to create metadata source, schema source or stat source");
                }
            }
        }

        //load standard VMF metadata and decompress them if there is a corresponding schema
        //or pass them further
        std::map<vmf_string, std::shared_ptr<MetadataSchema> > cSchemas;
        tmpSchemaSource->load(cSchemas);
        auto itCompression = cSchemas.find(COMPRESSED_DATA_SCHEMA_NAME);
        if(itCompression != cSchemas.end())
        {
            MetadataStream cStream;
            cStream.addSchema(itCompression->second);
            tmpMetaSource->loadSchema(COMPRESSED_DATA_SCHEMA_NAME, cStream);
            MetadataSet cSet = cStream.queryBySchema(COMPRESSED_DATA_SCHEMA_NAME);
            std::shared_ptr<Metadata> cItem = cSet[0];
            vmf_string algo    = cItem->getFieldValue(COMPRESSION_ALGO_PROP_NAME);
            vmf_string encoded = cItem->getFieldValue(COMPRESSED_DATA_PROP_NAME);
            bool ignoreBad = (openMode & MetadataStream::OpenModeFlags::IgnoreUnknownCompressor) != 0;
            try
            {
                std::shared_ptr<Compressor> decompressor = Compressor::create(algo);
                string decoded;
                XMPUtils::DecodeFromBase64(encoded.data(), encoded.length(), &decoded);
                vmf_rawbuffer compressed(decoded.c_str(), decoded.size());
                string theData;
                decompressor->decompress(compressed, theData);
                //replace tmp XMP entities
                tmpXMP->ParseFromBuffer(theData.c_str(), theData.size(), 0);
                tmpSchemaSource = make_shared<XMPSchemaSource>(tmpXMP);
                tmpMetaSource = make_shared<XMPMetadataSource>(tmpXMP);
                tmpStatSource = make_shared<XMPStatSource>(tmpXMP);
                if(!tmpMetaSource || !tmpSchemaSource || !tmpStatSource)
                {
                    VMF_EXCEPTION(DataStorageException,
                                  "Failed to create metadata source, schema source or stat source");
                }
            }
            catch(IncorrectParamException& ce)
            {
                //if there's no such compressor and we're allowed to ignore that
                if(!ignoreBad)
                {
                    VMF_EXCEPTION(IncorrectParamException, ce.what());
                }
            }
            catch(InternalErrorException& ce)
            {
                //if there was an error during decompression
                if(!ignoreBad)
                {
                    VMF_EXCEPTION(IncorrectParamException, ce.what());
                }
            }
        }
    }
    catch(const XMP_Error& e)
    {
        VMF_EXCEPTION(DataStorageException, e.GetErrMsg());
    }
    catch(const std::exception& e)
    {
        VMF_EXCEPTION(DataStorageException, e.what());
    }

    xmp = tmpXMP;
    schemaSource = tmpSchemaSource;
    metadataSource = tmpMetaSource;
    statSource = tmpStatSource;
}