mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 06:06:00 -06:00
76 lines
1.7 KiB
C++
76 lines
1.7 KiB
C++
|
|
struct ExifReader {
|
|
String app1;
|
|
bool le;
|
|
|
|
const byte *Begin() const { return (const byte *)~app1 + 6; }
|
|
const byte *End() const { return (const byte *)app1.End(); }
|
|
operator bool() const { return app1.GetCount(); }
|
|
|
|
uint32 Peek32(const byte *ptr) const { return (le ? Peek32le : Peek32be)(ptr); }
|
|
uint16 Peek16(const byte *ptr) const { return (le ? Peek16le : Peek16be)(ptr); }
|
|
|
|
String GetThumbnail() const;
|
|
|
|
ExifReader(const String& app1);
|
|
};
|
|
|
|
ExifReader::ExifReader(const String& q)
|
|
{
|
|
app1 = q;
|
|
if(app1.GetCount() > 30 && memcmp(~app1, "ExifReader", 4) == 0)
|
|
if(app1[6] == 'I')
|
|
le = true;
|
|
else
|
|
if(app1[6] == 'M')
|
|
le = false;
|
|
else
|
|
app1.Clear();
|
|
else
|
|
app1.Clear();
|
|
}
|
|
|
|
String ExifReader::GetThumbnail() const
|
|
{
|
|
if(!app1.GetCount())
|
|
return Null;
|
|
const byte *begin = Begin();
|
|
const byte *end = End();
|
|
const byte *p = begin + Peek32(begin + 4);
|
|
if(p + 2 >= end) return Null;
|
|
p += Peek16(p) * 12 + 2;
|
|
if(p + 4 >= end) return Null;
|
|
p = begin + Peek32(p);
|
|
if(p <= begin || p + 2 >= end) return Null;
|
|
word count = Peek16(p);
|
|
p += 2;
|
|
dword offset = 0;
|
|
dword len = 0;
|
|
for(int n = 0; n < count; n++) {
|
|
if(p + 12 >= end) Null;
|
|
if(Peek32(p + 4) == 1) {
|
|
dword val = 0;
|
|
switch(Peek16(p + 2)) {
|
|
case 4:
|
|
case 9:
|
|
val = Peek32(p + 8);
|
|
break;
|
|
case 3:
|
|
case 8:
|
|
val = Peek16(p + 8);
|
|
break;
|
|
}
|
|
if(val)
|
|
switch(Peek16(p)) {
|
|
case 0x201:
|
|
offset = val;
|
|
break;
|
|
case 0x202:
|
|
len = val;
|
|
break;
|
|
}
|
|
}
|
|
p += 12;
|
|
}
|
|
return offset && len && begin + offset + len < end ? String(begin + offset, len) : String();
|
|
}
|