JPGRaster::GetExifThumbnail

git-svn-id: svn://ultimatepp.org/upp/trunk@1051 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-04-07 15:53:48 +00:00
parent b4aa7520fd
commit 89cab47f77
3 changed files with 58 additions and 1 deletions

View file

@ -1,7 +1,7 @@
#ifndef _plugin_jpg_icpp_init_stub
#define _plugin_jpg_icpp_init_stub
#include "Draw/init"
#define BLITZ_INDEX__ FCE5007ECA328A2C1D7B74D02BA609390
#define BLITZ_INDEX__ F6C2A6C6E2A707C9DA951CEB742219A6F
#include "jpgreg.icpp"
#undef BLITZ_INDEX__
#endif

View file

@ -23,6 +23,8 @@ public:
virtual const RasterFormat *GetFormat();
virtual Value GetMetaData(String id);
virtual void EnumMetaData(Vector<String>& id_list);
Image GetExifThumbnail();
};
class JPGEncoder : public StreamRasterEncoder {

View file

@ -192,6 +192,7 @@ public:
void ScanExifData(const char *begin);
Value GetMetaData(String id);
void EnumMetaData(Vector<String>& id_list);
String GetThumbnail();
private:
bool Init();
@ -212,6 +213,7 @@ private:
RGBA palette[256];
VectorMap<String, Value> metadata;
int thumboffset, thumblen;
struct jpeg_decompress_struct cinfo;
struct jpeg_longjmp_error_mgr jerr;
@ -371,6 +373,53 @@ void JPGRaster::Data::EnumMetaData(Vector<String>& id_list)
id_list <<= metadata.GetKeys();
}
String JPGRaster::Data::GetThumbnail()
{
ScanMetaData();
String app1 = GetMetaData("APP1");
if(!app1.GetCount())
return Null;
const char *begin = ~app1 + 6;
const char *end = app1.End();
const char *p = begin + Exif32(begin + 4);
if(p + 2 >= end) return Null;
p += Exif16(p) * 12 + 2;
if(p + 4 >= end) return Null;
p = begin + Exif32(p);
if(p <= begin || p + 2 >= end) return Null;
word count = Exif16(p);
p += 2;
dword offset = 0;
dword len = 0;
for(int n = 0; n < count; n++) {
if(p + 12 >= end) Null;
if(Exif32(p + 4) == 1) {
dword val = 0;
switch(Exif16(p + 2)) {
case 4:
case 9:
val = Exif32(p + 8);
break;
case 3:
case 8:
val = Exif16(p + 8);
break;
}
if(val)
switch(Exif16(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();
}
bool JPGRaster::Data::Init()
{
if(setjmp(jerr.jmpbuf))
@ -619,4 +668,10 @@ void JPGEncoder::WriteLineRaw(const byte *s)
data->WriteLineRaw(s);
}
Image JPGRaster::GetExifThumbnail()
{
ASSERT(data);
return StreamRaster::LoadStringAny(data->GetThumbnail());
}
END_UPP_NAMESPACE