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;
|
||||
}
|
||||
|
||||
// read entire image file
|
||||
std::ifstream file(argv[1], std::ifstream::in|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);
|
||||
// open a stream to read just the necessary parts of the image file
|
||||
std::ifstream istream(argv[1], std::ifstream::binary);
|
||||
|
||||
// parse image EXIF and XMP metadata
|
||||
TinyEXIF::EXIFInfo imageEXIF(data.data(), length);
|
||||
TinyEXIF::EXIFInfo imageEXIF(istream);
|
||||
if (imageEXIF.Fields)
|
||||
std::cout
|
||||
<< "Image Description " << imageEXIF.ImageDescription << "\n"
|
||||
|
||||
34
TinyEXIF.cpp
34
TinyEXIF.cpp
@@ -43,6 +43,7 @@
|
||||
#include <cfloat>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
namespace {
|
||||
@@ -338,6 +339,9 @@ EXIFInfo::EXIFInfo() : Fields(FIELD_NA) {
|
||||
EXIFInfo::EXIFInfo(EXIFStream& stream) {
|
||||
parseFrom(stream);
|
||||
}
|
||||
EXIFInfo::EXIFInfo(std::istream& stream) {
|
||||
parseFrom(stream);
|
||||
}
|
||||
EXIFInfo::EXIFInfo(const uint8_t* data, unsigned length) {
|
||||
parseFrom(data, length);
|
||||
}
|
||||
@@ -848,6 +852,36 @@ int EXIFInfo::parseFrom(EXIFStream& stream) {
|
||||
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) {
|
||||
class EXIFStreamBuffer : public EXIFStream {
|
||||
public:
|
||||
|
||||
@@ -100,6 +100,7 @@ class TINYEXIF_LIB EXIFInfo {
|
||||
public:
|
||||
EXIFInfo();
|
||||
EXIFInfo(EXIFStream& stream);
|
||||
EXIFInfo(std::istream& stream); // NB: the stream must have been opened in binary mode
|
||||
EXIFInfo(const uint8_t* data, unsigned length);
|
||||
|
||||
// Parsing function for an entire JPEG image stream.
|
||||
@@ -110,6 +111,7 @@ public:
|
||||
// RETURN: PARSE_SUCCESS (0) on success with 'result' filled out
|
||||
// error code otherwise, as defined by the PARSE_* macros
|
||||
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);
|
||||
|
||||
// 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 <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)
|
||||
{
|
||||
if (argc != 2) {
|
||||
@@ -37,9 +16,9 @@ int main(int argc, const char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read entire image file
|
||||
EXIFStreamFile stream(argv[1]);
|
||||
if (!stream.IsValid()) {
|
||||
// open a stream to read just the necessary parts of the image file
|
||||
std::ifstream stream(argv[1], std::ios::binary);
|
||||
if (!stream) {
|
||||
std::cout << "error: can not open '" << argv[1] << "'\n";
|
||||
return -2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user