/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/

#include <iostream.h>

#include "metacam.h"

static const char *rcsid="$Id: ifd.cc,v 1.3 2000/09/18 07:51:43 daniel Exp $";

IFD::IFD(const IFD &i)
    : file(i.file), ofs(i.ofs), entries(i.entries), next_ifd(i.next_ifd)
{
    if (entries) {
	table = new IFDEntry *[i.entries];
	for (int x=0; x<entries; ++x) table[x] = new IFDEntry(*i.table[x]);
    } else {
	table = 0;
    }
}

IFD &
IFD::operator=(const IFD &i)
{
    if (this == &i) return *this;
    if (&file != &i.file) {
	cerr << "Cannot change file!" << endl;
	exit(2);
    }

    if (entries) {
	for (int i=0; i<entries; ++i) delete table[i];
	delete [] table;
    }

    ofs = i.ofs;
    entries = i.entries;
    next_ifd = i.next_ifd;

    if (entries) {
	table = new IFDEntry *[i.entries];
	for (int x=0; x<entries; ++x) table[x] = new IFDEntry(*i.table[x]);
    } else {
	table = 0;
    }
    return *this;
}

IFD::~IFD()
{
    if (entries) {
	for (int i=0; i<entries; ++i) delete table[i];
	delete [] table;
    }
}

IFD::IFD(tiffFile &t, unsigned long o, unsigned long tagofs)
    : file(t), ofs(o), table(0)
{
    if (!ofs) {
	entries=0;
	table=0;
	next_ifd=0;
	return;
    }
    file.Seek(ofs);
    entries = file.Get_UShort();
    table = new IFDEntry *[entries];

    int i;
    for (i=0; i<entries; ++i) {
	IFDEntry e(file);
	e.tag = file.Get_UShort() + tagofs;
	e.type = file.Get_UShort();
	e.values = file.Get_ULong();

	if (e.Length() <= 4) {
	    e.offset = file.Get_Offset();
	    file.Get_ULong();
	} else {
	    e.offset = file.Get_ULong();
	}

	table[i] = new IFDEntry(e);
    }

    next_ifd = file.Get_ULong();
}

const IFDEntry &
IFD::operator[](int n)  const
{
    if ((n<0) || (n>=entries)) {
	cerr << "IFD Array Bounds Violated" << endl;
	exit(2);
    }
    return *table[n];
}


