Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members

plexif.h

00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plexif.h,v 1.4 2003/04/20 12:44:47 uzadow Exp $
00005 |
00006 |      Copyright (c) 1996-2003 Ulrich von Zadow
00007 |
00008 |      Implementation of PLExif class by Mike Franklin
00009 |      Much of the decoding code was adapted from code by Ken Reneris:
00010 |         http://www.reneris.com/tools/exif.asp -
00011 |                                 though it has been heavily modified!
00012 |
00013 |
00014 \--------------------------------------------------------------------
00015 */
00016 
00017 #ifndef INCL_PLEXIF
00018 #define INCL_PLEXIF
00019 
00020 #ifdef _MSC_VER                 // The microsoft compiler generates masses 
00021                                 // of symbol too long
00022 #pragma warning(disable: 4786)  // for debugger warnings for sets and maps
00023 #endif
00024 
00025 #include "plpaintlibdefs.h"
00026 #include "plcountedpointer.h"
00027 
00028 #include <cstdio>
00029 #include <vector>
00030 #include <string>
00031 #include <map>
00032 
00033 struct jpeg_decompress_struct;
00034 struct jpeg_compress_struct;
00035 
00036 // these structures are for internal use only
00037 struct _PLExifTranslator;
00038 struct _PLExifTagValues;
00039 struct _PLExifFormatter;
00040 
00041 class PLExifTag;
00042 typedef PLCountedPointer<PLExifTag>           PLExifTagCPtr;  // PLExifTag counted pointer
00043 typedef std::vector<PLExifTagCPtr>            PLExifTagList;  // vector of PLExifTag counted pointers
00044 typedef PLCountedArrayPointer<PLBYTE>         PLByteCPtr;     // utility typedef
00045 
00046 
00047 class PLExif
00048 {
00049 public:
00050                         PLExif();
00051                         ~PLExif();
00052                         // default copying is safe
00053 
00054                         // reset the internal data
00055   void                  Clear();
00056 
00057   // Access the raw EXIF data (just a copy of the EXIF header held in memory)
00058   size_t                GetRawDataSize() const;
00059   PLBYTE *              GetRawData();
00060   const PLBYTE *        GetRawData() const;
00061 
00062 /*
00063   // These are not EXIF comments and should probably be moved to PLBmpInfo
00064   const std::string &   GetComment() const;
00065   const char *          GetCommmentCStr() const;
00066 
00067   void                  SetComment(const std::string &);
00068   void                  SetComment(const char *);
00069 */
00070   // Access to the Main, Sub and Manufacturer tags
00071   // also a single list that contains them all
00072   const PLExifTagList & GetAllTags() const;
00073   const PLExifTagList & GetMainTags() const;
00074   const PLExifTagList & GetSubTags() const;
00075   const PLExifTagList & GetManufacturerTags() const;
00076 
00077   // As above but returning a traditional C style array pointer
00078   // instead of an STL vector
00079   // It is an array of pointers to PLExifTag
00080   const PLExifTagCPtr * GetAllTagsC(size_t & size) const;
00081   const PLExifTagCPtr * GetMainTagsC(size_t & size) const;
00082   const PLExifTagCPtr * GetSubTagsC(size_t & size) const;
00083   const PLExifTagCPtr * GetManufacturerTagsC(size_t & size) const;
00084 
00085 
00086   // All the following functions give access to a tag given a tag shortname
00087   // they almost all return a pointer to the whole tag but mostly this
00088   // will just be used to check whether the tag was found by testing for
00089   // a NULL pointer. The useful data - the tag value is generally returned
00090   // by reference.
00091   //
00092   // duplicate copies of the functions allow efficient use whether
00093   // the source tag string is a std::string or a char *
00094   // All forms return a pointer to the found tag, 0 if not found
00095 
00096   // Just return the tag pointer
00097   PLExifTag *           GetTag(const char * TagShortName) const;
00098   PLExifTag *           GetTag(const std::string & TagShortName) const
00099                         { return GetTag(TagShortName.c_str()); }
00100 
00101   // place the tag value into the Value string, format is basic
00102   // as stored in the raw EXIF data eg f4.0 is likely to be 40/10
00103   PLExifTag *           GetTag(const char * TagShortName, std::string & Value) const;
00104   PLExifTag *           GetTag(const std::string & TagShortName, std::string & Value) const
00105                         { return GetTag(TagShortName.c_str(), Value); }
00106 
00107   // place the tag value in the Value string, format is common form
00108   // eg f4.0 is 4.0 rather than 40/10
00109   PLExifTag *           GetTagCommon(const char * TagShortName, std::string & Value) const;
00110   PLExifTag *           GetTagCommon(const std::string & TagShortName, std::string & Value) const
00111                         { return GetTagCommon(TagShortName.c_str(), Value); }
00112 
00113   // place the tag value in the Value double where appropriate
00114   // eg 1.234m focus
00115   PLExifTag *           GetTag(const char * TagShortName, double & Value) const;
00116   PLExifTag *           GetTag(const std::string & TagShortName, double & Value) const
00117                         { return GetTag(TagShortName.c_str(), Value); }
00118 
00119   // return tag value as a string (empty string if not found), format is basic
00120   // as stored in the raw EXIF data eg f4.0 is likely to be 40/10
00121   std::string &         TagStr(const char * TagShortName) const;
00122   std::string &         TagStr(const std::string & TagShortName) const
00123                         { return TagStr(TagShortName.c_str()); }
00124 
00125   // return tag value as a string (empty string if not found)
00126   // format is common form eg f4.0 is 4.0 rather than 40/10
00127   std::string &         TagStrCommon(const char * TagShortName) const;
00128   std::string &         TagStrCommon(const std::string & TagShortName) const
00129                         { return TagStrCommon(TagShortName.c_str()); }
00130 
00131   // C string return versions of TagStr and TagStrCommon
00132 
00133   // return tag value as a string (empty string if not found), format is basic
00134   // as stored in the raw EXIF data eg f4.0 is likely to be 40/10
00135   const char *          TagCStr(const char * TagShortName) const;
00136   const char *          TagCStr(const std::string & TagShortName) const
00137                         { return TagCStr(TagShortName.c_str()); }
00138 
00139   // return tag value as a string (empty string if not found)
00140   // format is common form eg f4.0 is 4.0 rather than 40/10
00141   const char *          TagCStrCommon(const char * TagShortName) const;
00142   const char *          TagCStrCommon(const std::string & TagShortName) const
00143                         { return TagCStrCommon(TagShortName.c_str()); }
00144 
00145   // These two methods are primarily intended for use only by the Paintlib encoders and decoders
00146                         // load data from cinfo - jpeg_save_markers must have been called first
00147   void                  ReadData(const jpeg_decompress_struct * pcinfo);
00148 
00149                          // write data to cinfo - after jpeg_start_compress
00150   void                  WriteData(jpeg_compress_struct * pcinfo);
00151 
00152 
00153 private:
00154   void                  decode();   // do the actual decoding of the EXIF data
00155 
00156   void                  ReadIFD(const _PLExifTagValues * Tags, char * Prefix, PLExifTagList & sectionList);
00157   void                  ExpandBinaryTag(const std::string & Src, const _PLExifTagValues *Tags, PLUINT Type, PLExifTagList & sectionList);
00158   void                  DecodeCanCustomFncs(const PLExifTag & rootTag, const _PLExifTagValues *Tags, PLExifTagList & sectionList);
00159 
00160   void                  CopyTag(const char * Src, const char * Dst);
00161   void                  SetTag(const char * Dst, const char * Value);
00162   void                  SetTag(const char * Dst, const std::string & Value)
00163                         { SetTag(Dst, Value.c_str()); }
00164   void                  AddTag(const char * Dst, const char * SrcTag, const char * Skip = NULL, const char * Sep = NULL);
00165   void                  AddStr(const char * Dst, const std::string & SrcStr,  const char * Skip = NULL, const char * Sep = NULL);
00166   void                  FormatRange(double Low, double High, std::string & Str);
00167 
00168   // these functions were originally designed to read from a file
00169   // they have been kept but are now "reading" from the vector m_Data
00170   // I may remove at least the first couple later
00171   void                  SetPos(size_t Pos);
00172   size_t                GetPos();
00173 
00174   PLWORD                GetU16();
00175   PLLONG                GetU32();
00176   void                  Read(void * Buffer, size_t Size);
00177 
00178 
00179 
00180 private:
00181 
00182   PLByteCPtr          m_Data;
00183   size_t              m_DataSize;
00184 
00185   // this should probably be moved to PLBmpInfo
00186 //  std::string         m_Comment;  // include comments even though they're not really EXIF
00187 
00188   size_t              m_Pos;     // offset into data (effectively index into m_Data
00189   size_t              m_IdfOffset;
00190   bool                m_Endian;
00191 
00192   PLExifTagList       m_AllTags;      // Tags in the order found
00193   PLExifTagList       m_MainTags;
00194   PLExifTagList       m_SubTags;
00195   PLExifTagList       m_ManufacturerTags;
00196 
00197   typedef std::map<std::string, PLExifTagCPtr>  TagMap;
00198   TagMap              m_Tags;         // tag look up for searching by short name
00199 
00200 };
00201 
00202 
00203 class PLExifTag
00204 {
00205 public:
00206                   // default copying is safe
00207                   ~PLExifTag();
00208 
00209   // C Interface - returning const char *
00210   const char *          GetShortNameCStr() const;
00211   const char *          GetDescriptionCStr() const;
00212   // Format is basic as stored in the raw EXIF data
00213   // eg f4.0 is likely to be 40/10
00214   const char *          GetValueCStr() const;
00215   // format is common form eg f4.0 is 4.0 rather than 40/10
00216   const char *          GetValueCommonCStr() const;
00217 
00218   // STL Interface - returning const string &
00219   const std::string &   GetShortName() const;
00220   const std::string     GetDescription() const;
00221   // Format is basic as stored in the raw EXIF data
00222   // eg f4.0 is likely to be 40/10
00223   const std::string &   GetValue() const;
00224   // format is common form eg f4.0 is 4.0 rather than 40/10
00225   const std::string &   GetValueCommon() const;
00226 
00227 private:
00228   // render functions to convert from raw memory data
00229   size_t          RenDef(PLBYTE * & Buffer);
00230   size_t          RenUDef(PLBYTE * & Buffer);
00231   size_t          RenUndef(PLBYTE * & Buffer);
00232   size_t          RenStr(PLBYTE * & Buffer);
00233   size_t          RenURat(PLBYTE * & Buffer);
00234   size_t          RenRat(PLBYTE * & Buffer);
00235 
00236   // conversion to common values
00237   void            CnvRat(std::string & result);   // evaluate nominator/denominator
00238   void            CnvRatAp(std::string & result); // evaluate nominator/denominator for fstop
00239   void            CnvFrac(std::string & result);  // evaluate nominator/denominator if > than 1
00240   void            CnvApexShutter(std::string & result);
00241   void            CnvApexAp(std::string & result);
00242   void            CnvCompCfg(std::string & result);   // component configuration
00243   void            CnvCanINo(std::string & result);    // decode canon image no
00244   void            CnvCanSNo(std::string & result);    // decode canon serial no
00245   void            CnvCanFlash(std::string & result);  // canon flash details
00246   void            CnvCanAFPnt(std::string & result);  // canon AF focus point used
00247 
00248   // friends to let them have access to the conversion and rendering
00249   // functions without having to make them public to the whole world
00250   friend struct _PLExifTagValues;
00251   friend struct _PLExifFormatter;
00252 
00253 private:
00254                   PLExifTag(PLUINT TagNo, PLUINT Format, PLUINT NoComp);    // only ever created by friend PLExif
00255 
00256   void            CleanWorkingArea();   // call after all decoding done to free mem buffer
00257   void            Swizzle();
00258   void            Render();
00259   void            DoTranslation();
00260   void            Value(size_t Index);
00261   double          GetDouble(size_t Index);
00262 
00263 
00264   const _PLExifTagValues *   m_Tag;    // The tag for this item - pointer to static data so copy safe
00265   const _PLExifFormatter *   m_Fmt;    // The format type - pointer to static data so copy safe
00266 
00267   std::string     m_ShortName;    // Copy of the short name
00268   std::string     m_Lookup;       // Lowercase version of shortname
00269 
00270   size_t          m_TagNo;        // The tag no
00271   size_t          m_Format;       // Format of this item
00272   size_t          m_NoComp;       // Number of components
00273   size_t          m_Size;         // Total size of item
00274   PLByteCPtr      m_Buffer;       // Copy of the item's data
00275   size_t          m_Pos;          // Location of tag
00276 
00277   // The rendered value
00278   std::string     m_Value;        // In printable form
00279   std::string     m_Common;       // in printable common form
00280   PLLONG          m_Num;          // Numerator
00281   PLLONG          m_Den;          // Denominator
00282   PLLONG          m_Int;          // As int
00283   PLUINT          m_UInt;         // As unsigned int
00284   double          m_Double;       // As double
00285 
00286 private:
00287   // not too thrilled with this but I inherited it!
00288   // however it does avoid having to put stuff into
00289   // the public interface that only PLExif will need
00290   // and will not be needed by the library clients
00291   friend class PLExif;
00292 
00293 private:
00294   // these need to be static members to have access to conversion and render functions
00295   static _PLExifTagValues   MainTags[];
00296   static _PLExifTagValues   SubTags[];
00297   static _PLExifTagValues   NikonTags[];
00298   static _PLExifTagValues   Nikon2Tags[];
00299   static _PLExifTagValues   OlympusTags[];
00300   static _PLExifTagValues   CanonTags[];
00301   static _PLExifTagValues   CanonSet1[];
00302   static _PLExifTagValues   CanonSet2[];
00303   static _PLExifTagValues   CanonCFn[];
00304   static _PLExifTagValues   FujifilmTags[];
00305   static _PLExifTagValues   CasioTags[];
00306   static _PLExifFormatter   rgExifFormat[];
00307 };
00308 
00309 
00310 
00311 
00312 
00313 
00314 #endif

Generated on Sun Jun 6 13:42:22 2004 for paintlib by doxygen 1.3.2