|
Packit Service |
21b5d1 |
// ***************************************************************** -*- C++ -*-
|
|
Packit Service |
21b5d1 |
/*
|
|
Packit Service |
21b5d1 |
* Copyright (C) 2004-2018 Exiv2 authors
|
|
Packit Service |
21b5d1 |
* This program is part of the Exiv2 distribution.
|
|
Packit Service |
21b5d1 |
*
|
|
Packit Service |
21b5d1 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
21b5d1 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
21b5d1 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
21b5d1 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
21b5d1 |
*
|
|
Packit Service |
21b5d1 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
21b5d1 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
21b5d1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
21b5d1 |
* GNU General Public License for more details.
|
|
Packit Service |
21b5d1 |
*
|
|
Packit Service |
21b5d1 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
21b5d1 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
21b5d1 |
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
|
Packit Service |
21b5d1 |
*/
|
|
Packit Service |
21b5d1 |
/*
|
|
Packit Service |
21b5d1 |
File: image.cpp
|
|
Packit Service |
21b5d1 |
*/
|
|
Packit Service |
21b5d1 |
// *****************************************************************************
|
|
Packit Service |
21b5d1 |
// included header files
|
|
Packit Service |
21b5d1 |
#include "config.h"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include "image.hpp"
|
|
Packit Service |
21b5d1 |
#include "image_int.hpp"
|
|
Packit Service |
21b5d1 |
#include "error.hpp"
|
|
Packit Service |
21b5d1 |
#include "futils.hpp"
|
|
Packit Service |
21b5d1 |
#include "safe_op.hpp"
|
|
Packit Service |
21b5d1 |
#include "slice.hpp"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include "cr2image.hpp"
|
|
Packit Service |
21b5d1 |
#include "crwimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "epsimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "jpgimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "mrwimage.hpp"
|
|
Packit Service |
21b5d1 |
#ifdef EXV_HAVE_LIBZ
|
|
Packit Service |
21b5d1 |
# include "pngimage.hpp"
|
|
Packit Service |
21b5d1 |
#endif // EXV_HAVE_LIBZ
|
|
Packit Service |
21b5d1 |
#include "rafimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "tiffimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "tiffimage_int.hpp"
|
|
Packit Service |
21b5d1 |
#include "tiffcomposite_int.hpp"
|
|
Packit Service |
21b5d1 |
#include "tiffvisitor_int.hpp"
|
|
Packit Service |
21b5d1 |
#include "bigtiffimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "webpimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "orfimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "gifimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "psdimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "tgaimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "bmpimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "jp2image.hpp"
|
|
Packit Service |
21b5d1 |
#include "nikonmn_int.hpp"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_ENABLE_VIDEO
|
|
Packit Service |
21b5d1 |
#include "matroskavideo.hpp"
|
|
Packit Service |
21b5d1 |
#include "quicktimevideo.hpp"
|
|
Packit Service |
21b5d1 |
#include "riffvideo.hpp"
|
|
Packit Service |
21b5d1 |
#include "asfvideo.hpp"
|
|
Packit Service |
21b5d1 |
#endif // EXV_ENABLE_VIDEO
|
|
Packit Service |
21b5d1 |
#include "rw2image.hpp"
|
|
Packit Service |
21b5d1 |
#include "pgfimage.hpp"
|
|
Packit Service |
21b5d1 |
#include "xmpsidecar.hpp"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// + standard includes
|
|
Packit Service |
21b5d1 |
#include <cerrno>
|
|
Packit Service |
21b5d1 |
#include <cstdio>
|
|
Packit Service |
21b5d1 |
#include <cstring>
|
|
Packit Service |
21b5d1 |
#include <cassert>
|
|
Packit Service |
21b5d1 |
#include <iostream>
|
|
Packit Service |
21b5d1 |
#include <limits>
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include <sys/types.h>
|
|
Packit Service |
21b5d1 |
#include <sys/stat.h>
|
|
Packit Service |
21b5d1 |
#ifdef _MSC_VER
|
|
Packit Service |
21b5d1 |
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
#ifdef EXV_HAVE_UNISTD_H
|
|
Packit Service |
21b5d1 |
# include <unistd.h> // stat
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *****************************************************************************
|
|
Packit Service |
21b5d1 |
namespace {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
using namespace Exiv2;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
//! Struct for storing image types and function pointers.
|
|
Packit Service |
21b5d1 |
struct Registry {
|
|
Packit Service |
21b5d1 |
//! Comparison operator to compare a Registry structure with an image type
|
|
Packit Service |
21b5d1 |
bool operator==(const int& imageType) const { return imageType == imageType_; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// DATA
|
|
Packit Service |
21b5d1 |
int imageType_;
|
|
Packit Service |
21b5d1 |
NewInstanceFct newInstance_;
|
|
Packit Service |
21b5d1 |
IsThisTypeFct isThisType_;
|
|
Packit Service |
21b5d1 |
AccessMode exifSupport_;
|
|
Packit Service |
21b5d1 |
AccessMode iptcSupport_;
|
|
Packit Service |
21b5d1 |
AccessMode xmpSupport_;
|
|
Packit Service |
21b5d1 |
AccessMode commentSupport_;
|
|
Packit Service |
21b5d1 |
};
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const Registry registry[] = {
|
|
Packit Service |
21b5d1 |
//image type creation fct type check Exif mode IPTC mode XMP mode Comment mode
|
|
Packit Service |
21b5d1 |
//--------------- --------------- ---------- ----------- ----------- ----------- ------------
|
|
Packit Service |
21b5d1 |
{ ImageType::jpeg, newJpegInstance, isJpegType, amReadWrite, amReadWrite, amReadWrite, amReadWrite },
|
|
Packit Service |
21b5d1 |
{ ImageType::exv, newExvInstance, isExvType, amReadWrite, amReadWrite, amReadWrite, amReadWrite },
|
|
Packit Service |
21b5d1 |
{ ImageType::cr2, newCr2Instance, isCr2Type, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::crw, newCrwInstance, isCrwType, amReadWrite, amNone, amNone, amReadWrite },
|
|
Packit Service |
21b5d1 |
{ ImageType::mrw, newMrwInstance, isMrwType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::tiff, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::bigtiff, newBigTiffInstance, isBigTiffType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::webp, newWebPInstance, isWebPType, amReadWrite, amNone, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::dng, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::nef, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::pef, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::arw, newTiffInstance, isTiffType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::rw2, newRw2Instance, isRw2Type, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::sr2, newTiffInstance, isTiffType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::srw, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::orf, newOrfInstance, isOrfType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
#ifdef EXV_HAVE_LIBZ
|
|
Packit Service |
21b5d1 |
{ ImageType::png, newPngInstance, isPngType, amReadWrite, amReadWrite, amReadWrite, amReadWrite },
|
|
Packit Service |
21b5d1 |
#endif // EXV_HAVE_LIBZ
|
|
Packit Service |
21b5d1 |
{ ImageType::pgf, newPgfInstance, isPgfType, amReadWrite, amReadWrite, amReadWrite, amReadWrite },
|
|
Packit Service |
21b5d1 |
{ ImageType::raf, newRafInstance, isRafType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::eps, newEpsInstance, isEpsType, amNone, amNone, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::xmp, newXmpInstance, isXmpType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::gif, newGifInstance, isGifType, amNone, amNone, amNone, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::psd, newPsdInstance, isPsdType, amRead, amRead, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::jp2, newJp2Instance, isJp2Type, amReadWrite, amReadWrite, amReadWrite, amNone },
|
|
Packit Service |
21b5d1 |
#ifdef EXV_ENABLE_VIDEO
|
|
Packit Service |
21b5d1 |
{ ImageType::qtime,newQTimeInstance,isQTimeType,amRead, amNone, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::riff, newRiffInstance, isRiffType, amRead, amNone, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::asf, newAsfInstance, isAsfType, amNone, amNone, amRead, amNone },
|
|
Packit Service |
21b5d1 |
{ ImageType::mkv, newMkvInstance, isMkvType, amNone, amNone, amRead, amNone },
|
|
Packit Service |
21b5d1 |
#endif // EXV_ENABLE_VIDEO
|
|
Packit Service |
21b5d1 |
// End of list marker
|
|
Packit Service |
21b5d1 |
{ ImageType::none, 0, 0, amNone, amNone, amNone, amNone }
|
|
Packit Service |
21b5d1 |
};
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *****************************************************************************
|
|
Packit Service |
21b5d1 |
// class member definitions
|
|
Packit Service |
21b5d1 |
namespace Exiv2 {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
Image::Image(int imageType,
|
|
Packit Service |
21b5d1 |
uint16_t supportedMetadata,
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io)
|
|
Packit Service |
21b5d1 |
: io_(io),
|
|
Packit Service |
21b5d1 |
pixelWidth_(0),
|
|
Packit Service |
21b5d1 |
pixelHeight_(0),
|
|
Packit Service |
21b5d1 |
imageType_(imageType),
|
|
Packit Service |
21b5d1 |
supportedMetadata_(supportedMetadata),
|
|
Packit Service |
21b5d1 |
#ifdef EXV_HAVE_XMP_TOOLKIT
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket_(false),
|
|
Packit Service |
21b5d1 |
#else
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket_(true),
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
byteOrder_(invalidByteOrder),
|
|
Packit Service |
21b5d1 |
tags_(),
|
|
Packit Service |
21b5d1 |
init_(true)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
Image::~Image()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::printStructure(std::ostream&, PrintStructureOption,int /*depth*/)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
throw Error(kerUnsupportedImageType, io_->path());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool Image::isStringType(uint16_t type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return type == Exiv2::asciiString
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::unsignedByte
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::signedByte
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::undefined
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isShortType(uint16_t type) {
|
|
Packit Service |
21b5d1 |
return type == Exiv2::unsignedShort
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::signedShort
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isLongType(uint16_t type) {
|
|
Packit Service |
21b5d1 |
return type == Exiv2::unsignedLong
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::signedLong
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isLongLongType(uint16_t type) {
|
|
Packit Service |
21b5d1 |
return type == Exiv2::unsignedLongLong
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::signedLongLong
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isRationalType(uint16_t type) {
|
|
Packit Service |
21b5d1 |
return type == Exiv2::unsignedRational
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::signedRational
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::is2ByteType(uint16_t type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return isShortType(type);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::is4ByteType(uint16_t type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return isLongType(type)
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::tiffFloat
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::tiffIfd
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::is8ByteType(uint16_t type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return isRationalType(type)
|
|
Packit Service |
21b5d1 |
|| isLongLongType(type)
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::tiffIfd8
|
|
Packit Service |
21b5d1 |
|| type == Exiv2::tiffDouble
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isPrintXMP(uint16_t type, Exiv2::PrintStructureOption option)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return type == 700 && option == kpsXMP;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isPrintICC(uint16_t type, Exiv2::PrintStructureOption option)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return type == 0x8773 && option == kpsIccProfile;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool Image::isBigEndianPlatform()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
union {
|
|
Packit Service |
21b5d1 |
uint32_t i;
|
|
Packit Service |
21b5d1 |
char c[4];
|
|
Packit Service |
21b5d1 |
} e = { 0x01000000 };
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return e.c[0]?true:false;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bool Image::isLittleEndianPlatform() { return !isBigEndianPlatform(); }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint64_t Image::byteSwap(uint64_t value,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint64_t result = 0;
|
|
Packit Service |
21b5d1 |
byte* source_value = reinterpret_cast<byte *>(&value);
|
|
Packit Service |
21b5d1 |
byte* destination_value = reinterpret_cast<byte *>(&result);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for (int i = 0; i < 8; i++)
|
|
Packit Service |
21b5d1 |
destination_value[i] = source_value[8 - i - 1];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return bSwap ? result : value;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint32_t Image::byteSwap(uint32_t value,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint32_t result = 0;
|
|
Packit Service |
21b5d1 |
result |= (value & 0x000000FF) << 24;
|
|
Packit Service |
21b5d1 |
result |= (value & 0x0000FF00) << 8;
|
|
Packit Service |
21b5d1 |
result |= (value & 0x00FF0000) >> 8;
|
|
Packit Service |
21b5d1 |
result |= (value & 0xFF000000) >> 24;
|
|
Packit Service |
21b5d1 |
return bSwap ? result : value;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint16_t Image::byteSwap(uint16_t value,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint16_t result = 0;
|
|
Packit Service |
21b5d1 |
result |= (value & 0x00FF) << 8;
|
|
Packit Service |
21b5d1 |
result |= (value & 0xFF00) >> 8;
|
|
Packit Service |
21b5d1 |
return bSwap ? result : value;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint16_t Image::byteSwap2(const DataBuf& buf,size_t offset,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint16_t v;
|
|
Packit Service |
21b5d1 |
char* p = (char*) &v;
|
|
Packit Service |
21b5d1 |
p[0] = buf.pData_[offset];
|
|
Packit Service |
21b5d1 |
p[1] = buf.pData_[offset+1];
|
|
Packit Service |
21b5d1 |
return Image::byteSwap(v,bSwap);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint32_t Image::byteSwap4(const DataBuf& buf,size_t offset,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint32_t v;
|
|
Packit Service |
21b5d1 |
char* p = (char*) &v;
|
|
Packit Service |
21b5d1 |
p[0] = buf.pData_[offset];
|
|
Packit Service |
21b5d1 |
p[1] = buf.pData_[offset+1];
|
|
Packit Service |
21b5d1 |
p[2] = buf.pData_[offset+2];
|
|
Packit Service |
21b5d1 |
p[3] = buf.pData_[offset+3];
|
|
Packit Service |
21b5d1 |
return Image::byteSwap(v,bSwap);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint64_t Image::byteSwap8(const DataBuf& buf,size_t offset,bool bSwap) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
uint64_t v;
|
|
Packit Service |
21b5d1 |
byte* p = reinterpret_cast<byte *>(&v);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for(int i = 0; i < 8; i++)
|
|
Packit Service |
21b5d1 |
p[i] = buf.pData_[offset + i];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return Image::byteSwap(v,bSwap);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const char* Image::typeName(uint16_t tag) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
//! List of TIFF image tags
|
|
Packit Service |
21b5d1 |
const char* result = NULL;
|
|
Packit Service |
21b5d1 |
switch (tag ) {
|
|
Packit Service |
21b5d1 |
case Exiv2::unsignedByte : result = "BYTE" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::asciiString : result = "ASCII" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::unsignedShort : result = "SHORT" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::unsignedLong : result = "LONG" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::unsignedRational : result = "RATIONAL" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::signedByte : result = "SBYTE" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::undefined : result = "UNDEFINED" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::signedShort : result = "SSHORT" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::signedLong : result = "SLONG" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::signedRational : result = "SRATIONAL" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::tiffFloat : result = "FLOAT" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::tiffDouble : result = "DOUBLE" ; break;
|
|
Packit Service |
21b5d1 |
case Exiv2::tiffIfd : result = "IFD" ; break;
|
|
Packit Service |
21b5d1 |
default : result = "unknown" ; break;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return result;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static bool typeValid(uint16_t type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return type >= 1 && type <= 13 ;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,uint32_t start,bool bSwap,char c,int depth)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
depth++;
|
|
Packit Service |
21b5d1 |
bool bFirst = true ;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// buffer
|
|
Packit Service |
21b5d1 |
const size_t dirSize = 32;
|
|
Packit Service |
21b5d1 |
DataBuf dir(dirSize);
|
|
Packit Service |
21b5d1 |
bool bPrint = option == kpsBasic || option == kpsRecursive;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
do {
|
|
Packit Service |
21b5d1 |
// Read top of directory
|
|
Packit Service |
21b5d1 |
const int seekSuccess = !io.seek(start,BasicIo::beg);
|
|
Packit Service |
21b5d1 |
const long bytesRead = io.read(dir.pData_, 2);
|
|
Packit Service |
21b5d1 |
if (!seekSuccess || bytesRead == 0) {
|
|
Packit Service |
21b5d1 |
throw Error(kerCorruptedMetadata);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
uint16_t dirLength = byteSwap2(dir,0,bSwap);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool tooBig = dirLength > 500;
|
|
Packit Service |
21b5d1 |
if ( tooBig ) throw Error(kerTiffDirectoryTooLarge);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( bFirst && bPrint ) {
|
|
Packit Service |
21b5d1 |
out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE (%c%c): ",c,c) << io.path() << std::endl;
|
|
Packit Service |
21b5d1 |
if ( tooBig ) out << Internal::indent(depth) << "dirLength = " << dirLength << std::endl;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Read the dictionary
|
|
Packit Service |
21b5d1 |
for ( int i = 0 ; i < dirLength ; i ++ ) {
|
|
Packit Service |
21b5d1 |
if ( bFirst && bPrint ) {
|
|
Packit Service |
21b5d1 |
out << Internal::indent(depth)
|
|
Packit Service |
21b5d1 |
<< " address | tag | "
|
|
Packit Service |
21b5d1 |
<< " type | count | offset | value\n";
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
bFirst = false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
io.read(dir.pData_, 12);
|
|
Packit Service |
21b5d1 |
uint16_t tag = byteSwap2(dir,0,bSwap);
|
|
Packit Service |
21b5d1 |
uint16_t type = byteSwap2(dir,2,bSwap);
|
|
Packit Service |
21b5d1 |
uint32_t count = byteSwap4(dir,4,bSwap);
|
|
Packit Service |
21b5d1 |
uint32_t offset = byteSwap4(dir,8,bSwap);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Break for unknown tag types else we may segfault.
|
|
Packit Service |
21b5d1 |
if ( !typeValid(type) ) {
|
|
Packit Service |
21b5d1 |
std::cerr << "invalid type value detected in Image::printIFDStructure: " << type << std::endl;
|
|
Packit Service |
21b5d1 |
start = 0; // break from do loop
|
|
Packit Service |
21b5d1 |
throw Error(kerInvalidTypeValue);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
std::string sp = "" ; // output spacer
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
//prepare to print the value
|
|
Packit Service |
21b5d1 |
uint32_t kount = isPrintXMP(tag,option) ? count // haul in all the data
|
|
Packit Service |
21b5d1 |
: isPrintICC(tag,option) ? count // ditto
|
|
Packit Service |
21b5d1 |
: isStringType(type) ? (count > 32 ? 32 : count) // restrict long arrays
|
|
Packit Service |
21b5d1 |
: count > 5 ? 5
|
|
Packit Service |
21b5d1 |
: count
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
uint32_t pad = isStringType(type) ? 1 : 0;
|
|
Packit Service |
21b5d1 |
uint32_t size = isStringType(type) ? 1
|
|
Packit Service |
21b5d1 |
: is2ByteType(type) ? 2
|
|
Packit Service |
21b5d1 |
: is4ByteType(type) ? 4
|
|
Packit Service |
21b5d1 |
: is8ByteType(type) ? 8
|
|
Packit Service |
21b5d1 |
: 1
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// if ( offset > io.size() ) offset = 0; // Denial of service?
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// #55 and #56 memory allocation crash test/data/POC8
|
|
Packit Service |
21b5d1 |
long long allocate = (long long) size*count + pad+20;
|
|
Packit Service |
21b5d1 |
if ( allocate > (long long) io.size() ) {
|
|
Packit Service |
21b5d1 |
throw Error(kerInvalidMalloc);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
DataBuf buf((long)allocate); // allocate a buffer
|
|
Packit Service |
21b5d1 |
std::memset(buf.pData_, 0, buf.size_);
|
|
Packit Service |
21b5d1 |
std::memcpy(buf.pData_,dir.pData_+8,4); // copy dir[8:11] into buffer (short strings)
|
|
Packit Service |
21b5d1 |
const bool bOffsetIsPointer = count*size > 4;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( bOffsetIsPointer ) { // read into buffer
|
|
Packit Service |
21b5d1 |
size_t restore = io.tell(); // save
|
|
Packit Service |
21b5d1 |
io.seek(offset,BasicIo::beg); // position
|
|
Packit Service |
21b5d1 |
io.read(buf.pData_,count*size);// read
|
|
Packit Service |
21b5d1 |
io.seek(restore,BasicIo::beg); // restore
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( bPrint ) {
|
|
Packit Service |
21b5d1 |
const uint32_t address = start + 2 + i*12 ;
|
|
Packit Service |
21b5d1 |
const std::string offsetString = bOffsetIsPointer?
|
|
Packit Service |
21b5d1 |
Internal::stringFormat("%10u", offset):
|
|
Packit Service |
21b5d1 |
"";
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
out << Internal::indent(depth)
|
|
Packit Service |
21b5d1 |
<< Internal::stringFormat("%8u | %#06x %-28s |%10s |%9u |%10s | "
|
|
Packit Service |
21b5d1 |
,address,tag,tagName(tag).c_str(),typeName(type),count,offsetString.c_str());
|
|
Packit Service |
21b5d1 |
if ( isShortType(type) ){
|
|
Packit Service |
21b5d1 |
for ( size_t k = 0 ; k < kount ; k++ ) {
|
|
Packit Service |
21b5d1 |
out << sp << byteSwap2(buf,k*size,bSwap);
|
|
Packit Service |
21b5d1 |
sp = " ";
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
} else if ( isLongType(type) ){
|
|
Packit Service |
21b5d1 |
for ( size_t k = 0 ; k < kount ; k++ ) {
|
|
Packit Service |
21b5d1 |
out << sp << byteSwap4(buf,k*size,bSwap);
|
|
Packit Service |
21b5d1 |
sp = " ";
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} else if ( isRationalType(type) ){
|
|
Packit Service |
21b5d1 |
for ( size_t k = 0 ; k < kount ; k++ ) {
|
|
Packit Service |
21b5d1 |
uint32_t a = byteSwap4(buf,k*size+0,bSwap);
|
|
Packit Service |
21b5d1 |
uint32_t b = byteSwap4(buf,k*size+4,bSwap);
|
|
Packit Service |
21b5d1 |
out << sp << a << "/" << b;
|
|
Packit Service |
21b5d1 |
sp = " ";
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
} else if ( isStringType(type) ) {
|
|
Packit Service |
21b5d1 |
out << sp << Internal::binaryToString(makeSlice(buf, 0, kount));
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
sp = kount == count ? "" : " ...";
|
|
Packit Service |
21b5d1 |
out << sp << std::endl;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( option == kpsRecursive && (tag == 0x8769 /* ExifTag */ || tag == 0x014a/*SubIFDs*/ || type == tiffIfd) ) {
|
|
Packit Service |
21b5d1 |
for ( size_t k = 0 ; k < count ; k++ ) {
|
|
Packit Service |
21b5d1 |
size_t restore = io.tell();
|
|
Packit Service |
21b5d1 |
uint32_t offset = byteSwap4(buf,k*size,bSwap);
|
|
Packit Service |
21b5d1 |
printIFDStructure(io,out,option,offset,bSwap,c,depth);
|
|
Packit Service |
21b5d1 |
io.seek(restore,BasicIo::beg);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
} else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if (static_cast<size_t>(Safe::add(count, offset)) > io.size()) {
|
|
Packit Service |
21b5d1 |
throw Error(kerCorruptedMetadata);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const size_t restore = io.tell();
|
|
Packit Service |
21b5d1 |
io.seek(offset, BasicIo::beg); // position
|
|
Packit Service |
21b5d1 |
std::vector<byte> bytes(count) ; // allocate memory
|
|
Packit Service |
21b5d1 |
// TODO: once we have C++11 use bytes.data()
|
|
Packit Service |
21b5d1 |
const long read_bytes = io.read(&bytes[0], count);
|
|
Packit Service |
21b5d1 |
io.seek(restore, BasicIo::beg);
|
|
Packit Service |
21b5d1 |
// TODO: once we have C++11 use bytes.data()
|
|
Packit Service |
21b5d1 |
IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
|
|
Packit Service |
21b5d1 |
size_t restore = io.tell(); // save
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
uint32_t jump= 10 ;
|
|
Packit Service |
21b5d1 |
byte bytes[20] ;
|
|
Packit Service |
21b5d1 |
const char* chars = (const char*) &bytes[0] ;
|
|
Packit Service |
21b5d1 |
io.seek(offset,BasicIo::beg); // position
|
|
Packit Service |
21b5d1 |
io.read(bytes,jump ) ; // read
|
|
Packit Service |
21b5d1 |
bytes[jump]=0 ;
|
|
Packit Service |
21b5d1 |
if ( ::strcmp("Nikon",chars) == 0 ) {
|
|
Packit Service |
21b5d1 |
// tag is an embedded tiff
|
|
Packit Service |
21b5d1 |
byte* bytes=new byte[count-jump] ; // allocate memory
|
|
Packit Service |
21b5d1 |
io.read(bytes,count-jump) ; // read
|
|
Packit Service |
21b5d1 |
MemIo memIo(bytes,count-jump) ; // create a file
|
|
Packit Service |
21b5d1 |
printTiffStructure(memIo,out,option,depth);
|
|
Packit Service |
21b5d1 |
delete[] bytes ; // free
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
// tag is an IFD
|
|
Packit Service |
21b5d1 |
io.seek(0,BasicIo::beg); // position
|
|
Packit Service |
21b5d1 |
printIFDStructure(io,out,option,offset,bSwap,c,depth);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
io.seek(restore,BasicIo::beg); // restore
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( isPrintXMP(tag,option) ) {
|
|
Packit Service |
21b5d1 |
buf.pData_[count]=0;
|
|
Packit Service |
21b5d1 |
out << (char*) buf.pData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( isPrintICC(tag,option) ) {
|
|
Packit Service |
21b5d1 |
out.write((const char*)buf.pData_,count);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( start ) {
|
|
Packit Service |
21b5d1 |
io.read(dir.pData_, 4);
|
|
Packit Service |
21b5d1 |
start = tooBig ? 0 : byteSwap4(dir,0,bSwap);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
} while (start) ;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( bPrint ) {
|
|
Packit Service |
21b5d1 |
out << Internal::indent(depth) << "END " << io.path() << std::endl;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
out.flush();
|
|
Packit Service |
21b5d1 |
depth--;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::printTiffStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,int depth,size_t offset /*=0*/)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if ( option == kpsBasic || option == kpsXMP || option == kpsRecursive || option == kpsIccProfile ) {
|
|
Packit Service |
21b5d1 |
// buffer
|
|
Packit Service |
21b5d1 |
const size_t dirSize = 32;
|
|
Packit Service |
21b5d1 |
DataBuf dir(dirSize);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// read header (we already know for certain that we have a Tiff file)
|
|
Packit Service |
21b5d1 |
io.read(dir.pData_, 8);
|
|
Packit Service |
21b5d1 |
char c = (char) dir.pData_[0] ;
|
|
Packit Service |
21b5d1 |
bool bSwap = ( c == 'M' && isLittleEndianPlatform() )
|
|
Packit Service |
21b5d1 |
|| ( c == 'I' && isBigEndianPlatform() )
|
|
Packit Service |
21b5d1 |
;
|
|
Packit Service |
21b5d1 |
uint32_t start = byteSwap4(dir,4,bSwap);
|
|
Packit Service |
21b5d1 |
printIFDStructure(io,out,option,start+(uint32_t)offset,bSwap,c,depth);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearMetadata()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
clearExifData();
|
|
Packit Service |
21b5d1 |
clearIptcData();
|
|
Packit Service |
21b5d1 |
clearXmpPacket();
|
|
Packit Service |
21b5d1 |
clearXmpData();
|
|
Packit Service |
21b5d1 |
clearComment();
|
|
Packit Service |
21b5d1 |
clearIccProfile();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
ExifData& Image::exifData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return exifData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
IptcData& Image::iptcData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return iptcData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XmpData& Image::xmpData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return xmpData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
std::string& Image::xmpPacket()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
// Serialize the current XMP
|
|
Packit Service |
21b5d1 |
if (xmpData_.count() > 0 && !writeXmpFromPacket()) {
|
|
Packit Service |
21b5d1 |
XmpParser::encode(xmpPacket_, xmpData_,
|
|
Packit Service |
21b5d1 |
XmpParser::useCompactFormat |
|
|
Packit Service |
21b5d1 |
XmpParser::omitAllFormatting);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return xmpPacket_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setMetadata(const Image& image)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if (checkMode(mdExif) & amWrite) {
|
|
Packit Service |
21b5d1 |
setExifData(image.exifData());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if (checkMode(mdIptc) & amWrite) {
|
|
Packit Service |
21b5d1 |
setIptcData(image.iptcData());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if (checkMode(mdIccProfile) & amWrite && iccProfile()) {
|
|
Packit Service |
21b5d1 |
setIccProfile(*iccProfile());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if (checkMode(mdXmp) & amWrite) {
|
|
Packit Service |
21b5d1 |
setXmpPacket(image.xmpPacket());
|
|
Packit Service |
21b5d1 |
setXmpData(image.xmpData());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if (checkMode(mdComment) & amWrite) {
|
|
Packit Service |
21b5d1 |
setComment(image.comment());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearExifData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
exifData_.clear();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setExifData(const ExifData& exifData)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
exifData_ = exifData;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearIptcData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
iptcData_.clear();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setIptcData(const IptcData& iptcData)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
iptcData_ = iptcData;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearXmpPacket()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
xmpPacket_.clear();
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket(true);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setXmpPacket(const std::string& xmpPacket)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
xmpPacket_ = xmpPacket;
|
|
Packit Service |
21b5d1 |
if ( XmpParser::decode(xmpData_, xmpPacket) ) {
|
|
Packit Service |
21b5d1 |
throw Error(kerInvalidXMP);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
xmpPacket_ = xmpPacket;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearXmpData()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
xmpData_.clear();
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket(false);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setXmpData(const XmpData& xmpData)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
xmpData_ = xmpData;
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket(false);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_HAVE_XMP_TOOLKIT
|
|
Packit Service |
21b5d1 |
void Image::writeXmpFromPacket(bool flag)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
writeXmpFromPacket_ = flag;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
#else
|
|
Packit Service |
21b5d1 |
void Image::writeXmpFromPacket(bool) {}
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearComment()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
comment_.erase();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setComment(const std::string& comment)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
comment_ = comment;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setIccProfile(Exiv2::DataBuf& iccProfile,bool bTestValid)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if ( bTestValid ) {
|
|
Packit Service |
21b5d1 |
if ( iccProfile.pData_ && ( iccProfile.size_ < (long) sizeof(long)) ) throw Error(kerInvalidIccProfile);
|
|
Packit Service |
21b5d1 |
long size = iccProfile.pData_ ? getULong(iccProfile.pData_, bigEndian): -1;
|
|
Packit Service |
21b5d1 |
if ( size!= iccProfile.size_ ) throw Error(kerInvalidIccProfile);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
iccProfile_ = iccProfile;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::clearIccProfile()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
iccProfile_.free();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void Image::setByteOrder(ByteOrder byteOrder)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
byteOrder_ = byteOrder;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
ByteOrder Image::byteOrder() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return byteOrder_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
int Image::pixelWidth() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return pixelWidth_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
int Image::pixelHeight() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return pixelHeight_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const ExifData& Image::exifData() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return exifData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const IptcData& Image::iptcData() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return iptcData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XmpData& Image::xmpData() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return xmpData_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
std::string Image::comment() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return comment_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const std::string& Image::xmpPacket() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return xmpPacket_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
BasicIo& Image::io() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return *io_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool Image::writeXmpFromPacket() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return writeXmpFromPacket_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const NativePreviewList& Image::nativePreviews() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return nativePreviews_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool Image::good() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if (io_->open() != 0) return false;
|
|
Packit Service |
21b5d1 |
IoCloser closer(*io_);
|
|
Packit Service |
21b5d1 |
return ImageFactory::checkType(imageType_, *io_, false);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool Image::supportsMetadata(MetadataId metadataId) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return (supportedMetadata_ & metadataId) != 0;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
AccessMode Image::checkMode(MetadataId metadataId) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
return ImageFactory::checkMode(imageType_, metadataId);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const std::string& Image::tagName(uint16_t tag)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if ( init_ ) {
|
|
Packit Service |
21b5d1 |
int idx;
|
|
Packit Service |
21b5d1 |
const TagInfo* ti ;
|
|
Packit Service |
21b5d1 |
for (ti = Internal:: mnTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal:: iopTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal:: gpsTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal:: ifdTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal::exifTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal:: mpfTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
for (ti = Internal::Nikon1MakerNote::tagList(), idx = 0
|
|
Packit Service |
21b5d1 |
; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
init_ = false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return tags_[tag] ;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
AccessMode ImageFactory::checkMode(int type, MetadataId metadataId)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
const Registry* r = find(registry, type);
|
|
Packit Service |
21b5d1 |
if (!r) throw Error(kerUnsupportedImageType, type);
|
|
Packit Service |
21b5d1 |
AccessMode am = amNone;
|
|
Packit Service |
21b5d1 |
switch (metadataId) {
|
|
Packit Service |
21b5d1 |
case mdNone:
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
case mdExif:
|
|
Packit Service |
21b5d1 |
am = r->exifSupport_;
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
case mdIptc:
|
|
Packit Service |
21b5d1 |
am = r->iptcSupport_;
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
case mdXmp:
|
|
Packit Service |
21b5d1 |
am = r->xmpSupport_;
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
case mdComment:
|
|
Packit Service |
21b5d1 |
am = r->commentSupport_;
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
case mdIccProfile: break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// no default: let the compiler complain
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return am;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
bool ImageFactory::checkType(int type, BasicIo& io, bool advance)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
const Registry* r = find(registry, type);
|
|
Packit Service |
21b5d1 |
if (0 != r) {
|
|
Packit Service |
21b5d1 |
return r->isThisType_(io, advance);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return false;
|
|
Packit Service |
21b5d1 |
} // ImageFactory::checkType
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
int ImageFactory::getType(const std::string& path)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
FileIo fileIo(path);
|
|
Packit Service |
21b5d1 |
return getType(fileIo);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_UNICODE_PATH
|
|
Packit Service |
21b5d1 |
int ImageFactory::getType(const std::wstring& wpath)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
FileIo fileIo(wpath);
|
|
Packit Service |
21b5d1 |
return getType(fileIo);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
int ImageFactory::getType(const byte* data, long size)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
MemIo memIo(data, size);
|
|
Packit Service |
21b5d1 |
return getType(memIo);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
int ImageFactory::getType(BasicIo& io)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if (io.open() != 0) return ImageType::none;
|
|
Packit Service |
21b5d1 |
IoCloser closer(io);
|
|
Packit Service |
21b5d1 |
for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
|
|
Packit Service |
21b5d1 |
if (registry[i].isThisType_(io, false)) {
|
|
Packit Service |
21b5d1 |
return registry[i].imageType_;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return ImageType::none;
|
|
Packit Service |
21b5d1 |
} // ImageFactory::getType
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr ImageFactory::createIo(const std::string& path, bool useCurl)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
Protocol fProt = fileProtocol(path);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_USE_SSH
|
|
Packit Service |
21b5d1 |
if (fProt == pSsh || fProt == pSftp) {
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new SshIo(path)); // may throw
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_USE_CURL
|
|
Packit Service |
21b5d1 |
if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) {
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new CurlIo(path)); // may throw
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if (fProt == pHttp)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new HttpIo(path)); // may throw
|
|
Packit Service |
21b5d1 |
if (fProt == pFileUri)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new FileIo(pathOfFileUrl(path)));
|
|
Packit Service |
21b5d1 |
if (fProt == pStdin || fProt == pDataUri)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new XPathIo(path)); // may throw
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new FileIo(path));
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
(void)(useCurl);
|
|
Packit Service |
21b5d1 |
} // ImageFactory::createIo
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_UNICODE_PATH
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr ImageFactory::createIo(const std::wstring& wpath, bool useCurl)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
Protocol fProt = fileProtocol(wpath);
|
|
Packit Service |
21b5d1 |
#if EXV_USE_SSH == 1
|
|
Packit Service |
21b5d1 |
if (fProt == pSsh || fProt == pSftp) {
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new SshIo(wpath));
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
#if EXV_USE_CURL == 1
|
|
Packit Service |
21b5d1 |
if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) {
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new CurlIo(wpath));
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
if (fProt == pHttp)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new HttpIo(wpath));
|
|
Packit Service |
21b5d1 |
if (fProt == pFileUri)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new FileIo(pathOfFileUrl(wpath)));
|
|
Packit Service |
21b5d1 |
if (fProt == pStdin || fProt == pDataUri)
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new XPathIo(wpath)); // may throw
|
|
Packit Service |
21b5d1 |
return BasicIo::AutoPtr(new FileIo(wpath));
|
|
Packit Service |
21b5d1 |
} // ImageFactory::createIo
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::open(const std::string& path, bool useCurl)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = open(ImageFactory::createIo(path, useCurl)); // may throw
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw Error(kerFileContainsUnknownImageType, path);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_UNICODE_PATH
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::open(const std::wstring& wpath, bool useCurl)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = open(ImageFactory::createIo(wpath, useCurl)); // may throw
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw WError(kerFileContainsUnknownImageType, wpath);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::open(const byte* data, long size)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io(new MemIo(data, size));
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = open(io); // may throw
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw Error(kerMemoryContainsUnknownImageType);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::open(BasicIo::AutoPtr io)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if (io->open() != 0) {
|
|
Packit Service |
21b5d1 |
throw Error(kerDataSourceOpenFailed, io->path(), strError());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
|
|
Packit Service |
21b5d1 |
if (registry[i].isThisType_(*io, false)) {
|
|
Packit Service |
21b5d1 |
return registry[i].newInstance_(io, false);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return Image::AutoPtr();
|
|
Packit Service |
21b5d1 |
} // ImageFactory::open
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::create(int type,
|
|
Packit Service |
21b5d1 |
const std::string& path)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
std::auto_ptr<FileIo> fileIo(new FileIo(path));
|
|
Packit Service |
21b5d1 |
// Create or overwrite the file, then close it
|
|
Packit Service |
21b5d1 |
if (fileIo->open("w+b") != 0) {
|
|
Packit Service |
21b5d1 |
throw Error(kerFileOpenFailed, path, "w+b", strError());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
fileIo->close();
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io(fileIo);
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = create(type, io);
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw Error(kerUnsupportedImageType, type);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#ifdef EXV_UNICODE_PATH
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::create(int type,
|
|
Packit Service |
21b5d1 |
const std::wstring& wpath)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
std::auto_ptr<FileIo> fileIo(new FileIo(wpath));
|
|
Packit Service |
21b5d1 |
// Create or overwrite the file, then close it
|
|
Packit Service |
21b5d1 |
if (fileIo->open("w+b") != 0) {
|
|
Packit Service |
21b5d1 |
throw WError(kerFileOpenFailed, wpath, "w+b", strError().c_str());
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
fileIo->close();
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io(fileIo);
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = create(type, io);
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw Error(kerUnsupportedImageType, type);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::create(int type)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io(new MemIo);
|
|
Packit Service |
21b5d1 |
Image::AutoPtr image = create(type, io);
|
|
Packit Service |
21b5d1 |
if (image.get() == 0) throw Error(kerUnsupportedImageType, type);
|
|
Packit Service |
21b5d1 |
return image;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
Image::AutoPtr ImageFactory::create(int type,
|
|
Packit Service |
21b5d1 |
BasicIo::AutoPtr io)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
// BasicIo instance does not need to be open
|
|
Packit Service |
21b5d1 |
const Registry* r = find(registry, type);
|
|
Packit Service |
21b5d1 |
if (0 != r) {
|
|
Packit Service |
21b5d1 |
return r->newInstance_(io, true);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return Image::AutoPtr();
|
|
Packit Service |
21b5d1 |
} // ImageFactory::create
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *****************************************************************************
|
|
Packit Service |
21b5d1 |
// template, inline and free functions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void append(Blob& blob, const byte* buf, uint32_t len)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if (len != 0) {
|
|
Packit Service |
21b5d1 |
assert(buf != 0);
|
|
Packit Service |
21b5d1 |
Blob::size_type size = blob.size();
|
|
Packit Service |
21b5d1 |
if (blob.capacity() - size < len) {
|
|
Packit Service |
21b5d1 |
blob.reserve(size + 65536);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
blob.resize(size + len);
|
|
Packit Service |
21b5d1 |
std::memcpy(&blob[size], buf, len);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
} // append
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // namespace Exiv2
|