Port Iptc::printStructure & getUshort to slices API

This fixes #211, #210, #209
v0.27.3
Dan Čermák 7 years ago
parent fec6535ae8
commit 962962a8e9

@ -274,7 +274,7 @@ namespace Exiv2 {
/*!
@brief dump iptc formatted binary data (used by printStructure kpsRecursive)
*/
static void printStructure(std::ostream& out, const byte* bytes,const size_t size,uint32_t depth);
static void printStructure(std::ostream& out, const Slice<byte*>& bytes,uint32_t depth);
//@}
private:

@ -33,6 +33,7 @@
#include "config.h"
#include "slice.hpp"
#include "exiv2lib_export.h"
#include "slice.hpp"
// + standard includes
#include <string>
@ -296,6 +297,17 @@ namespace Exiv2 {
//! Read a 2 byte unsigned short value from the data buffer
EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte unsigned short value from a Slice
template <typename T>
uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
} else {
return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
}
}
//! Read a 4 byte unsigned long value from the data buffer
EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
//! Read a 8 byte unsigned long value from the data buffer

@ -4,6 +4,7 @@
#include <cassert>
#include <limits>
#include "safe_op.hpp"
#include "exif.hpp"
#include "error.hpp"
#include "image_int.hpp"
@ -355,13 +356,19 @@ namespace Exiv2
}
else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ )
{
const size_t restore = io.tell(); // save
io.seek(offset, BasicIo::beg); // position
byte* bytes=new byte[(size_t)count] ; // allocate memory
io.read(bytes,(long)count) ; // read
io.seek(restore, BasicIo::beg); // restore
IptcData::printStructure(out,bytes,(size_t)count,depth);
delete[] bytes; // free
if (Safe::add(count, offset) > io.size()) {
throw Error(kerCorruptedMetadata);
}
const size_t restore = io.tell();
io.seek(offset, BasicIo::beg); // position
std::vector<byte> bytes(count) ; // allocate memory
// TODO: once we have C++11 use bytes.data()
const long read_bytes = io.read(&bytes[0], static_cast<long>(count));
io.seek(restore, BasicIo::beg);
// TODO: once we have C++11 use bytes.data()
IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
}
else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10)
{

@ -28,6 +28,8 @@
#include "image_int.hpp"
#include "error.hpp"
#include "futils.hpp"
#include "safe_op.hpp"
#include "slice.hpp"
#include "cr2image.hpp"
#include "crwimage.hpp"
@ -454,19 +456,20 @@ namespace Exiv2 {
io.seek(restore,BasicIo::beg);
}
} else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {
if (offset > std::numeric_limits<uint32_t>::max() - count) {
throw Error(kerArithmeticOverflow);
}
if (static_cast<size_t>(offset + count) > io.size()) {
if (static_cast<size_t>(Safe::add(count, offset)) > io.size()) {
throw Error(kerCorruptedMetadata);
}
size_t restore = io.tell(); // save
io.seek(offset,BasicIo::beg); // position
byte* bytes=new byte[count] ; // allocate memory
io.read(bytes,count) ; // read
io.seek(restore,BasicIo::beg); // restore
IptcData::printStructure(out,bytes,count,depth);
delete[] bytes; // free
const size_t restore = io.tell();
io.seek(offset, BasicIo::beg); // position
std::vector<byte> bytes(count) ; // allocate memory
// TODO: once we have C++11 use bytes.data()
const long read_bytes = io.read(&bytes[0], count);
io.seek(restore, BasicIo::beg);
// TODO: once we have C++11 use bytes.data()
IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
} else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
size_t restore = io.tell(); // save

@ -347,21 +347,21 @@ namespace Exiv2 {
return iptcMetadata_.erase(pos);
}
void IptcData::printStructure(std::ostream& out, const byte* bytes, const size_t size, uint32_t depth)
void IptcData::printStructure(std::ostream& out, const Slice<byte*>& bytes, uint32_t depth)
{
uint32_t i = 0;
while (i < size - 3 && bytes[i] != 0x1c)
while (i < bytes.size() - 3 && bytes.at(i) != 0x1c)
i++;
depth++;
out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl;
while (i < size - 3) {
if (bytes[i] != 0x1c) {
while (i < bytes.size() - 3) {
if (bytes.at(i) != 0x1c) {
break;
}
char buff[100];
uint16_t record = bytes[i + 1];
uint16_t dataset = bytes[i + 2];
uint16_t len = getUShort(bytes + i + 3, bigEndian);
uint16_t record = bytes.at(i + 1);
uint16_t dataset = bytes.at(i + 2);
uint16_t len = getUShort(bytes.subSlice(i + 3, bytes.size()), bigEndian);
sprintf(buff, " %6d | %7d | %-24s | %6d | ", record, dataset,
Exiv2::IptcDataSets::dataSetName(dataset, record).c_str(), len);

@ -576,7 +576,7 @@ namespace Exiv2
if(bIsIPTC && bRecursive)
{
IptcData::printStructure(out,rawData.pData_,rawData.size_,depth);
IptcData::printStructure(out, makeSlice(rawData.pData_, 0, rawData.size_), depth);
}
if( bIsXMP && bXMP )

@ -637,7 +637,7 @@ namespace Exiv2 {
throw Error(kerFailedToReadImageData);
if (bufRead < 2)
throw Error(kerNotAJpeg);
uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
const uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
if (bPrint && mHasLength[marker])
out << Internal::stringFormat(" | %7d ", size);
@ -780,7 +780,7 @@ namespace Exiv2 {
}
if (bPS) {
IptcData::printStructure(out, exif, size, depth);
IptcData::printStructure(out, makeSlice(exif, 0, size), depth);
} else {
// create a copy on write memio object with the data, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(exif + start, size - start));

@ -356,7 +356,7 @@ namespace Exiv2 {
printTiffStructure(*p,out,option,depth);
}
if ( bIptc ) {
IptcData::printStructure(out,parsedBuf.pData_,parsedBuf.size_,depth);
IptcData::printStructure(out, makeSlice(parsedBuf.pData_, 0, parsedBuf.size_), depth);
}
}
}

@ -276,12 +276,7 @@ namespace Exiv2 {
uint16_t getUShort(const byte* buf, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
return (byte)buf[1] << 8 | (byte)buf[0];
}
else {
return (byte)buf[0] << 8 | (byte)buf[1];
}
return getUShort(makeSliceUntil(buf, 2), byteOrder);
}
uint32_t getULong(const byte* buf, ByteOrder byteOrder)

Loading…
Cancel
Save