146 lines
5.7 KiB
C++
146 lines
5.7 KiB
C++
// ***************************************************************** -*- C++ -*-
|
|
/*
|
|
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
|
|
*
|
|
* This program is part of the Exiv2 distribution.
|
|
*
|
|
* 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/*
|
|
File: tiffparser.cpp
|
|
Version: $Rev$
|
|
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
|
History: 15-Mar-06, ahu: created
|
|
|
|
*/
|
|
// *****************************************************************************
|
|
#include "rcsid.hpp"
|
|
EXIV2_RCSID("@(#) $Id$");
|
|
|
|
// *****************************************************************************
|
|
// included header files
|
|
#ifdef _MSC_VER
|
|
# include "exv_msvc.h"
|
|
#else
|
|
# include "exv_conf.h"
|
|
#endif
|
|
|
|
#include "tiffparser.hpp"
|
|
#include "tiffcomposite.hpp"
|
|
#include "tiffvisitor.hpp"
|
|
#include "tiffimage.hpp"
|
|
#include "error.hpp"
|
|
|
|
// + standard includes
|
|
#include <cassert>
|
|
|
|
/* --------------------------------------------------------------------------
|
|
|
|
Todo:
|
|
|
|
+ Add further child mgmt stuff to TIFF composite: remove
|
|
+ Review boundary checking, is it better to check the offsets?
|
|
+ Define and implement consistent error handling for recursive hierarchy
|
|
+ Make TiffImage a template StandardImage, which can be parametrized with
|
|
a parser and the necessary checking functions to cover all types of
|
|
images which need to be loaded completely.
|
|
+ TiffComponent: should it have end() and setEnd() or pData and size?
|
|
+ Can NewTiffCompFct and TiffCompFactoryFct be combined?
|
|
+ Create function is repeated when actually only the table changes. Fix it.
|
|
+ CR2 Makernotes don't seem to have a next pointer but Canon Jpeg Makernotes
|
|
do. What a mess. (That'll become an issue when it comes to writing to CR2)
|
|
|
|
in crwimage.* :
|
|
|
|
+ Fix CiffHeader according to TiffHeade2
|
|
+ Combine Error(15) and Error(33), add format argument %1
|
|
+ Search crwimage for todos, fix writeMetadata comment
|
|
+ rename all Ciff stuff to Crw for easier reference
|
|
|
|
-------------------------------------------------------------------------- */
|
|
|
|
|
|
// *****************************************************************************
|
|
// class member definitions
|
|
namespace Exiv2 {
|
|
|
|
/*
|
|
This table describes the standard TIFF layout and determines the
|
|
corresponding Exiv2 TIFF components. The key of the table consists of the
|
|
first two attributes, (extended) tag and group. Tag is the TIFF tag or one
|
|
of a few extended tags, group identifies the IFD or any other composite
|
|
TIFF component. Each entry of the table defines for a particular tag and
|
|
group combination, which create function is used and what the group of the
|
|
new component is.
|
|
*/
|
|
const TiffStructure TiffCreator::tiffStructure_[] = {
|
|
// ext. tag group create function new group
|
|
//--------- ----------- ---------------- -----------
|
|
{ Tag::root, Group::none, newTiffDirectory, Group::ifd0 },
|
|
{ 0x8769, Group::ifd0, newTiffSubIfd, Group::exif },
|
|
{ 0x8825, Group::ifd0, newTiffSubIfd, Group::gps },
|
|
{ 0xa005, Group::exif, newTiffSubIfd, Group::iop },
|
|
{ 0x927c, Group::exif, newTiffMnEntry, Group::mn },
|
|
{ 0x0201, Group::ifd1, newTiffThumbData, Group::ifd1 },
|
|
{ 0x0202, Group::ifd1, newTiffThumbSize, Group::ifd1 },
|
|
{ Tag::next, Group::ifd0, newTiffDirectory, Group::ifd1 },
|
|
{ Tag::next, Group::ifd1, newTiffDirectory, Group::ignr },
|
|
{ Tag::next, Group::ignr, newTiffDirectory, Group::ignr }
|
|
};
|
|
|
|
TiffComponent::AutoPtr TiffCreator::create(uint32_t extendedTag,
|
|
uint16_t group)
|
|
{
|
|
TiffComponent::AutoPtr tc(0);
|
|
uint16_t tag = static_cast<uint16_t>(extendedTag & 0xffff);
|
|
const TiffStructure* ts = find(tiffStructure_,
|
|
TiffStructure::Key(extendedTag, group));
|
|
if (ts && ts->newTiffCompFct_) {
|
|
tc = ts->newTiffCompFct_(tag, ts);
|
|
}
|
|
if (!ts && extendedTag != Tag::next) {
|
|
tc = TiffComponent::AutoPtr(new TiffEntry(tag, group));
|
|
}
|
|
return tc;
|
|
} // TiffCreator::create
|
|
|
|
void TiffParser::decode(Image* pImage,
|
|
const byte* pData,
|
|
uint32_t size,
|
|
TiffCompFactoryFct createFct)
|
|
{
|
|
assert(pImage != 0);
|
|
assert(pData != 0);
|
|
|
|
TiffHeade2 tiffHeader;
|
|
if (!tiffHeader.read(pData, size) || tiffHeader.ifdOffset() >= size) {
|
|
throw Error(3, "TIFF");
|
|
}
|
|
TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none);
|
|
if (0 == rootDir.get()) return;
|
|
rootDir->setStart(pData + tiffHeader.ifdOffset());
|
|
|
|
TiffRwState::AutoPtr state(
|
|
new TiffRwState(tiffHeader.byteOrder(), 0, createFct));
|
|
TiffReader reader(pData, size, rootDir.get(), state);
|
|
rootDir->accept(reader);
|
|
|
|
TiffMetadataDecoder decoder(pImage);
|
|
rootDir->accept(decoder);
|
|
|
|
} // TiffParser::decode
|
|
|
|
} // namespace Exiv2
|