Example #1
0
static void set_xmp_prop(const char * filename, const std::string & value_name, 
			 const std::string & prop_value,
			 bool no_reconcile, bool is_an_xmp, bool write_in_place, FILE *outio)
{
	xmp::ScopedPtr<XmpPtr> xmp(get_xmp_from_file(filename, no_reconcile, is_an_xmp));
	
	std::string prefix;
	size_t idx = value_name.find(':');
	if(idx != std::string::npos) {
		prefix = std::string(value_name, 0, idx);
	}

	xmp::ScopedPtr<XmpStringPtr> ns(xmp_string_new());
	xmp_prefix_namespace_uri(prefix.c_str(), ns);
	if(!xmp_set_property(xmp, xmp_string_cstr(ns), value_name.c_str() + idx + 1, prop_value.c_str(), 0)) {
		fprintf(stderr, "set error = %d\n", xmp_get_error());
	}

	if(write_in_place) {
		xmp::ScopedPtr<XmpFilePtr> f(xmp_files_open_new(filename, 
						(XmpOpenFileOptions)(XMP_OPEN_FORUPDATE 
							| (no_reconcile ? XMP_OPEN_ONLYXMP : 0))));
	
		if(!xmp_files_can_put_xmp(f, xmp)) {
			fprintf(stderr, "can put xmp error = %d\n", xmp_get_error());		 				
		}
		if(!xmp_files_put_xmp(f, xmp)) {
			fprintf(stderr, "put xmp error = %d\n", xmp_get_error());		 	
		}
		if(!xmp_files_close(f, XMP_CLOSE_SAFEUPDATE)) {
			fprintf(stderr, "close error = %d\n", xmp_get_error());
		}
	}		
}
Example #2
0
/** dump the XMP xml to the output IO */
static void dump_xmp(const char *filename, bool no_reconcile, 
		     bool is_an_xmp, FILE *outio)
{
	printf("dump_xmp for file %s\n", filename);
	xmp::ScopedPtr<XmpPtr> xmp(get_xmp_from_file(filename, no_reconcile, is_an_xmp));
	
	xmp::ScopedPtr<XmpStringPtr> output(xmp_string_new());

	xmp_serialize_and_format(xmp, output, 
							 XMP_SERIAL_OMITPACKETWRAPPER, 
							 0, "\n", " ", 0);
							 
	fprintf(outio, "%s", xmp_string_cstr(output));
}
Example #3
0
/** get an xmp prop and dump it to the output IO */
static void get_xmp_prop(const char * filename, const std::string & value_name, bool no_reconcile, bool is_an_xmp, FILE *outio)
{
	xmp::ScopedPtr<XmpPtr> xmp(get_xmp_from_file(filename, no_reconcile, is_an_xmp));
		
	std::string prefix;
	size_t idx = value_name.find(':');
	if(idx != std::string::npos) {
		prefix = std::string(value_name, 0, idx);
	}
			
	xmp::ScopedPtr<XmpStringPtr> property(xmp_string_new());
	xmp::ScopedPtr<XmpStringPtr> ns(xmp_string_new());
	xmp_prefix_namespace_uri(prefix.c_str(), ns);
	xmp_get_property(xmp, xmp_string_cstr(ns), value_name.c_str(), property, NULL);
	fprintf(outio, "%s\n", xmp_string_cstr(property));
}
Example #4
0
    void Jp2Image::doWriteMetadata(BasicIo& outIo)
    {
        if (!io_->isopen()) throw Error(20);
        if (!outIo.isopen()) throw Error(21);

#ifdef DEBUG
        std::cout << "Exiv2::Jp2Image::doWriteMetadata: Writing JPEG-2000 file " << io_->path() << "\n";
        std::cout << "Exiv2::Jp2Image::doWriteMetadata: tmp file created " << outIo.path() << "\n";
#endif

        // Ensure that this is the correct image type
        if (!isJp2Type(*io_, true))
        {
            if (io_->error() || io_->eof()) throw Error(20);
            throw Error(22);
        }

        // Write JPEG2000 Signature.
        if (outIo.write(Jp2Signature, 12) != 12) throw Error(21);

        Jp2BoxHeader box = {0,0};

        byte    boxDataSize[4];
        byte    boxUUIDtype[4];
        DataBuf bheaderBuf(8);     // Box header : 4 bytes (data size) + 4 bytes (box type).

        // FIXME: Andreas, why the loop do not stop when EOF is taken from _io. The loop go out by an exception
        // generated by a zero size data read.

        while(io_->tell() < io_->size())
        {
#ifdef DEBUG
            std::cout << "Exiv2::Jp2Image::doWriteMetadata: Position: " << io_->tell() << " / " << io_->size() << "\n";
#endif

            // Read chunk header.

            std::memset(bheaderBuf.pData_, 0x00, bheaderBuf.size_);
            long bufRead = io_->read(bheaderBuf.pData_, bheaderBuf.size_);
            if (io_->error()) throw Error(14);
            if (bufRead != bheaderBuf.size_) throw Error(20);

            // Decode box header.

            box.boxLength = getLong(bheaderBuf.pData_,     bigEndian);
            box.boxType   = getLong(bheaderBuf.pData_ + 4, bigEndian);

#ifdef DEBUG
            std::cout << "Exiv2::Jp2Image::doWriteMetadata: Find box type: " << bheaderBuf.pData_ + 4
                      << " lenght: " << box.boxLength << "\n";
#endif

            if (box.boxLength == 0)
            {
#ifdef DEBUG
                std::cout << "Exiv2::Jp2Image::doWriteMetadata: Null Box size has been found. "
                             "This is the last box of file.\n";
#endif
                box.boxLength = io_->size() - io_->tell() + 8;
            }
            if (box.boxLength == 1)
            {
                // FIXME. Special case. the real box size is given in another place.
            }

            // Read whole box : Box header + Box data (not fixed size - can be null).

            DataBuf boxBuf(box.boxLength);                             // Box header (8 bytes) + box data.
            memcpy(boxBuf.pData_, bheaderBuf.pData_, 8);               // Copy header.
            bufRead = io_->read(boxBuf.pData_ + 8, box.boxLength - 8); // Extract box data.
            if (io_->error())
            {
#ifdef DEBUG
                std::cout << "Exiv2::Jp2Image::doWriteMetadata: Error reading source file\n";
#endif

                throw Error(14);
            }

            if (bufRead != (long)(box.boxLength - 8))
            {
#ifdef DEBUG
                std::cout << "Exiv2::Jp2Image::doWriteMetadata: Cannot read source file data\n";
#endif
                throw Error(20);
            }

            switch(box.boxType)
            {
                case kJp2BoxTypeJp2Header:
                {

#ifdef DEBUG
                    std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (lenght: " << box.boxLength << ")\n";
#endif
                    if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(21);

                    // Write all updated metadata here, just after JP2Header.

                    if (exifData_.count() > 0)
                    {
                        // Update Exif data to a new UUID box

                        Blob blob;
                        ExifParser::encode(blob, littleEndian, exifData_);
                        if (blob.size())
                        {
                            const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};

                            DataBuf rawExif(static_cast<long>(sizeof(ExifHeader) + blob.size()));
                            memcpy(rawExif.pData_, ExifHeader, sizeof(ExifHeader));
                            memcpy(rawExif.pData_ + sizeof(ExifHeader), &blob[0], blob.size());

                            DataBuf boxData(8 + 16 + rawExif.size_);
                            ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian);
                            ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
                            memcpy(boxData.pData_,          boxDataSize,    4);
                            memcpy(boxData.pData_ + 4,      boxUUIDtype,    4);
                            memcpy(boxData.pData_ + 8,      kJp2UuidExif,   16);
                            memcpy(boxData.pData_ + 8 + 16, rawExif.pData_, rawExif.size_);

#ifdef DEBUG
                            std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (lenght: "
                                      << boxData.size_ << ")\n";
#endif
                            if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(21);
                        }
                    }

                    if (iptcData_.count() > 0)
                    {
                        // Update Iptc data to a new UUID box

                        DataBuf rawIptc = IptcParser::encode(iptcData_);
                        if (rawIptc.size_ > 0)
                        {
                            DataBuf boxData(8 + 16 + rawIptc.size_);
                            ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian);
                            ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
                            memcpy(boxData.pData_,          boxDataSize,    4);
                            memcpy(boxData.pData_ + 4,      boxUUIDtype,    4);
                            memcpy(boxData.pData_ + 8,      kJp2UuidIptc,   16);
                            memcpy(boxData.pData_ + 8 + 16, rawIptc.pData_, rawIptc.size_);

#ifdef DEBUG
                            std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (lenght: "
                                      << boxData.size_ << ")\n";
#endif
                            if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(21);
                        }
                    }

                    if (writeXmpFromPacket() == false)
                    {
                        if (XmpParser::encode(xmpPacket_, xmpData_) > 1)
                        {
#ifndef SUPPRESS_WARNINGS
                            EXV_ERROR << "Failed to encode XMP metadata.\n";
#endif
                        }
                    }
                    if (xmpPacket_.size() > 0)
                    {
                        // Update Xmp data to a new UUID box

                        DataBuf xmp(reinterpret_cast<const byte*>(xmpPacket_.data()), static_cast<long>(xmpPacket_.size()));
                        DataBuf boxData(8 + 16 + xmp.size_);
                        ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian);
                        ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
                        memcpy(boxData.pData_,          boxDataSize,  4);
                        memcpy(boxData.pData_ + 4,      boxUUIDtype,  4);
                        memcpy(boxData.pData_ + 8,      kJp2UuidXmp,  16);
                        memcpy(boxData.pData_ + 8 + 16, xmp.pData_,   xmp.size_);

#ifdef DEBUG
                        std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (lenght: "
                                  << boxData.size_ << ")\n";
#endif
                        if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(21);
                    }

                    break;
                }

                case kJp2BoxTypeUuid:
                {
                    if(memcmp(boxBuf.pData_ + 8, kJp2UuidExif, sizeof(16)) == 0)
                    {
#ifdef DEBUG
                        std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Exif Uuid box\n";
#endif
                    }
                    else if(memcmp(boxBuf.pData_ + 8, kJp2UuidIptc, sizeof(16)) == 0)
                    {
#ifdef DEBUG
                        std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Iptc Uuid box\n";
#endif
                    }
                    else if(memcmp(boxBuf.pData_ + 8, kJp2UuidXmp,  sizeof(16)) == 0)
                    {
#ifdef DEBUG
                        std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Xmp Uuid box\n";
#endif
                    }
                    else
                    {
#ifdef DEBUG
                        std::cout << "Exiv2::Jp2Image::doWriteMetadata: write Uuid box (lenght: " << box.boxLength << ")\n";
#endif
                        if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(21);
                    }
                    break;
                }

                default:
                {
#ifdef DEBUG
                    std::cout << "Exiv2::Jp2Image::doWriteMetadata: write box (lenght: " << box.boxLength << ")\n";
#endif
                    if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(21);

                    break;
                }
            }
        }

#ifdef DEBUG
        std::cout << "Exiv2::Jp2Image::doWriteMetadata: EOF\n";
#endif

    } // Jp2Image::doWriteMetadata