#1271 Thanks to Ben for reporting this and providing the patch.

v0.27.3
Robin Mills 8 years ago
parent 2d3386bb42
commit 11993b3b55

@ -79,6 +79,7 @@ namespace Exiv2 {
//! @name Manipulators //! @name Manipulators
//@{ //@{
void printStructure(std::ostream& out, PrintStructureOption option,int depth);
void readMetadata(); void readMetadata();
void writeMetadata(); void writeMetadata();
/*! /*!

@ -78,6 +78,7 @@ namespace Exiv2 {
//! @name Manipulators //! @name Manipulators
//@{ //@{
void printStructure(std::ostream& out, PrintStructureOption option,int depth);
void readMetadata(); void readMetadata();
/*! /*!
@brief Todo: Write metadata back to the image. This method is not @brief Todo: Write metadata back to the image. This method is not

@ -71,6 +71,7 @@ namespace Exiv2 {
//! @name Manipulators //! @name Manipulators
//@{ //@{
void printStructure(std::ostream& out, PrintStructureOption option,int depth);
void readMetadata(); void readMetadata();
void writeMetadata(); void writeMetadata();
//@} //@}
@ -185,9 +186,14 @@ namespace Exiv2 {
RiffVideo(const RiffVideo& rhs); RiffVideo(const RiffVideo& rhs);
//! Assignment operator //! Assignment operator
RiffVideo& operator=(const RiffVideo& rhs); RiffVideo& operator=(const RiffVideo& rhs);
bool equalsRiffTag(Exiv2::DataBuf& buf ,const char* str);
//@} //@}
private: private:
const static int RIFF_TAG_SIZE;
const static char* RIFF_CHUNK_HEADER_ICCP;
const static char* RIFF_CHUNK_HEADER_EXIF;
const static char* RIFF_CHUNK_HEADER_XMP;
//! Variable to check the end of metadata traversing. //! Variable to check the end of metadata traversing.
bool continueTraversing_; bool continueTraversing_;
//! Variable which stores current stream being processsed. //! Variable which stores current stream being processsed.

@ -76,6 +76,7 @@ namespace Exiv2 {
//! @name Manipulators //! @name Manipulators
//@{ //@{
void printStructure(std::ostream& out, PrintStructureOption option,int depth);
void readMetadata(); void readMetadata();
/*! /*!
@brief Todo: Write metadata back to the image. This method is not @brief Todo: Write metadata back to the image. This method is not

@ -107,6 +107,8 @@ namespace Exiv2 {
throw Error(3, "CR2"); throw Error(3, "CR2");
} }
clearMetadata(); clearMetadata();
std::ofstream devnull;
printStructure(devnull, kpsRecursive, 0);
ByteOrder bo = Cr2Parser::decode(exifData_, ByteOrder bo = Cr2Parser::decode(exifData_,
iptcData_, iptcData_,
xmpData_, xmpData_,

@ -89,6 +89,21 @@ namespace Exiv2 {
throw(Error(32, "Image comment", "ORF")); throw(Error(32, "Image comment", "ORF"));
} }
void OrfImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
std::cout << "ORF IMAGE" << std::endl;
if (io_->open() != 0) throw Error(9, io_->path(), strError());
// Ensure that this is the correct image type
if ( imageType() == ImageType::none )
if (!isOrfType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(15);
}
io_->seek(0,BasicIo::beg);
printTiffStructure(io(),out,option,depth-1);
} // OrfImage::printStructure
void OrfImage::readMetadata() void OrfImage::readMetadata()
{ {
#ifdef DEBUG #ifdef DEBUG
@ -104,6 +119,8 @@ namespace Exiv2 {
throw Error(3, "ORF"); throw Error(3, "ORF");
} }
clearMetadata(); clearMetadata();
std::ofstream devnull;
printStructure(devnull, kpsRecursive, 0);
ByteOrder bo = OrfParser::decode(exifData_, ByteOrder bo = OrfParser::decode(exifData_,
iptcData_, iptcData_,
xmpData_, xmpData_,

@ -34,6 +34,7 @@ EXIV2_RCSID("@(#) $Id$")
#include "rafimage.hpp" #include "rafimage.hpp"
#include "tiffimage.hpp" #include "tiffimage.hpp"
#include "image_int.hpp"
#include "image.hpp" #include "image.hpp"
#include "basicio.hpp" #include "basicio.hpp"
#include "error.hpp" #include "error.hpp"
@ -95,6 +96,189 @@ namespace Exiv2 {
throw(Error(32, "Image comment", "RAF")); throw(Error(32, "Image comment", "RAF"));
} }
void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
if (io_->open() != 0) {
throw Error(9, io_->path(), strError());
}
// Ensure this is the correct image type
if (!isRafType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "RAF");
}
bool bPrint = option==kpsBasic || option==kpsRecursive;
if ( bPrint ) {
io_->seek(0,BasicIo::beg); // rewind
if ( bPrint ) {
out << Internal::indent(depth)
<< "STRUCTURE OF RAF FILE: "
<< io().path()
<< std::endl;
out << Internal::indent(depth)
<< Internal::stringFormat(" Length | Offset | Payload")
<< std::endl;
}
byte magicdata [17];
io_->read(magicdata, 16);
magicdata[16] = 0;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 16, 0)
<< "Magic number : "
<< std::string((char*)&magicdata)
<< std::endl;
}
byte data1 [5];
io_->read(data1, 4);
data1[4] = 0;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 16)
<< "data 1 : "
<< std::string((char*)&data1)
<< std::endl;
}
byte data2 [9];
io_->read(data2, 8);
data2[8] = 0;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 8, 20)
<< "data 2 : "
<< std::string((char*)&data2)
<< std::endl;
}
byte camdata [33];
io_->read(camdata, 32);
camdata[32] = 0;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 32, 28)
<< "camera : "
<< std::string((char*)&camdata)
<< std::endl;
}
byte dir_version [5];
io_->read(dir_version, 4);
dir_version[4] = 0;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 60)
<< "dir version : "
<< std::string((char*)&dir_version)
<< std::endl;
}
byte unknown [20];
io_->read(unknown, 20);
byte jpg_img_offset [4];
io_->read(jpg_img_offset, 4);
byte jpg_img_length [4];
io_->read(jpg_img_length, 4);
long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
std::stringstream j_off;
std::stringstream j_len;
j_off << jpg_img_off;
j_len << jpg_img_len;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 84)
<< "JPEG Image Offset : "
<< j_off.str()
<< std::endl;
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 88)
<< "JPEG Image Length : "
<< j_len.str()
<< std::endl;
}
byte cfa_header_offset [4];
io_->read(cfa_header_offset, 4);
byte cfa_header_length [4];
io_->read(cfa_header_length, 4);
long cfa_hdr_off = Exiv2::getULong((const byte *) cfa_header_offset, bigEndian);
long cfa_hdr_len = Exiv2::getULong((const byte *) cfa_header_length, bigEndian);
std::stringstream ch_off;
std::stringstream ch_len;
ch_off << cfa_hdr_off;
ch_len << cfa_hdr_len;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 92)
<< "CFA Header Offset : "
<< ch_off.str()
<< std::endl;
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 96)
<< "CFA Header Length : "
<< ch_len.str()
<< std::endl;
}
byte cfa_offset [4];
io_->read(cfa_offset, 4);
byte cfa_length [4];
io_->read(cfa_length, 4);
long cfa_off = Exiv2::getULong((const byte *) cfa_offset, bigEndian);
long cfa_len = Exiv2::getULong((const byte *) cfa_length, bigEndian);
std::stringstream c_off;
std::stringstream c_len;
c_off << cfa_off;
c_len << cfa_len;
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 100)
<< "CFA Offset : "
<< c_off.str()
<< std::endl;
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", 4, 104)
<< "CFA Length : "
<< c_len.str()
<< std::endl;
}
io_->seek(jpg_img_off, BasicIo::beg); // rewind
DataBuf payload(16); // header is different from chunks
io_->read(payload.pData_, payload.size_);
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", jpg_img_len, jpg_img_off)
<< "jpg image / exif : "
<< Internal::binaryToString(payload, payload.size_)
<< std::endl;
}
io_->seek(cfa_hdr_off, BasicIo::beg); // rewind
io_->read(payload.pData_, payload.size_);
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", cfa_hdr_len, cfa_hdr_off)
<< "CFA Header: "
<< Internal::binaryToString(payload, payload.size_)
<< std::endl;
}
io_->seek(cfa_off, BasicIo::beg); // rewind
io_->read(payload.pData_, payload.size_);
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %8u | %8u | ", cfa_len, cfa_off)
<< "CFA : "
<< Internal::binaryToString(payload, payload.size_)
<< std::endl;
}
}
} // RafImage::printStructure
void RafImage::readMetadata() void RafImage::readMetadata()
{ {
#ifdef DEBUG #ifdef DEBUG
@ -107,20 +291,32 @@ namespace Exiv2 {
if (io_->error() || io_->eof()) throw Error(14); if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "RAF"); throw Error(3, "RAF");
} }
byte const* pData = io_->mmap();
long size = io_->size();
if (size < 88 + 4) throw Error(14); // includes the test for -1
uint32_t const start = getULong(pData + 84, bigEndian) + 12;
if (static_cast<uint32_t>(size) < start) throw Error(14);
clearMetadata(); clearMetadata();
io_->seek(84,BasicIo::beg);
byte jpg_img_offset [4];
io_->read(jpg_img_offset, 4);
byte jpg_img_length [4];
io_->read(jpg_img_length, 4);
long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
DataBuf buf(jpg_img_len - 12);
io_->seek(jpg_img_off + 12,BasicIo::beg);
io_->read(buf.pData_, buf.size_ - 12);
if (io_->error() || io_->eof()) throw Error(14);
io_->seek(0,BasicIo::beg); // rewind
ByteOrder bo = TiffParser::decode(exifData_, ByteOrder bo = TiffParser::decode(exifData_,
iptcData_, iptcData_,
xmpData_, xmpData_,
pData + start, buf.pData_,
size - start); buf.size_);
exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(pData + 84, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian);
exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(pData + 88, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian);
setByteOrder(bo); setByteOrder(bo);
} // RafImage::readMetadata } // RafImage::readMetadata

@ -41,6 +41,7 @@ EXIV2_RCSID("@(#) $Id$")
#include "tags_int.hpp" #include "tags_int.hpp"
#include "types.hpp" #include "types.hpp"
#include "tiffimage_int.hpp" #include "tiffimage_int.hpp"
#include "image_int.hpp"
// + standard includes // + standard includes
#include <cmath> #include <cmath>
@ -516,6 +517,88 @@ namespace Exiv2 {
return "video/riff"; return "video/riff";
} }
const int RiffVideo::RIFF_TAG_SIZE = 0x4;
const char* RiffVideo::RIFF_CHUNK_HEADER_ICCP = "ICCP";
const char* RiffVideo::RIFF_CHUNK_HEADER_EXIF = "EXIF";
const char* RiffVideo::RIFF_CHUNK_HEADER_XMP = "XMP ";
/*!
@brief Function used to check equality of a Tags with a
particular string (ignores case while comparing).
@param buf Data buffer that will contain Tag to compare
@param str char* Pointer to string
@return Returns true if the buffer value is equal to string.
*/
bool RiffVideo::equalsRiffTag(Exiv2::DataBuf& buf, const char* str) {
for(int i = 0; i < 4; i++ )
if(toupper(buf.pData_[i]) != str[i])
return false;
return true;
}
void RiffVideo::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
if (io_->open() != 0) {
throw Error(9, io_->path(), strError());
}
// Ensure this is the correct image type
if (!isRiffType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "RIFF");
}
bool bPrint = option==kpsBasic || option==kpsRecursive;
if ( bPrint || option == kpsXMP || option == kpsIccProfile || option == kpsIptcErase ) {
byte data [RIFF_TAG_SIZE * 2];
io_->read(data, RIFF_TAG_SIZE * 2);
uint64_t filesize = Exiv2::getULong(data + RIFF_TAG_SIZE, littleEndian);
DataBuf chunkId(5) ;
chunkId.pData_[4] = '\0' ;
if ( bPrint ) {
out << Internal::indent(depth)
<< "STRUCTURE OF RIFF FILE: "
<< io().path()
<< std::endl;
out << Internal::indent(depth)
<< Internal::stringFormat(" Chunk | Length | Offset | Payload")
<< std::endl;
}
io_->seek(0,BasicIo::beg); // rewind
while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
uint64_t offset = (uint64_t) io_->tell();
byte size_buff[RIFF_TAG_SIZE];
io_->read(chunkId.pData_, RIFF_TAG_SIZE);
io_->read(size_buff, RIFF_TAG_SIZE);
long size = Exiv2::getULong(size_buff, littleEndian);
DataBuf payload(offset?size:RIFF_TAG_SIZE); // header is different from chunks
io_->read(payload.pData_, payload.size_);
if ( bPrint ) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %s | %12u | %12u | ", (const char*)chunkId.pData_,size,(uint32_t)offset)
<< Internal::binaryToString(payload,payload.size_>32?32:payload.size_)
<< std::endl;
}
if ( equalsRiffTag(chunkId, RIFF_CHUNK_HEADER_EXIF) && option==kpsRecursive ) {
// create memio object with the payload, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(payload.pData_,payload.size_));
printTiffStructure(*p,out,option,depth);
}
bool bPrintPayload = (equalsRiffTag(chunkId, RIFF_CHUNK_HEADER_XMP) && option==kpsXMP)
|| (equalsRiffTag(chunkId, RIFF_CHUNK_HEADER_ICCP) && option==kpsIccProfile)
;
if ( bPrintPayload ) {
out.write((const char*) payload.pData_,payload.size_);
}
if ( offset && io_->tell() % 2 ) io_->seek(+1, BasicIo::cur); // skip padding byte on sub-chunks
}
}
} // RiffVideo::printStructure
void RiffVideo::writeMetadata() void RiffVideo::writeMetadata()
{ {
} // RiffVideo::writeMetadata } // RiffVideo::writeMetadata

@ -100,6 +100,21 @@ namespace Exiv2 {
throw(Error(32, "Image comment", "RW2")); throw(Error(32, "Image comment", "RW2"));
} }
void Rw2Image::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
std::cout << "RW2 IMAGE" << std::endl;
if (io_->open() != 0) throw Error(9, io_->path(), strError());
// Ensure that this is the correct image type
if ( imageType() == ImageType::none )
if (!isRw2Type(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(15);
}
io_->seek(0,BasicIo::beg);
printTiffStructure(io(),out,option,depth-1);
} // Rw2Image::printStructure
void Rw2Image::readMetadata() void Rw2Image::readMetadata()
{ {
#ifdef DEBUG #ifdef DEBUG
@ -115,6 +130,8 @@ namespace Exiv2 {
throw Error(3, "RW2"); throw Error(3, "RW2");
} }
clearMetadata(); clearMetadata();
std::ofstream devnull;
printStructure(devnull, kpsRecursive, 0);
ByteOrder bo = Rw2Parser::decode(exifData_, ByteOrder bo = Rw2Parser::decode(exifData_,
iptcData_, iptcData_,
xmpData_, xmpData_,

@ -412,8 +412,9 @@ namespace Exiv2 {
void WebPImage::printStructure(std::ostream& out, PrintStructureOption option,int depth) void WebPImage::printStructure(std::ostream& out, PrintStructureOption option,int depth)
{ {
if (io_->open() != 0) throw Error(9, io_->path(), strError()); if (io_->open() != 0) {
IoCloser closer(*io_); throw Error(9, io_->path(), strError());
}
// Ensure this is the correct image type // Ensure this is the correct image type
if (!isWebPType(*io_, true)) { if (!isWebPType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(14); if (io_->error() || io_->eof()) throw Error(14);

Loading…
Cancel
Save