cdcseacave / tinyexif Goto Github PK
View Code? Open in Web Editor NEWTiny ISO-compliant C++ EXIF and XMP parsing library for JPEG.
Tiny ISO-compliant C++ EXIF and XMP parsing library for JPEG.
The Readme leaves the impression, that this library does not depend on "third party dependencies", but it includes tinyxml2. It would be nice if that could be pointed out. Or you could just supply tinyxml2.cpp tinyxml2.h with the source.
It would be great to have a vector or set containing the names of the fields that were found when decoding the EXIF data.
Not having it is a problem since the fields have default values that could be valid and (I guess that) it is not possible to detect otherwise.
Another option is to use std::optional
on the fields, which may be better, but may break old implementations if/when they update TinyEXIF. Also, it requires C++17.
An example where this problem may arise is when 0
, despite being unknown, is a possible input value, and developers will not be able to distinguish between the unknown and the missing.
I just added a branch to my fork of this repository that apply the change above, but I'm unsure if I should create a pull request for it.
In the line:
0 == _tcsncmp(haystack, needle, needle_len))
You are using TCHAR-ized name of the strncmp()
function assuming that the project will always be compiled with multi-byte strings. This results in the compile error when the project is compiled with UNICODE support.
That's not the only place where this happens and frankly I don't see a point of using those names if the resst of the code uses std::string which is char *
, not wchar_t *
.
The example usage suggests to gulp up the entire 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);
This is impractical for large files - and many of us deal with very large images (like 360 panoramas easily exceeding 20MB). I have just spent ~2hrs studying JPEG format to assure myself APP1 segment can only live before the SOS and that - with way less confidence - that APP0 and APP1 must immediately follow SOI (which yields the max offset of 120kB instead of the whole image). Studying jpeg is precisely what tinyexif should relieve users from needing to do. It would be a massive favour if the authors, certainly knowledgeable in JPEG innards, have fixed the example usage with this subtlety in mind.
I want to read xmp data in tiff of Sequoia(ex. REDEDGE,NIR etc).
Are there plans to support tiff format?
I compile a DLL by setting TINYEXIF_EXPORT
macro, and upon linking to it with TINYEXIF_IMPORT
in another project I am getting a lot of C4251 warnings in the following form:
'TinyEXIF::EXIFInfo::ImageDescription': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TinyEXIF::EXIFInfo' (compiling source file ImageCodecJPEG.cpp)
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.23.28105\include\xstring(4440): message : see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' (compiling source file ImageCodecJPEG.cpp)
There seem to be two approaches to solving the problem:
class EXPORTED ExportedClass
{
private:
std::vector<int> *_integers;
public:
ExportedClass()
{
_integers = new std::vector<int>();
}
~ExportedClass()
{
delete _integers;
}
};
Hey
Inside parseString
, the arguments data
, and num_components
are entirely user controlled. They are added together with base
and used to check if we can safely read the contents of our string inside our given len
. The problem here is that both data
and num_components
are unsigned int
. This means if the user provides a big enough value for the first check, we can overflow the calculation:
static std::string parseString(const uint8_t* buf,
unsigned num_components,
unsigned data,
unsigned base,
unsigned len,
bool intel)
{
std::string value;
if (num_components <= 4) {
// ...
} else
// [1] Calculation here, data = 0xffffffff, num_components < len
if (base+data+num_components <= len) {
const char* const sz((const char*)buf+base+data);
unsigned num(0);
// [2] segfault when we check `sz[num] != '\0'`
while (num < num_components && sz[num] != '\0')
++num;
while (num && sz[num-1] == ' ')
--num;
// Copy `num` chars from `sz` into `value`.
value.assign(sz, num);
}
return value;
}
};
If, for example we set data
as 0xffffffff
, and then num_components
as a small value, the calculation will overflow and the result can be less than len
. Then when we pass this check, we add data
to our buf
pointer. In this case, sz
will now be pointing to unmapped memory owing to the addition of 0xffffffff
, and will cause a segfault when we try to dereference to check for null bytes.
To mitigate this, perhaps you could add a small check before [1]
to ensure it doesnt overflow.
Note that this doesnt have to be a segfault. With smaller values, this will alow us to read out of bounds on the heap, reading contents from other chunks and copying them into value
.
Thanks for your time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.