1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
/*
/--------------------------------------------------------------------
|
| $Id: plexif.h,v 1.5 2004/06/06 12:56:38 uzadow Exp $
|
| Copyright (c) 1996-2003 Ulrich von Zadow
|
| Implementation of PLExif class by Mike Franklin
| Much of the decoding code was adapted from code by Ken Reneris:
| http://www.reneris.com/tools/exif.asp -
| though it has been heavily modified!
|
|
\--------------------------------------------------------------------
*/
#ifndef INCL_PLEXIF
#define INCL_PLEXIF
#ifdef _MSC_VER // The microsoft compiler generates masses
// of symbol too long
#pragma warning(disable: 4786) // for debugger warnings for sets and maps
#endif
#include "plpaintlibdefs.h"
#include "plcountedpointer.h"
#include <cstdio>
#include <vector>
#include <string>
#include <map>
struct jpeg_decompress_struct;
struct jpeg_compress_struct;
// these structures are for internal use only
struct _PLExifTranslator;
struct _PLExifTagValues;
struct _PLExifFormatter;
class PLExifTag;
typedef PLCountedPointer<PLExifTag> PLExifTagCPtr; // PLExifTag counted pointer
typedef std::vector<PLExifTagCPtr> PLExifTagList; // vector of PLExifTag counted pointers
typedef PLCountedArrayPointer<PLBYTE> PLByteCPtr; // utility typedef
class PLExif
{
public:
PLExif();
~PLExif();
// default copying is safe
// reset the internal data
void Clear();
// Access the raw EXIF data (just a copy of the EXIF header held in memory)
size_t GetRawDataSize() const;
PLBYTE * GetRawData();
const PLBYTE * GetRawData() const;
/*
// These are not EXIF comments and should probably be moved to PLBmpInfo
const std::string & GetComment() const;
const char * GetCommmentCStr() const;
void SetComment(const std::string &);
void SetComment(const char *);
*/
// Access to the Main, Sub and Manufacturer tags
// also a single list that contains them all
const PLExifTagList & GetAllTags() const;
const PLExifTagList & GetMainTags() const;
const PLExifTagList & GetSubTags() const;
const PLExifTagList & GetManufacturerTags() const;
// As above but returning a traditional C style array pointer
// instead of an STL vector
// It is an array of pointers to PLExifTag
const PLExifTagCPtr * GetAllTagsC(size_t & size) const;
const PLExifTagCPtr * GetMainTagsC(size_t & size) const;
const PLExifTagCPtr * GetSubTagsC(size_t & size) const;
const PLExifTagCPtr * GetManufacturerTagsC(size_t & size) const;
// All the following functions give access to a tag given a tag shortname
// they almost all return a pointer to the whole tag but mostly this
// will just be used to check whether the tag was found by testing for
// a NULL pointer. The useful data - the tag value is generally returned
// by reference.
//
// duplicate copies of the functions allow efficient use whether
// the source tag string is a std::string or a char *
// All forms return a pointer to the found tag, 0 if not found
// Just return the tag pointer
PLExifTag * GetTag(const char * TagShortName) const;
PLExifTag * GetTag(const std::string & TagShortName) const
{ return GetTag(TagShortName.c_str()); }
// place the tag value into the Value string, format is basic
// as stored in the raw EXIF data eg f4.0 is likely to be 40/10
PLExifTag * GetTag(const char * TagShortName, std::string & Value) const;
PLExifTag * GetTag(const std::string & TagShortName, std::string & Value) const
{ return GetTag(TagShortName.c_str(), Value); }
// place the tag value in the Value string, format is common form
// eg f4.0 is 4.0 rather than 40/10
PLExifTag * GetTagCommon(const char * TagShortName, std::string & Value) const;
PLExifTag * GetTagCommon(const std::string & TagShortName, std::string & Value) const
{ return GetTagCommon(TagShortName.c_str(), Value); }
// place the tag value in the Value double where appropriate
// eg 1.234m focus
PLExifTag * GetTag(const char * TagShortName, double & Value) const;
PLExifTag * GetTag(const std::string & TagShortName, double & Value) const
{ return GetTag(TagShortName.c_str(), Value); }
// return tag value as a string (empty string if not found), format is basic
// as stored in the raw EXIF data eg f4.0 is likely to be 40/10
std::string & TagStr(const char * TagShortName) const;
std::string & TagStr(const std::string & TagShortName) const
{ return TagStr(TagShortName.c_str()); }
// return tag value as a string (empty string if not found)
// format is common form eg f4.0 is 4.0 rather than 40/10
std::string & TagStrCommon(const char * TagShortName) const;
std::string & TagStrCommon(const std::string & TagShortName) const
{ return TagStrCommon(TagShortName.c_str()); }
// C string return versions of TagStr and TagStrCommon
// return tag value as a string (empty string if not found), format is basic
// as stored in the raw EXIF data eg f4.0 is likely to be 40/10
const char * TagCStr(const char * TagShortName) const;
const char * TagCStr(const std::string & TagShortName) const
{ return TagCStr(TagShortName.c_str()); }
// return tag value as a string (empty string if not found)
// format is common form eg f4.0 is 4.0 rather than 40/10
const char * TagCStrCommon(const char * TagShortName) const;
const char * TagCStrCommon(const std::string & TagShortName) const
{ return TagCStrCommon(TagShortName.c_str()); }
// These two methods are primarily intended for use only by the Paintlib encoders and decoders
// load data from cinfo - jpeg_save_markers must have been called first
void ReadData(const jpeg_decompress_struct * pcinfo);
// write data to cinfo - after jpeg_start_compress
void WriteData(jpeg_compress_struct * pcinfo);
private:
void decode(); // do the actual decoding of the EXIF data
void ReadIFD(const _PLExifTagValues * Tags, char * Prefix, PLExifTagList & sectionList);
void ExpandBinaryTag(const std::string & Src, const _PLExifTagValues *Tags, PLUINT Type, PLExifTagList & sectionList);
void DecodeCanCustomFncs(const PLExifTag & rootTag, const _PLExifTagValues *Tags, PLExifTagList & sectionList);
void CopyTag(const char * Src, const char * Dst);
void SetTag(const char * Dst, const char * Value);
void SetTag(const char * Dst, const std::string & Value)
{ SetTag(Dst, Value.c_str()); }
void AddTag(const char * Dst, const char * SrcTag, const char * Skip = NULL, const char * Sep = NULL);
void AddStr(const char * Dst, const std::string & SrcStr, const char * Skip = NULL, const char * Sep = NULL);
void FormatRange(double Low, double High, std::string & Str);
// these functions were originally designed to read from a file
// they have been kept but are now "reading" from the vector m_Data
// I may remove at least the first couple later
void SetPos(size_t Pos);
size_t GetPos();
PLWORD GetU16();
PLLONG GetU32();
void Read(void * Buffer, size_t Size);
private:
PLByteCPtr m_Data;
size_t m_DataSize;
// this should probably be moved to PLBmpInfo
// std::string m_Comment; // include comments even though they're not really EXIF
size_t m_Pos; // offset into data (effectively index into m_Data
size_t m_IdfOffset;
bool m_Endian;
PLExifTagList m_AllTags; // Tags in the order found
PLExifTagList m_MainTags;
PLExifTagList m_SubTags;
PLExifTagList m_ManufacturerTags;
typedef std::map<std::string, PLExifTagCPtr> TagMap;
TagMap m_Tags; // tag look up for searching by short name
};
class PLExifTag
{
public:
// default copying is safe
~PLExifTag();
// C Interface - returning const char *
const char * GetShortNameCStr() const;
const char * GetDescriptionCStr() const;
// Format is basic as stored in the raw EXIF data
// eg f4.0 is likely to be 40/10
const char * GetValueCStr() const;
// format is common form eg f4.0 is 4.0 rather than 40/10
const char * GetValueCommonCStr() const;
// STL Interface - returning const string &
const std::string & GetShortName() const;
const std::string GetDescription() const;
// Format is basic as stored in the raw EXIF data
// eg f4.0 is likely to be 40/10
const std::string & GetValue() const;
// format is common form eg f4.0 is 4.0 rather than 40/10
const std::string & GetValueCommon() const;
private:
// render functions to convert from raw memory data
size_t RenDef(PLBYTE * & Buffer);
size_t RenUDef(PLBYTE * & Buffer);
size_t RenUndef(PLBYTE * & Buffer);
size_t RenStr(PLBYTE * & Buffer);
size_t RenURat(PLBYTE * & Buffer);
size_t RenRat(PLBYTE * & Buffer);
// conversion to common values
void CnvRat(std::string & result); // evaluate nominator/denominator
void CnvRatAp(std::string & result); // evaluate nominator/denominator for fstop
void CnvFrac(std::string & result); // evaluate nominator/denominator if > than 1
void CnvApexShutter(std::string & result);
void CnvApexAp(std::string & result);
void CnvCompCfg(std::string & result); // component configuration
void CnvCanINo(std::string & result); // decode canon image no
void CnvCanSNo(std::string & result); // decode canon serial no
void CnvCanFlash(std::string & result); // canon flash details
void CnvCanAFPnt(std::string & result); // canon AF focus point used
// friends to let them have access to the conversion and rendering
// functions without having to make them public to the whole world
friend struct _PLExifTagValues;
friend struct _PLExifFormatter;
private:
PLExifTag(PLUINT TagNo, PLUINT Format, PLUINT NoComp); // only ever created by friend PLExif
void CleanWorkingArea(); // call after all decoding done to free mem buffer
void Swizzle();
void Render();
void DoTranslation();
void Value(size_t Index);
double GetDouble(size_t Index);
const _PLExifTagValues * m_Tag; // The tag for this item - pointer to static data so copy safe
const _PLExifFormatter * m_Fmt; // The format type - pointer to static data so copy safe
std::string m_ShortName; // Copy of the short name
std::string m_Lookup; // Lowercase version of shortname
size_t m_TagNo; // The tag no
size_t m_Format; // Format of this item
size_t m_NoComp; // Number of components
size_t m_Size; // Total size of item
PLByteCPtr m_Buffer; // Copy of the item's data
size_t m_Pos; // Location of tag
// The rendered value
std::string m_Value; // In printable form
std::string m_Common; // in printable common form
PLLONG m_Num; // Numerator
PLLONG m_Den; // Denominator
PLLONG m_Int; // As int
PLUINT m_UInt; // As unsigned int
double m_Double; // As double
private:
// not too thrilled with this but I inherited it!
// however it does avoid having to put stuff into
// the public interface that only PLExif will need
// and will not be needed by the library clients
friend class PLExif;
private:
// these need to be static members to have access to conversion and render functions
static _PLExifTagValues MainTags[];
static _PLExifTagValues SubTags[];
static _PLExifTagValues NikonTags[];
static _PLExifTagValues Nikon2Tags[];
static _PLExifTagValues OlympusTags[];
static _PLExifTagValues CanonTags[];
static _PLExifTagValues CanonSet1[];
static _PLExifTagValues CanonSet2[];
static _PLExifTagValues CanonCFn[];
static _PLExifTagValues FujifilmTags[];
static _PLExifTagValues CasioTags[];
static _PLExifFormatter rgExifFormat[];
};
#endif
|