Add constructor that takes generic std::istream objects (#11)
This commit is contained in:
11
README.md
11
README.md
@@ -18,16 +18,11 @@ int main(int argc, const char** argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read entire image file
|
// open a stream to read just the necessary parts of the image file
|
||||||
std::ifstream file(argv[1], std::ifstream::in|std::ifstream::binary);
|
std::ifstream istream(argv[1], std::ifstream::binary);
|
||||||
file.seekg(0,std::ios::end);
|
|
||||||
std::streampos length = file.tellg();
|
|
||||||
file.seekg(0,std::ios::beg);
|
|
||||||
std::vector<uint8_t> data(length);
|
|
||||||
file.read((char*)data.data(), length);
|
|
||||||
|
|
||||||
// parse image EXIF and XMP metadata
|
// parse image EXIF and XMP metadata
|
||||||
TinyEXIF::EXIFInfo imageEXIF(data.data(), length);
|
TinyEXIF::EXIFInfo imageEXIF(istream);
|
||||||
if (imageEXIF.Fields)
|
if (imageEXIF.Fields)
|
||||||
std::cout
|
std::cout
|
||||||
<< "Image Description " << imageEXIF.ImageDescription << "\n"
|
<< "Image Description " << imageEXIF.ImageDescription << "\n"
|
||||||
|
|||||||
34
TinyEXIF.cpp
34
TinyEXIF.cpp
@@ -43,6 +43,7 @@
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
namespace {
|
namespace {
|
||||||
@@ -338,6 +339,9 @@ EXIFInfo::EXIFInfo() : Fields(FIELD_NA) {
|
|||||||
EXIFInfo::EXIFInfo(EXIFStream& stream) {
|
EXIFInfo::EXIFInfo(EXIFStream& stream) {
|
||||||
parseFrom(stream);
|
parseFrom(stream);
|
||||||
}
|
}
|
||||||
|
EXIFInfo::EXIFInfo(std::istream& stream) {
|
||||||
|
parseFrom(stream);
|
||||||
|
}
|
||||||
EXIFInfo::EXIFInfo(const uint8_t* data, unsigned length) {
|
EXIFInfo::EXIFInfo(const uint8_t* data, unsigned length) {
|
||||||
parseFrom(data, length);
|
parseFrom(data, length);
|
||||||
}
|
}
|
||||||
@@ -848,6 +852,36 @@ int EXIFInfo::parseFrom(EXIFStream& stream) {
|
|||||||
return app1s();
|
return app1s();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int EXIFInfo::parseFrom(std::istream& stream) {
|
||||||
|
class EXIFStdStream : public EXIFStream {
|
||||||
|
public:
|
||||||
|
EXIFStdStream(std::istream& stream)
|
||||||
|
: stream(stream) {
|
||||||
|
// Would be nice to assert here that the stream was opened in binary mode, but
|
||||||
|
// apparently that's not possible: https://stackoverflow.com/a/224259/19254
|
||||||
|
}
|
||||||
|
bool IsValid() const override {
|
||||||
|
return !!stream;
|
||||||
|
}
|
||||||
|
const uint8_t* GetBuffer(unsigned desiredLength) override {
|
||||||
|
buffer.resize(desiredLength);
|
||||||
|
if (!stream.read(reinterpret_cast<char*>(buffer.data()), desiredLength))
|
||||||
|
return NULL;
|
||||||
|
return buffer.data();
|
||||||
|
}
|
||||||
|
bool SkipBuffer(unsigned desiredLength) override {
|
||||||
|
return (bool)stream.seekg(desiredLength, std::ios::cur);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::istream& stream;
|
||||||
|
std::vector<uint8_t> buffer;
|
||||||
|
};
|
||||||
|
EXIFStdStream streamWrapper(stream);
|
||||||
|
return parseFrom(streamWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int EXIFInfo::parseFrom(const uint8_t* buf, unsigned len) {
|
int EXIFInfo::parseFrom(const uint8_t* buf, unsigned len) {
|
||||||
class EXIFStreamBuffer : public EXIFStream {
|
class EXIFStreamBuffer : public EXIFStream {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ class TINYEXIF_LIB EXIFInfo {
|
|||||||
public:
|
public:
|
||||||
EXIFInfo();
|
EXIFInfo();
|
||||||
EXIFInfo(EXIFStream& stream);
|
EXIFInfo(EXIFStream& stream);
|
||||||
|
EXIFInfo(std::istream& stream); // NB: the stream must have been opened in binary mode
|
||||||
EXIFInfo(const uint8_t* data, unsigned length);
|
EXIFInfo(const uint8_t* data, unsigned length);
|
||||||
|
|
||||||
// Parsing function for an entire JPEG image stream.
|
// Parsing function for an entire JPEG image stream.
|
||||||
@@ -110,6 +111,7 @@ public:
|
|||||||
// RETURN: PARSE_SUCCESS (0) on success with 'result' filled out
|
// RETURN: PARSE_SUCCESS (0) on success with 'result' filled out
|
||||||
// error code otherwise, as defined by the PARSE_* macros
|
// error code otherwise, as defined by the PARSE_* macros
|
||||||
int parseFrom(EXIFStream& stream);
|
int parseFrom(EXIFStream& stream);
|
||||||
|
int parseFrom(std::istream& stream); // NB: the stream must have been opened in binary mode
|
||||||
int parseFrom(const uint8_t* data, unsigned length);
|
int parseFrom(const uint8_t* data, unsigned length);
|
||||||
|
|
||||||
// Parsing function for an EXIF segment. This is used internally by parseFrom()
|
// Parsing function for an EXIF segment. This is used internally by parseFrom()
|
||||||
|
|||||||
27
main.cpp
27
main.cpp
@@ -9,27 +9,6 @@
|
|||||||
#include <vector> // std::vector
|
#include <vector> // std::vector
|
||||||
#include <iomanip> // std::setprecision
|
#include <iomanip> // std::setprecision
|
||||||
|
|
||||||
class EXIFStreamFile : public TinyEXIF::EXIFStream {
|
|
||||||
public:
|
|
||||||
explicit EXIFStreamFile(const char* fileName)
|
|
||||||
: file(fileName, std::ifstream::in|std::ifstream::binary) {}
|
|
||||||
bool IsValid() const override {
|
|
||||||
return file.is_open();
|
|
||||||
}
|
|
||||||
const uint8_t* GetBuffer(unsigned desiredLength) override {
|
|
||||||
buffer.resize(desiredLength);
|
|
||||||
if (!file.read((char*)buffer.data(), desiredLength))
|
|
||||||
return NULL;
|
|
||||||
return buffer.data();
|
|
||||||
}
|
|
||||||
bool SkipBuffer(unsigned desiredLength) override {
|
|
||||||
return (bool)file.seekg(desiredLength,std::ios::cur);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
std::ifstream file;
|
|
||||||
std::vector<uint8_t> buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
@@ -37,9 +16,9 @@ int main(int argc, const char** argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read entire image file
|
// open a stream to read just the necessary parts of the image file
|
||||||
EXIFStreamFile stream(argv[1]);
|
std::ifstream stream(argv[1], std::ios::binary);
|
||||||
if (!stream.IsValid()) {
|
if (!stream) {
|
||||||
std::cout << "error: can not open '" << argv[1] << "'\n";
|
std::cout << "error: can not open '" << argv[1] << "'\n";
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user