/* This file is -*-C++-*- ------------------------------------------------------------------------------ denef - Decode NEF image files Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: metacam.h,v 1.4 2000/09/18 15:37:53 daniel Exp $ */ #ifndef METACAM_H_INCLUDED #define METACAM_H_INCLUDED #include #include #include class IFD; class IFDEntry; class istream; class ostream; typedef unsigned long tiffUNSIGNED; typedef signed long tiffSIGNED; const unsigned short tBYTE = 1; const unsigned short tASCII = 2; const unsigned short tSHORT = 3; const unsigned short tLONG = 4; const unsigned short tRATIONAL = 5; const unsigned short tSBYTE = 6; const unsigned short tUNDEFINED = 7; const unsigned short tSSHORT = 8; const unsigned short tSLONG = 9; const unsigned short tSRATIONAL = 10; const unsigned short tFLOAT = 11; const unsigned short tDOUBLE = 12; class tiffRATIONAL { public: tiffUNSIGNED num; tiffUNSIGNED den; tiffRATIONAL() : num(0), den(0) {}; tiffRATIONAL(tiffUNSIGNED n, tiffUNSIGNED d) : num(n), den(d) {}; bool operator == (const tiffRATIONAL &r) const { return ((num == r.num) && (den == r.den)); } bool operator != (const tiffRATIONAL &r) const { return ((num != r.num) || (den != r.den)); } operator double() const { double n(num); double d(den); return n/d; } void Normalize(); }; class tiffSRATIONAL { public: tiffSIGNED num; tiffSIGNED den; tiffSRATIONAL() : num(0), den(0) {}; tiffSRATIONAL(tiffSIGNED n, tiffSIGNED d) : num(n), den(d) {}; bool operator == (const tiffSRATIONAL &r) const { return ((num == r.num) && (den == r.den)); } bool operator != (const tiffSRATIONAL &r) const { return ((num != r.num) || (den != r.den)); } operator double() const { double n(num); double d(den); return n/d; } void Normalize(); }; inline ostream &operator << (ostream &os, const tiffRATIONAL &r) { os << r.num << "/" << r.den; return os; } inline ostream &operator << (ostream &os, const tiffSRATIONAL &r) { os << r.num << "/" << r.den; return os; } class tiffFile { private: friend class IFD; friend class IFDEntry; istream &is; unsigned long global_offset; bool bigendian; protected: void Seek(unsigned long ofs); unsigned long Get_Offset() const { return is.tellg()-global_offset; } void Get_Data(unsigned char *buf, size_t bytes); unsigned char Get_UByte(); unsigned short Get_UShort(); unsigned long Get_ULong(); signed char Get_SByte(); signed short Get_SShort(); signed long Get_SLong(); unsigned long First_IFD() { Seek(4); return Get_ULong(); } public: tiffFile(istream &i, unsigned long ofs=0); IFD Get_IFD(); IFD Get_IFD(unsigned long ofs, unsigned long tagofs=0); }; class IFDEntry; class IFD { private: tiffFile &file; unsigned long ofs; unsigned short entries; unsigned long next_ifd; IFDEntry **table; public: IFD(const IFD &); IFD &operator=(const IFD &); IFD(tiffFile &t, unsigned long o, unsigned long tagofs = 0); ~IFD(); bool operator !() const {return ofs==0;} operator bool() const {return ofs!=0;} tiffFile &File() const {return file;} const IFDEntry &operator[](int n) const; unsigned short Entries() const {return entries;} IFD Next_IFD() const { return file.Get_IFD(next_ifd); } }; class IFDEntry { friend class IFD; private: tiffFile &file; unsigned long tag; unsigned short type; unsigned long values; unsigned long offset; public: IFDEntry(tiffFile &t) : file(t), tag(0), type(0), values(0), offset(0) {}; static int Type_Length(unsigned short); int Length() const {return Type_Length(type) * values;} unsigned long Tag() const {return tag;} unsigned short Type() const {return type;} unsigned long Values() const {return values;} unsigned long Offset() const {return offset;} void Output_Value(ostream &os) const; vector Get_UVALUES() const; vector Get_SVALUES() const; vector Get_RATIONALS() const; vector Get_SRATIONALS() const; vector Get_STRINGS() const; vector Get_OPAQUE() const; }; inline ostream & operator<<(ostream &os, const IFDEntry &e) { os << "[TAG " << hex << e.Tag() << dec << " TYPE " << e.Type() << " VALUES " << e.Values() << " OFFSET " << e.Offset() << "]"; return os; } class idpair { private: unsigned long tag; unsigned short type; public: idpair() : tag(0), type(0) {}; idpair(unsigned long a, unsigned short b) : tag(a), type(b) {}; bool operator==(const idpair &i) const { return (tag==i.tag) && (type == i.type); } bool operator!=(const idpair &i) const { return (tag!=i.tag) || (type != i.type); } bool operator<=(const idpair &i) const { if (tag < i.tag) return true; if (tag > i.tag) return false; return (type <= i.type); } bool operator<(const idpair &i) const { if (tag < i.tag) return true; if (tag > i.tag) return false; return (type < i.type); } bool operator>(const idpair &i) const { if (tag > i.tag) return true; if (tag < i.tag) return false; return (type > i.type); } bool operator>=(const idpair &i) const { if (tag > i.tag) return true; if (tag < i.tag) return false; return (type >= i.type); } unsigned long Tag() const {return tag;} unsigned long Type() const {return type;} }; typedef map tagmap; typedef void dpyFunction(ostream &os, const char *, const IFDEntry &e); struct knowntag { unsigned long tag; unsigned short type; int verbose; const char *name; dpyFunction *func; }; inline ostream & operator<<(ostream &os, const idpair &p) { os << hex << p.Tag() << ":" << p.Type() << dec; return os; } #endif /* METACAM_H_INCLUDED */