Revamped image and introduced byte* interface (Brad, bs_1.patch with minor modifications by ahu)
This commit is contained in:
parent
964e1df085
commit
9d72b7d1ec
@ -104,3 +104,12 @@
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* File path seperator */
|
||||
#ifdef _MSC_VER
|
||||
#define SEPERATOR_STR "\\"
|
||||
#define SEPERATOR_CHR '\\'
|
||||
#else
|
||||
#define SEPERATOR_STR "/"
|
||||
#define SEPERATOR_CHR '/'
|
||||
#endif
|
||||
|
||||
28
src/Makefile
28
src/Makefile
@ -61,13 +61,19 @@ BINSRC = addmoddel.cpp exifcomment.cpp exifprint.cpp ifd-test.cpp \
|
||||
# State the main source file of the Exiv2 application here
|
||||
EXIV2MAIN = exiv2.cpp
|
||||
|
||||
# Add additional source files of the real application to this list
|
||||
# Add additional source files of the Exiv2 application to this list
|
||||
EXIV2SRC = actions.cpp utils.cpp
|
||||
# C source files of the application
|
||||
# C source files of the Exiv2 application
|
||||
ifndef HAVE_TIMEGM
|
||||
EXIVCSRC = localtime.c
|
||||
endif
|
||||
|
||||
# State the main source file of the metacopy application here
|
||||
MCMAIN = metacopy.cpp
|
||||
|
||||
# Add additional source files of the metacopy application to this list
|
||||
MCSRC = utils.cpp
|
||||
|
||||
# ******************************************************************************
|
||||
# Library
|
||||
|
||||
@ -101,7 +107,8 @@ HDR = $(CCHDR)
|
||||
OBJ = $(CCOBJ)
|
||||
SOBJ = $(CCSOBJ)
|
||||
DEP = $(CCSRC:%.cpp=.%.d) $(BINSRC:%.cpp=.%.d) \
|
||||
$(EXIV2MAIN:%.cpp=.%.d) $(EXIV2SRC:%.cpp=.%.d) $(EXIVCSRC:%.c=.%.d)
|
||||
$(EXIV2MAIN:%.cpp=.%.d) $(EXIV2SRC:%.cpp=.%.d) $(EXIVCSRC:%.c=.%.d) \
|
||||
$(MCMAIN:%.cpp=.%.d) $(MCSRC:%.cpp=.%.d)
|
||||
|
||||
BINOBJ = $(BINSRC:.cpp=.o)
|
||||
BINARY = $(BINSRC:.cpp=)
|
||||
@ -109,6 +116,10 @@ BINARY = $(BINSRC:.cpp=)
|
||||
EXIV2OBJ = $(EXIV2MAIN:.cpp=.o) $(EXIV2SRC:.cpp=.o) $(EXIVCSRC:.c=.o)
|
||||
EXIV2BIN = $(EXIV2MAIN:.cpp=)
|
||||
|
||||
MCOBJ = $(MCMAIN:.cpp=.o) $(MCSRC:.cpp=.o)
|
||||
MCBIN = $(MCMAIN:.cpp=)
|
||||
|
||||
|
||||
ARCHIVE = lib$(LIBNAME)$(ARCHIVE_SUFFIX)
|
||||
SHAREDLIB = lib$(LIBNAME)$(SHAREDLIB_SUFFIX)
|
||||
|
||||
@ -179,6 +190,9 @@ $(BINARY): %: %.o
|
||||
$(EXIV2BIN): %: %.o
|
||||
$(CXX) $(CXXFLAGS) $(EXIV2OBJ) $(LDLIBS) $(LDFLAGS_BIN) -o $@
|
||||
|
||||
$(MCBIN): %: %.o
|
||||
$(CXX) $(CXXFLAGS) $(MCOBJ) $(LDLIBS) $(LDFLAGS_BIN) -o $@
|
||||
|
||||
mn.cpp: ./mn.sh
|
||||
./mn.sh
|
||||
|
||||
@ -217,7 +231,9 @@ endif
|
||||
|
||||
$(EXIV2BIN): lib $(EXIV2OBJ)
|
||||
|
||||
bin: lib $(BINARY) $(EXIV2BIN)
|
||||
$(MCBIN): lib $(MCOBJ)
|
||||
|
||||
bin: lib $(BINARY) $(EXIV2BIN) $(MCBIN)
|
||||
|
||||
install: $(INSTALL)
|
||||
$(INSTALL_DIRS) $(bindir)
|
||||
@ -278,7 +294,7 @@ check:
|
||||
mostlyclean:
|
||||
$(RM) core
|
||||
$(RM) $(CCSRC:.cpp=.ii)
|
||||
$(RM) $(OBJ) $(SOBJ) $(BINOBJ) $(EXIV2OBJ)
|
||||
$(RM) $(OBJ) $(SOBJ) $(BINOBJ) $(EXIV2OBJ) $(MCOBJ)
|
||||
$(RM) mn.o
|
||||
@if test -n "$(CXX_REPOSITORY)"; then \
|
||||
echo "rm -rf $(CXX_REPOSITORY)"; \
|
||||
@ -287,7 +303,7 @@ mostlyclean:
|
||||
|
||||
clean: mostlyclean
|
||||
$(RM) $(ARCHIVE) $(SHAREDLIB)
|
||||
$(RM) $(BINARY) $(EXIV2BIN)
|
||||
$(RM) $(BINARY) $(EXIV2BIN) $(MCBIN)
|
||||
|
||||
# Run `make distclean' from the top source directory to also remove
|
||||
# files created by configuring the program.
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: actions.cpp
|
||||
Version: $Name: $ $Revision: 1.30 $
|
||||
Version: $Name: $ $Revision: 1.31 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 08-Dec-03, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.30 $ $RCSfile: actions.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.31 $ $RCSfile: actions.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -513,7 +513,7 @@ namespace Action {
|
||||
return 1;
|
||||
}
|
||||
std::string newPath
|
||||
= Util::dirname(path) + "/" + basename + Util::suffix(path);
|
||||
= Util::dirname(path) + SEPERATOR_STR + basename + Util::suffix(path);
|
||||
if ( Util::dirname(newPath) == Util::dirname(path)
|
||||
&& Util::basename(newPath) == Util::basename(path)) {
|
||||
if (Params::instance().verbose_) {
|
||||
@ -647,7 +647,7 @@ namespace Action {
|
||||
|
||||
int Extract::writeExifData(Exiv2::ExifData& exifData) const
|
||||
{
|
||||
std::string exvPath = Util::dirname(path_) + "/"
|
||||
std::string exvPath = Util::dirname(path_) + SEPERATOR_STR
|
||||
+ Util::basename(path_, true) + ".exv";
|
||||
if (Params::instance().verbose_) {
|
||||
std::cout << "Writing Exif data to " << exvPath << "\n";
|
||||
@ -669,7 +669,7 @@ namespace Action {
|
||||
int Extract::writeThumbnail(const Exiv2::ExifData& exifData) const
|
||||
{
|
||||
int rc = 0;
|
||||
std::string thumb = Util::dirname(path_) + "/"
|
||||
std::string thumb = Util::dirname(path_) + SEPERATOR_STR
|
||||
+ Util::basename(path_, true) + "-thumb";
|
||||
std::string thumbExt = exifData.thumbnailExtension();
|
||||
if (thumbExt.empty()) {
|
||||
@ -709,7 +709,7 @@ namespace Action {
|
||||
|
||||
int Insert::run(const std::string& path)
|
||||
try {
|
||||
std::string exvPath = Util::dirname(path) + "/"
|
||||
std::string exvPath = Util::dirname(path) + SEPERATOR_STR
|
||||
+ Util::basename(path, true) + ".exv";
|
||||
Exiv2::ExifData exifData;
|
||||
int rc = exifData.read(exvPath);
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: canonmn.cpp
|
||||
Version: $Name: $ $Revision: 1.10 $
|
||||
Version: $Name: $ $Revision: 1.11 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
07-Mar-04, ahu: isolated as a separate component
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: canonmn.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: canonmn.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -553,7 +553,8 @@ namespace Exiv2 {
|
||||
}
|
||||
if (value.count() < 26) return os;
|
||||
|
||||
float fu = value.toLong(25);
|
||||
// Todo: why not use toFloat()?
|
||||
float fu = static_cast<float>(value.toLong(25));
|
||||
float len1 = value.toLong(23) / fu;
|
||||
float len2 = value.toLong(24) / fu;
|
||||
std::ostringstream oss;
|
||||
@ -656,7 +657,7 @@ namespace Exiv2 {
|
||||
// free functions
|
||||
|
||||
MakerNote* createCanonMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
|
||||
@ -23,10 +23,10 @@
|
||||
@brief Canon MakerNote implemented according to the specification
|
||||
<a href="http://www.burren.cx/david/canon.html">
|
||||
EXIF MakerNote of Canon</a> by David Burren
|
||||
@version $Name: $ $Revision: 1.8 $
|
||||
@version $Name: $ $Revision: 1.9 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 18-Feb-04, ahu: created
|
||||
@date 18-Feb-04, ahu: created<BR>
|
||||
07-Mar-04, ahu: isolated as a separate component
|
||||
*/
|
||||
#ifndef CANONMN_HPP_
|
||||
@ -73,7 +73,7 @@ namespace Exiv2 {
|
||||
this copy and is responsible to delete it!
|
||||
*/
|
||||
MakerNote* createCanonMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
|
||||
@ -21,10 +21,10 @@
|
||||
/*!
|
||||
@file error.hpp
|
||||
@brief Error class for exceptions
|
||||
@version $Name: $ $Revision: 1.2 $
|
||||
@version $Name: $ $Revision: 1.3 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Jan-04, ahu: created
|
||||
@date 15-Jan-04, ahu: created<BR>
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
#ifndef ERROR_HPP_
|
||||
|
||||
112
src/exif.cpp
112
src/exif.cpp
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: exif.cpp
|
||||
Version: $Name: $ $Revision: 1.48 $
|
||||
Version: $Name: $ $Revision: 1.49 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.48 $ $RCSfile: exif.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.49 $ $RCSfile: exif.cpp,v $")
|
||||
|
||||
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -173,7 +173,7 @@ namespace Exiv2 {
|
||||
ifd_(ifd1, 0, false)
|
||||
{
|
||||
if (rhs.pImage_ && rhs.size_ > 0) {
|
||||
pImage_ = new char[rhs.size_];
|
||||
pImage_ = new byte[rhs.size_];
|
||||
memcpy(pImage_, rhs.pImage_, rhs.size_);
|
||||
tiffHeader_.read(pImage_);
|
||||
ifd_.read(pImage_ + tiffHeader_.offset(),
|
||||
@ -184,9 +184,9 @@ namespace Exiv2 {
|
||||
|
||||
TiffThumbnail& TiffThumbnail::operator=(const TiffThumbnail& rhs)
|
||||
{
|
||||
char* pNewImage = 0;
|
||||
byte* pNewImage = 0;
|
||||
if (rhs.pImage_ && rhs.size_ > 0) {
|
||||
pNewImage = new char[rhs.size_];
|
||||
pNewImage = new byte[rhs.size_];
|
||||
memcpy(pNewImage, rhs.pImage_, rhs.size_);
|
||||
tiffHeader_.read(rhs.pImage_);
|
||||
ifd_.read(pNewImage + tiffHeader_.offset(),
|
||||
@ -200,7 +200,7 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
int TiffThumbnail::read(const char* buf,
|
||||
int TiffThumbnail::read(const byte* buf,
|
||||
long len,
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder)
|
||||
@ -276,7 +276,7 @@ namespace Exiv2 {
|
||||
ifd1.copy(img.pData_ + ifdOffset, tiffHeader.byteOrder(), ifdOffset);
|
||||
|
||||
delete[] pImage_;
|
||||
pImage_ = new char[buflen];
|
||||
pImage_ = new byte[buflen];
|
||||
memcpy(pImage_, img.pData_, buflen);
|
||||
size_ = buflen;
|
||||
offset_ = minOffset;
|
||||
@ -302,11 +302,12 @@ namespace Exiv2 {
|
||||
int TiffThumbnail::write(const std::string& path) const
|
||||
{
|
||||
std::string name = path + extension();
|
||||
std::ofstream file(name.c_str(), std::ios::binary);
|
||||
if (!file) return -1;
|
||||
file.write(pImage_, size_);
|
||||
if (!file.good()) return 4;
|
||||
return 0;
|
||||
FILE *ofp = fopen(name.c_str(), "wb");
|
||||
if (!ofp) return -1;
|
||||
int rc = 0;
|
||||
if (fwrite(pImage_, 1, size_, ofp) != (size_t)size_) rc = 4;
|
||||
fclose(ofp);
|
||||
return rc;
|
||||
} // TiffThumbnail::write
|
||||
|
||||
void TiffThumbnail::update(ExifData& exifData) const
|
||||
@ -338,7 +339,7 @@ namespace Exiv2 {
|
||||
|
||||
} // TiffThumbnail::update
|
||||
|
||||
long TiffThumbnail::copy(char* buf) const
|
||||
long TiffThumbnail::copy(byte* buf) const
|
||||
{
|
||||
long offset = ifd_.offset() + ifd_.size() + ifd_.dataSize();
|
||||
long size = size_ - offset;
|
||||
@ -402,16 +403,16 @@ namespace Exiv2 {
|
||||
: offset_(rhs.offset_), size_(rhs.size_), pImage_(0)
|
||||
{
|
||||
if (rhs.pImage_ && rhs.size_ > 0) {
|
||||
pImage_ = new char[rhs.size_];
|
||||
pImage_ = new byte[rhs.size_];
|
||||
memcpy(pImage_, rhs.pImage_, rhs.size_);
|
||||
}
|
||||
}
|
||||
|
||||
JpegThumbnail& JpegThumbnail::operator=(const JpegThumbnail& rhs)
|
||||
{
|
||||
char* pNewImage = 0;
|
||||
byte* pNewImage = 0;
|
||||
if (rhs.pImage_ && rhs.size_ > 0) {
|
||||
pNewImage = new char[rhs.size_];
|
||||
pNewImage = new byte[rhs.size_];
|
||||
memcpy(pNewImage, rhs.pImage_, rhs.size_);
|
||||
}
|
||||
offset_ = rhs.offset_;
|
||||
@ -421,7 +422,7 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
int JpegThumbnail::read(const char* buf,
|
||||
int JpegThumbnail::read(const byte* buf,
|
||||
long len,
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder)
|
||||
@ -436,7 +437,7 @@ namespace Exiv2 {
|
||||
long size = pos->toLong();
|
||||
if (len < offset + size) return 1;
|
||||
delete[] pImage_;
|
||||
pImage_ = new char[size];
|
||||
pImage_ = new byte[size];
|
||||
memcpy(pImage_, buf + offset, size);
|
||||
size_ = size;
|
||||
offset_ = offset;
|
||||
@ -456,11 +457,12 @@ namespace Exiv2 {
|
||||
int JpegThumbnail::write(const std::string& path) const
|
||||
{
|
||||
std::string name = path + extension();
|
||||
std::ofstream file(name.c_str(), std::ios::binary);
|
||||
if (!file) return -1;
|
||||
file.write(pImage_, size_);
|
||||
if (!file.good()) return 4;
|
||||
return 0;
|
||||
FILE *ofp = fopen(name.c_str(), "wb");
|
||||
if (!ofp) return -1;
|
||||
int rc = 0;
|
||||
if (fwrite(pImage_, 1, size_, ofp) != (size_t)size_) rc = 4;
|
||||
fclose(ofp);
|
||||
return rc;
|
||||
} // JpegThumbnail::write
|
||||
|
||||
void JpegThumbnail::update(ExifData& exifData) const
|
||||
@ -487,7 +489,7 @@ namespace Exiv2 {
|
||||
|
||||
} // JpegThumbnail::update
|
||||
|
||||
long JpegThumbnail::copy(char* buf) const
|
||||
long JpegThumbnail::copy(byte* buf) const
|
||||
{
|
||||
memcpy(buf, pImage_, size_);
|
||||
return size_;
|
||||
@ -533,30 +535,25 @@ namespace Exiv2 {
|
||||
|
||||
int ExifData::read(const std::string& path)
|
||||
{
|
||||
std::ifstream file(path.c_str(), std::ios::binary);
|
||||
if (!file) return -1;
|
||||
Image* pImage = ImageFactory::instance().create(file);
|
||||
Image* pImage = ImageFactory::instance().open(path);
|
||||
// Todo: if (!pImage) return -1;
|
||||
if (pImage) {
|
||||
int rc = pImage->readExifData(file);
|
||||
if (rc == 0) rc = read(pImage->exifData(), pImage->sizeExifData());
|
||||
int rc = pImage->readMetadata();
|
||||
if (rc == 0 && pImage->sizeExifData() > 0 ) {
|
||||
rc = read(pImage->exifData(), pImage->sizeExifData());
|
||||
}
|
||||
delete pImage;
|
||||
return rc;
|
||||
}
|
||||
if (ExvFile::isThisType(file)) {
|
||||
ExvFile exvFile;
|
||||
int rc = exvFile.readExifData(file);
|
||||
if (rc == 0) rc = read(exvFile.exifData(), exvFile.sizeExifData());
|
||||
return rc;
|
||||
}
|
||||
// We don't know this type of file
|
||||
return -2;
|
||||
}
|
||||
|
||||
int ExifData::read(const char* buf, long len)
|
||||
int ExifData::read(const byte* buf, long len)
|
||||
{
|
||||
// Copy the data buffer
|
||||
delete[] pData_;
|
||||
pData_ = new char[len];
|
||||
pData_ = new byte[len];
|
||||
memcpy(pData_, buf, len);
|
||||
size_ = len;
|
||||
|
||||
@ -581,8 +578,9 @@ namespace Exiv2 {
|
||||
if (pos != exifIfd_.end() && make != ifd0_.end() && model != ifd0_.end()) {
|
||||
MakerNoteFactory& mnf = MakerNoteFactory::instance();
|
||||
// Todo: The conversion to string assumes that there is a \0 at the end
|
||||
pMakerNote_ = mnf.create(make->data(),
|
||||
model->data(),
|
||||
// Todo: How to avoid the cast (is that a MSVC thing?)
|
||||
pMakerNote_ = mnf.create(reinterpret_cast<const char*>(make->data()),
|
||||
reinterpret_cast<const char*>(model->data()),
|
||||
false,
|
||||
pos->data(),
|
||||
pos->size(),
|
||||
@ -654,13 +652,15 @@ namespace Exiv2 {
|
||||
|
||||
int ExifData::erase(const std::string& path) const
|
||||
{
|
||||
std::ifstream is(path.c_str(), std::ios::binary);
|
||||
if (!is) return -1;
|
||||
Image* pImage = ImageFactory::instance().create(is);
|
||||
is.close();
|
||||
Image* pImage = ImageFactory::instance().open(path);
|
||||
if (pImage == 0) return -2;
|
||||
|
||||
int rc = pImage->eraseExifData(path);
|
||||
// Read all metadata then erase only Exif data
|
||||
int rc = pImage->readMetadata();
|
||||
if (rc == 0) {
|
||||
pImage->clearExifData();
|
||||
rc = pImage->writeMetadata();
|
||||
}
|
||||
delete pImage;
|
||||
return rc;
|
||||
} // ExifData::erase
|
||||
@ -670,23 +670,24 @@ namespace Exiv2 {
|
||||
// Remove the Exif section from the file if there is no metadata
|
||||
if (count() == 0 && !pThumbnail_) return erase(path);
|
||||
|
||||
std::ifstream is(path.c_str(), std::ios::binary);
|
||||
if (!is) return -1;
|
||||
Image* pImage = ImageFactory::instance().create(is);
|
||||
is.close();
|
||||
Image* pImage = ImageFactory::instance().open(path);
|
||||
if (pImage == 0) return -2;
|
||||
|
||||
DataBuf buf(size());
|
||||
long actualSize = copy(buf.pData_);
|
||||
assert(actualSize <= buf.size_);
|
||||
|
||||
pImage->setExifData(buf.pData_, actualSize);
|
||||
int rc = pImage->writeExifData(path);
|
||||
// Read all metadata to preserve non-Exif data
|
||||
int rc = pImage->readMetadata();
|
||||
if (rc == 0) {
|
||||
pImage->setExifData(buf.pData_, actualSize);
|
||||
rc = pImage->writeMetadata();
|
||||
}
|
||||
delete pImage;
|
||||
return rc;
|
||||
} // ExifData::write
|
||||
|
||||
long ExifData::copy(char* buf)
|
||||
long ExifData::copy(byte* buf)
|
||||
{
|
||||
long size = 0;
|
||||
// If we can update the internal IFDs and the underlying data buffer
|
||||
@ -709,7 +710,7 @@ namespace Exiv2 {
|
||||
return size;
|
||||
}
|
||||
|
||||
long ExifData::copyFromMetadata(char* buf)
|
||||
long ExifData::copyFromMetadata(byte* buf)
|
||||
{
|
||||
// Build IFD0
|
||||
Ifd ifd0(ifd0);
|
||||
@ -873,9 +874,10 @@ namespace Exiv2 {
|
||||
long actualSize = copy(buf.pData_);
|
||||
assert(actualSize <= buf.size_);
|
||||
|
||||
ExvFile exvFile;
|
||||
exvFile.setExifData(buf.pData_, actualSize);
|
||||
return exvFile.writeExifData(path);
|
||||
ExvImage exvImage(path, true);
|
||||
if (!exvImage.good()) return -2;
|
||||
exvImage.setExifData(buf.pData_, actualSize);
|
||||
return exvImage.writeMetadata();
|
||||
} // ExifData::writeExifData
|
||||
|
||||
void ExifData::add(Entries::const_iterator begin,
|
||||
|
||||
30
src/exif.hpp
30
src/exif.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file exif.hpp
|
||||
@brief Encoding and decoding of Exif data
|
||||
@version $Name: $ $Revision: 1.47 $
|
||||
@version $Name: $ $Revision: 1.48 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@ -126,7 +126,7 @@ namespace Exiv2 {
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@return Number of characters written.
|
||||
*/
|
||||
long copy(char* buf, ByteOrder byteOrder) const
|
||||
long copy(byte* buf, ByteOrder byteOrder) const
|
||||
{ return pValue_ == 0 ? 0 : pValue_->copy(buf, byteOrder); }
|
||||
/*!
|
||||
@brief Return the key of the metadatum. The key is of the form
|
||||
@ -274,7 +274,7 @@ namespace Exiv2 {
|
||||
1 in case of inconsistent JPEG thumbnail Exif data<BR>
|
||||
2 in case of inconsistent TIFF thumbnail Exif data
|
||||
*/
|
||||
virtual int read(const char* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder =littleEndian) =0;
|
||||
@ -319,7 +319,7 @@ namespace Exiv2 {
|
||||
enough memory. Otherwise the call results in undefined
|
||||
behaviour. Return the number of characters written.
|
||||
*/
|
||||
virtual long copy(char* buf) const =0;
|
||||
virtual long copy(byte* buf) const =0;
|
||||
/*!
|
||||
@brief Update the Exif data according to the actual thumbnail image.
|
||||
|
||||
@ -374,7 +374,7 @@ namespace Exiv2 {
|
||||
//@{
|
||||
//! Assignment operator.
|
||||
TiffThumbnail& operator=(const TiffThumbnail& rhs);
|
||||
int read(const char* buf,
|
||||
int read(const byte* buf,
|
||||
long len,
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder =littleEndian);
|
||||
@ -386,7 +386,7 @@ namespace Exiv2 {
|
||||
int write(const std::string& path) const;
|
||||
const char* format() const;
|
||||
const char* extension() const;
|
||||
long copy(char* buf) const;
|
||||
long copy(byte* buf) const;
|
||||
void update(ExifData& exifData) const;
|
||||
long offset() const;
|
||||
long size() const;
|
||||
@ -398,7 +398,7 @@ namespace Exiv2 {
|
||||
long offset_; // Original offset of the thumbnail data
|
||||
// from the start of the TIFF header
|
||||
long size_; //!< Size of the image data
|
||||
char* pImage_; //!< Thumbnail image data
|
||||
byte* pImage_; //!< Thumbnail image data
|
||||
TiffHeader tiffHeader_; //!< Thumbnail TIFF Header
|
||||
Ifd ifd_; //!< Thumbnail IFD (IFD1 of the Exif data)
|
||||
|
||||
@ -421,7 +421,7 @@ namespace Exiv2 {
|
||||
//@{
|
||||
//! Assignment operator.
|
||||
JpegThumbnail& operator=(const JpegThumbnail& rhs);
|
||||
int read(const char* buf,
|
||||
int read(const byte* buf,
|
||||
long len,
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder =littleEndian);
|
||||
@ -433,7 +433,7 @@ namespace Exiv2 {
|
||||
int write(const std::string& path) const;
|
||||
const char* format() const;
|
||||
const char* extension() const;
|
||||
long copy(char* buf) const;
|
||||
long copy(byte* buf) const;
|
||||
void update(ExifData& exifData) const;
|
||||
long offset() const;
|
||||
long size() const;
|
||||
@ -445,7 +445,7 @@ namespace Exiv2 {
|
||||
long offset_; // Original offset of the thumbnail data
|
||||
// from the start of the TIFF header
|
||||
long size_; // Size of the image data
|
||||
char* pImage_; // Thumbnail image data
|
||||
byte* pImage_; // Thumbnail image data
|
||||
|
||||
}; // class JpegThumbnail
|
||||
|
||||
@ -543,13 +543,13 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@return 0 if successful.
|
||||
*/
|
||||
int read(const char* buf, long len);
|
||||
int read(const byte* buf, long len);
|
||||
/*!
|
||||
@brief Write the Exif data to file path. If an Exif data section
|
||||
already exists in the file, it is replaced. If there is no
|
||||
metadata and no thumbnail to write, the Exif data section is
|
||||
deleted from the file. Otherwise, an Exif data section is
|
||||
created. See copy(char* buf) for further details.
|
||||
created. See copy(byte* buf) for further details.
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
@ -585,7 +585,7 @@ namespace Exiv2 {
|
||||
undefined behaviour.
|
||||
@return Number of characters written to the buffer.
|
||||
*/
|
||||
long copy(char* buf);
|
||||
long copy(byte* buf);
|
||||
/*!
|
||||
@brief Add all (IFD) entries in the range from iterator position begin
|
||||
to iterator position end to the Exif metadata. No duplicate
|
||||
@ -782,7 +782,7 @@ namespace Exiv2 {
|
||||
the Exif data with the metadata from the actual thumbnail image
|
||||
(overriding existing metadata).
|
||||
*/
|
||||
long copyFromMetadata(char* buf);
|
||||
long copyFromMetadata(byte* buf);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -829,7 +829,7 @@ namespace Exiv2 {
|
||||
Ifd ifd1_;
|
||||
|
||||
long size_; //!< Size of the Exif raw data in bytes
|
||||
char* pData_; //!< Exif raw data buffer
|
||||
byte* pData_; //!< Exif raw data buffer
|
||||
|
||||
/*!
|
||||
Can be set to false to indicate that non-intrusive writing is not
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Abstract : Sample program showing how to set the Exif comment of an image
|
||||
|
||||
File: exifcomment.cpp
|
||||
Version : $Name: $ $Revision: 1.2 $
|
||||
Version : $Name: $ $Revision: 1.3 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History : 10-May-04, ahu: created
|
||||
*/
|
||||
@ -56,7 +56,8 @@ try {
|
||||
std::string charset("ASCII\0\0\0", 8);
|
||||
std::string comment("A comment added to the Exif metadata through Exiv2");
|
||||
Exiv2::DataValue value;
|
||||
value.read((charset + comment).data(), 8 + comment.size());
|
||||
value.read(reinterpret_cast<const Exiv2::byte*>((charset + comment).data()),
|
||||
8 + static_cast<long>(comment.size()));
|
||||
|
||||
// Set the Exif comment
|
||||
std::string key = "Image.UserInfo.UserComment";
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: fujimn.cpp
|
||||
Version: $Name: $ $Revision: 1.7 $
|
||||
Version: $Name: $ $Revision: 1.8 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
07-Mar-04, ahu: isolated as a separate component
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: fujimn.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: fujimn.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -84,7 +84,7 @@ namespace Exiv2 {
|
||||
absOffset_ = false;
|
||||
}
|
||||
|
||||
int FujiMakerNote::readHeader(const char* buf,
|
||||
int FujiMakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
@ -103,7 +103,8 @@ namespace Exiv2 {
|
||||
int rc = 0;
|
||||
// Check the FUJIFILM prefix
|
||||
if ( header_.size_ < 12
|
||||
|| std::string(header_.pData_, 8) != std::string("FUJIFILM", 8)) {
|
||||
|| std::string(reinterpret_cast<char*>(header_.pData_), 8)
|
||||
!= std::string("FUJIFILM", 8)) {
|
||||
rc = 2;
|
||||
}
|
||||
return rc;
|
||||
@ -255,7 +256,7 @@ namespace Exiv2 {
|
||||
// free functions
|
||||
|
||||
MakerNote* createFujiMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
in Appendix 4: Makernote of Fujifilm of the document
|
||||
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
|
||||
Exif file format</a> by TsuruZoh Tachibanaya
|
||||
@version $Name: $ $Revision: 1.5 $
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 11-Feb-04, ahu: created
|
||||
@ -73,7 +73,7 @@ namespace Exiv2 {
|
||||
this copy and is responsible to delete it!
|
||||
*/
|
||||
MakerNote* createFujiMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
@ -97,7 +97,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
int readHeader(const char* buf,
|
||||
int readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
@ -109,7 +109,7 @@ char *alloca ();
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
#include "getopt_win32.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
int main()
|
||||
try {
|
||||
long len = 76;
|
||||
char buf[]
|
||||
Exiv2::byte buf[]
|
||||
= { // No
|
||||
0x00,0x04,
|
||||
// Tag Type Components Offset/Data
|
||||
@ -45,7 +45,7 @@ try {
|
||||
std::cout << "Tag not found!\n";
|
||||
return 1;
|
||||
}
|
||||
char data[] = { 'T', 'H', 'R', 'E', 'E', '\0' };
|
||||
Exiv2::byte data[] = { 'T', 'H', 'R', 'E', 'E', '\0' };
|
||||
|
||||
std::cout << "Setting value of entry 3...\n";
|
||||
pos->setValue(2, 6, data, 6);
|
||||
|
||||
36
src/ifd.cpp
36
src/ifd.cpp
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: ifd.cpp
|
||||
Version: $Name: $ $Revision: 1.23 $
|
||||
Version: $Name: $ $Revision: 1.24 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.23 $ $RCSfile: ifd.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.24 $ $RCSfile: ifd.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -68,7 +68,7 @@ namespace Exiv2 {
|
||||
{
|
||||
if (alloc_) {
|
||||
if (rhs.pData_) {
|
||||
pData_ = new char[rhs.size()];
|
||||
pData_ = new byte[rhs.size()];
|
||||
memcpy(pData_, rhs.pData_, rhs.size());
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ namespace Exiv2 {
|
||||
delete[] pData_;
|
||||
pData_ = 0;
|
||||
if (rhs.pData_) {
|
||||
pData_ = new char[rhs.size()];
|
||||
pData_ = new byte[rhs.size()];
|
||||
memcpy(pData_, rhs.pData_, rhs.size());
|
||||
}
|
||||
}
|
||||
@ -109,7 +109,7 @@ namespace Exiv2 {
|
||||
assert(alloc_);
|
||||
size_ = 4;
|
||||
delete[] pData_;
|
||||
pData_ = new char[size_];
|
||||
pData_ = new byte[size_];
|
||||
}
|
||||
ul2Data(pData_, data, byteOrder);
|
||||
// do not change size_
|
||||
@ -117,7 +117,7 @@ namespace Exiv2 {
|
||||
count_ = 1;
|
||||
}
|
||||
|
||||
void Entry::setValue(uint16 type, uint32 count, const char* buf, long len)
|
||||
void Entry::setValue(uint16 type, uint32 count, const byte* buf, long len)
|
||||
{
|
||||
long dataSize = count * TypeInfo::typeSize(TypeId(type));
|
||||
// No minimum size requirement, but make sure the buffer can hold the data
|
||||
@ -126,7 +126,7 @@ namespace Exiv2 {
|
||||
}
|
||||
if (alloc_) {
|
||||
delete[] pData_;
|
||||
pData_ = new char[len];
|
||||
pData_ = new byte[len];
|
||||
memset(pData_, 0x0, len);
|
||||
memcpy(pData_, buf, dataSize);
|
||||
size_ = len;
|
||||
@ -134,7 +134,7 @@ namespace Exiv2 {
|
||||
else {
|
||||
if (size_ == 0) {
|
||||
// Set the data pointer of a virgin entry
|
||||
pData_ = const_cast<char*>(buf);
|
||||
pData_ = const_cast<byte*>(buf);
|
||||
size_ = len;
|
||||
}
|
||||
else {
|
||||
@ -149,7 +149,7 @@ namespace Exiv2 {
|
||||
count_ = count;
|
||||
} // Entry::setValue
|
||||
|
||||
const char* Entry::component(uint32 n) const
|
||||
const byte* Entry::component(uint32 n) const
|
||||
{
|
||||
if (n >= count()) return 0;
|
||||
return data() + n * typeSize();
|
||||
@ -159,7 +159,7 @@ namespace Exiv2 {
|
||||
: alloc_(true), ifdId_(ifdId), offset_(0), dataOffset_(0),
|
||||
pNext_(0), next_(0)
|
||||
{
|
||||
pNext_ = new char[4];
|
||||
pNext_ = new byte[4];
|
||||
memset(pNext_, 0x0, 4);
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ namespace Exiv2 {
|
||||
: alloc_(true), ifdId_(ifdId), offset_(offset), dataOffset_(0),
|
||||
pNext_(0), next_(0)
|
||||
{
|
||||
pNext_ = new char[4];
|
||||
pNext_ = new byte[4];
|
||||
memset(pNext_, 0x0, 4);
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ namespace Exiv2 {
|
||||
pNext_(0), next_(0)
|
||||
{
|
||||
if (alloc_) {
|
||||
pNext_ = new char[4];
|
||||
pNext_ = new byte[4];
|
||||
memset(pNext_, 0x0, 4);
|
||||
}
|
||||
}
|
||||
@ -192,12 +192,12 @@ namespace Exiv2 {
|
||||
pNext_(rhs.pNext_), next_(rhs.next_)
|
||||
{
|
||||
if (alloc_ && rhs.pNext_) {
|
||||
pNext_ = new char[4];
|
||||
pNext_ = new byte[4];
|
||||
memcpy(pNext_, rhs.pNext_, 4);
|
||||
}
|
||||
}
|
||||
|
||||
int Ifd::read(const char* buf, long len, ByteOrder byteOrder, long offset)
|
||||
int Ifd::read(const byte* buf, long len, ByteOrder byteOrder, long offset)
|
||||
{
|
||||
int rc = 0;
|
||||
long o = 0;
|
||||
@ -242,7 +242,7 @@ namespace Exiv2 {
|
||||
memcpy(pNext_, buf + o, 4);
|
||||
}
|
||||
else {
|
||||
pNext_ = const_cast<char*>(buf + o);
|
||||
pNext_ = const_cast<byte*>(buf + o);
|
||||
}
|
||||
next_ = getULong(buf + o, byteOrder);
|
||||
}
|
||||
@ -356,7 +356,7 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
int Ifd::readSubIfd(
|
||||
Ifd& dest, const char* buf, long len, ByteOrder byteOrder, uint16 tag
|
||||
Ifd& dest, const byte* buf, long len, ByteOrder byteOrder, uint16 tag
|
||||
) const
|
||||
{
|
||||
int rc = 0;
|
||||
@ -373,7 +373,7 @@ namespace Exiv2 {
|
||||
return rc;
|
||||
} // Ifd::readSubIfd
|
||||
|
||||
long Ifd::copy(char* buf, ByteOrder byteOrder, long offset)
|
||||
long Ifd::copy(byte* buf, ByteOrder byteOrder, long offset)
|
||||
{
|
||||
if (offset != 0) offset_ = offset;
|
||||
|
||||
@ -508,7 +508,7 @@ namespace Exiv2 {
|
||||
<< std::hex << std::right << i->offset();
|
||||
}
|
||||
else {
|
||||
unsigned char* data = (unsigned char*)i->data();
|
||||
const byte* data = i->data();
|
||||
for (int k = 0; k < i->size(); ++k) {
|
||||
offset << std::setw(2) << std::setfill('0') << std::hex
|
||||
<< (int)data[k] << " ";
|
||||
|
||||
20
src/ifd.hpp
20
src/ifd.hpp
@ -21,10 +21,10 @@
|
||||
/*!
|
||||
@file ifd.hpp
|
||||
@brief Encoding and decoding of IFD (%Image File Directory) data
|
||||
@version $Name: $ $Revision: 1.19 $
|
||||
@version $Name: $ $Revision: 1.20 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@date 09-Jan-04, ahu: created<BR>
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
#ifndef IFD_HPP_
|
||||
@ -126,7 +126,7 @@ namespace Exiv2 {
|
||||
@throw Error ("Size too small") if size is not large enough to hold
|
||||
count components of the given type.
|
||||
*/
|
||||
void setValue(uint16 type, uint32 count, const char* data, long size);
|
||||
void setValue(uint16 type, uint32 count, const byte* data, long size);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -161,12 +161,12 @@ namespace Exiv2 {
|
||||
@brief Return a pointer to the data area. Do not attempt to write
|
||||
to this pointer.
|
||||
*/
|
||||
const char* data() const { return pData_; }
|
||||
const byte* data() const { return pData_; }
|
||||
/*!
|
||||
@brief Return a pointer to the n-th component, 0 if there is no
|
||||
n-th component. Do not attempt to write to this pointer.
|
||||
*/
|
||||
const char* component(uint32 n) const;
|
||||
const byte* component(uint32 n) const;
|
||||
//! Get the memory allocation mode
|
||||
bool alloc() const { return alloc_; }
|
||||
//@}
|
||||
@ -198,7 +198,7 @@ namespace Exiv2 {
|
||||
*/
|
||||
long size_;
|
||||
//! Pointer to the data buffer
|
||||
char* pData_;
|
||||
byte* pData_;
|
||||
|
||||
}; // class Entry
|
||||
|
||||
@ -323,7 +323,7 @@ namespace Exiv2 {
|
||||
beyond the provided buffer. The IFD is cleared in this
|
||||
case.
|
||||
*/
|
||||
int read(const char* buf, long len, ByteOrder byteOrder, long offset =0);
|
||||
int read(const byte* buf, long len, ByteOrder byteOrder, long offset =0);
|
||||
/*!
|
||||
@brief Read a sub-IFD from the location pointed to by the directory entry
|
||||
with the given tag.
|
||||
@ -344,7 +344,7 @@ namespace Exiv2 {
|
||||
IFD. 0 is returned and no action is taken in this case.
|
||||
*/
|
||||
int readSubIfd(
|
||||
Ifd& dest, const char* buf, long len, ByteOrder byteOrder, uint16 tag
|
||||
Ifd& dest, const byte* buf, long len, ByteOrder byteOrder, uint16 tag
|
||||
) const;
|
||||
/*!
|
||||
@brief Copy the IFD to a data array, update the offsets of the IFD and
|
||||
@ -371,7 +371,7 @@ namespace Exiv2 {
|
||||
original position, i.e., the offset of the IFD will be used.
|
||||
@return Returns the number of characters written.
|
||||
*/
|
||||
long copy(char* buf, ByteOrder byteOrder, long offset =0);
|
||||
long copy(byte* buf, ByteOrder byteOrder, long offset =0);
|
||||
/*!
|
||||
@brief Reset the IFD. Delete all IFD entries from the class and put
|
||||
the object in a state where it can accept completely new
|
||||
@ -489,7 +489,7 @@ namespace Exiv2 {
|
||||
//! Offset of the first data entry outside of the IFD directory
|
||||
long dataOffset_;
|
||||
//! Pointer to the offset of next IFD from the start of the TIFF header
|
||||
char* pNext_;
|
||||
byte* pNext_;
|
||||
//! The offset of the next IFD as data value (always in sync with *pNext_)
|
||||
uint32 next_;
|
||||
|
||||
|
||||
1026
src/image.cpp
1026
src/image.cpp
File diff suppressed because it is too large
Load Diff
806
src/image.hpp
806
src/image.hpp
@ -21,11 +21,14 @@
|
||||
/*!
|
||||
@file image.hpp
|
||||
@brief Class JpegImage to access JPEG images
|
||||
@version $Name: $ $Revision: 1.13 $
|
||||
@version $Name: $ $Revision: 1.14 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
@author Brad Schick (brad)
|
||||
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
||||
@date 09-Jan-04, ahu: created<BR>
|
||||
11-Feb-04, ahu: isolated as a component<BR>
|
||||
19-Jul-04, brad: revamped to be more flexible and support IPTC
|
||||
*/
|
||||
#ifndef IMAGE_HPP_
|
||||
#define IMAGE_HPP_
|
||||
@ -36,13 +39,20 @@
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
//! Type for function pointer that creates new Image instances
|
||||
typedef class Image* (*NewInstanceFct)(const std::string& path, FILE* ifp);
|
||||
|
||||
//! Type for function pointer that checks image types
|
||||
typedef bool (*IsThisTypeFct)(FILE* ifp, bool advance);
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
@ -52,12 +62,10 @@ namespace Exiv2 {
|
||||
class Image {
|
||||
public:
|
||||
//! Supported image formats
|
||||
enum Type { none, jpeg };
|
||||
enum Type { none, jpeg, exv };
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Constructor
|
||||
Image() {}
|
||||
//! Virtual Destructor
|
||||
virtual ~Image() {}
|
||||
//@}
|
||||
@ -65,99 +73,112 @@ namespace Exiv2 {
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read the Exif data from the file path into the internal
|
||||
data buffer.
|
||||
@param path Path to the file.
|
||||
@brief Read metadata from assigned image file into internal
|
||||
buffers.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int readExifData(const std::string& path) =0;
|
||||
virtual int readMetadata() =0;
|
||||
/*!
|
||||
@brief Read the Exif data from the stream into the internal
|
||||
data buffer.
|
||||
@param is Input stream to read from.
|
||||
@brief Write metadata from internal buffers into to the image fle.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int readExifData(std::istream& is) =0;
|
||||
virtual int writeMetadata() =0;
|
||||
/*!
|
||||
@brief Read the Exif data from the buffer buf which has size bytes.
|
||||
@param buf Pointer to the data buffer.
|
||||
@param size Number of characters in the data buffer.
|
||||
@brief Set the Exif data. The data is copied into an internal data
|
||||
buffer and is not written until writeMetadata is called.
|
||||
@param buf Pointer to the new Exif data.
|
||||
@param size Size in bytes of new Exif data.
|
||||
*/
|
||||
virtual void setExifData(const char* buf, long size) =0;
|
||||
virtual void setExifData(const byte* buf, long size) =0;
|
||||
/*!
|
||||
@brief Erase any buffered Exif data. Exif data is not removed
|
||||
from the actual file until writeMetadata is called.
|
||||
*/
|
||||
virtual void clearExifData() =0;
|
||||
/*!
|
||||
@brief Set the Iptc data. The data is copied into an internal data
|
||||
buffer and is not written until writeMetadata is called.
|
||||
@param buf Pointer to the new Iptc data.
|
||||
@param size Size in bytes of new Iptc data.
|
||||
*/
|
||||
virtual void setIptcData(const byte* buf, long size) =0;
|
||||
/*!
|
||||
@brief Erase any buffered Iptc data. Iptc data is not removed
|
||||
from the actual file until writeMetadata is called.
|
||||
*/
|
||||
virtual void clearIptcData() =0;
|
||||
/*!
|
||||
@brief Set the image comment. The data is copied into an internal data
|
||||
buffer and is not written until writeMetadata is called.
|
||||
@param comment String containing comment.
|
||||
*/
|
||||
virtual void setComment(const std::string &comment) =0;
|
||||
/*!
|
||||
@brief Erase any buffered comment. Comment is not removed
|
||||
from the actual file until writeMetadata is called.
|
||||
*/
|
||||
virtual void clearComment() =0;
|
||||
/*!
|
||||
@brief Copy all existing metadata from source %Image. The data is
|
||||
copied into internal buffers and is not written until
|
||||
writeMetadata is called.
|
||||
@param image Metadata source. All metadata types are copied.
|
||||
*/
|
||||
virtual void setMetadata(const Image& image) =0;
|
||||
/*!
|
||||
@brief Erase all buffered metadata. Metadata is not removed
|
||||
from the actual file until writeMetadata is called.
|
||||
*/
|
||||
virtual void clearMetadata() =0;
|
||||
/*!
|
||||
@brief Close associated image file but preserve buffered metadata.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int detach() =0;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Virtual copy construction
|
||||
virtual Image* clone() const =0;
|
||||
/*!
|
||||
@brief Determine if the content of the stream is an image of the type
|
||||
of this class.
|
||||
|
||||
The advance flag determines if the read position in the stream is
|
||||
moved (see below). This applies only if the image type matches and the
|
||||
function returns true. If the image type does not match, the stream
|
||||
position is not changed. However, if reading from the stream fails,
|
||||
the stream position is undefined. Consult the stream state to obtain
|
||||
more information in this case.
|
||||
|
||||
@param is Input stream with the image.
|
||||
@param advance Flag indicating whether the read position in the stream
|
||||
should be advanced by the number of characters read to
|
||||
analyse the image stream (true) or left at its original
|
||||
position (false). This applies only if the image type
|
||||
matches.
|
||||
@return true if the type of the image matches that of this;<BR>
|
||||
false if the type of the image does not match.
|
||||
@brief Check if the %Image instance is valid. Use after object
|
||||
construction.
|
||||
@return true if the %Image is in a valid state.
|
||||
*/
|
||||
virtual bool isThisType(std::istream& is, bool advance =false) const =0;
|
||||
/*!
|
||||
@brief Erase the Exif data from file path.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int eraseExifData(const std::string& path) const =0;
|
||||
/*!
|
||||
@brief Read from the image input stream is, erase Exif data from the
|
||||
image, if there is any, and write the resulting image to the
|
||||
output stream os.
|
||||
@param os Output stream to write to (e.g., a temporary file).
|
||||
@param is Input stream with the image from which the Exif data
|
||||
should be erased.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int eraseExifData(std::ostream& os, std::istream& is) const =0;
|
||||
/*!
|
||||
@brief Write the Exif data to file path.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int writeExifData(const std::string& path) const =0;
|
||||
/*!
|
||||
@brief Read from the image input stream is, add Exif data to the
|
||||
image, replacing existing Exif data, if there is any) and
|
||||
write the resulting image to the output stream os.
|
||||
@param os Output stream to write to (e.g., a temporary file).
|
||||
@param is Input stream with the image to which the Exif data
|
||||
should be copied.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int writeExifData(std::ostream& os, std::istream& is) const =0;
|
||||
virtual bool good() const =0;
|
||||
//! Return the size of the Exif data in bytes.
|
||||
virtual long sizeExifData() const =0;
|
||||
/*!
|
||||
@brief Return a read-only pointer to an Exif data buffer. Do not
|
||||
attempt to write to this buffer.
|
||||
*/
|
||||
virtual const char* exifData() const =0;
|
||||
virtual const byte* exifData() const =0;
|
||||
//! Return the size of the Iptc data in bytes.
|
||||
virtual long sizeIptcData() const =0;
|
||||
/*!
|
||||
@brief Return a read-only pointer to an Iptc data buffer. Do not
|
||||
attempt to write to this buffer.
|
||||
*/
|
||||
virtual const byte* iptcData() const =0;
|
||||
/*!
|
||||
@brief Return a read-only reference to the image comment.
|
||||
Do not attempt to write to this string. May be an empty string.
|
||||
*/
|
||||
virtual std::string comment() const =0;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
@brief Assignment operator. Protected so that it can only be used
|
||||
by subclasses but not directly.
|
||||
*/
|
||||
Image& operator=(const Image& rhs) { return *this; }
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Constructor
|
||||
Image() {}
|
||||
//@}
|
||||
|
||||
private:
|
||||
// NOT Implemented
|
||||
//! Copy constructor
|
||||
Image(const Image& rhs);
|
||||
//! Assignment operator
|
||||
Image& operator=(const Image& rhs);
|
||||
|
||||
}; // class Image
|
||||
|
||||
@ -172,6 +193,56 @@ namespace Exiv2 {
|
||||
public:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Register image type together with its function pointers.
|
||||
|
||||
The image factory creates new images calling their associated
|
||||
function pointer. Additional images can be added by registering
|
||||
new type and function pointers. If called for a type that already
|
||||
exists in the list, the corresponding prototype is replaced.
|
||||
|
||||
@param type Image type.
|
||||
@param newInst Function pointer for creating image instances.
|
||||
@param isType Function pointer to test for matching image types.
|
||||
*/
|
||||
void registerImage(Image::Type type,
|
||||
NewInstanceFct newInst,
|
||||
IsThisTypeFct isType);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Create an %Image of the appropriate type by opening the
|
||||
specified file. File type is derived from the contents of the
|
||||
file.
|
||||
@param path %Image file. The contents of the file are tested to
|
||||
determine the image type to open. File extension is ignored.
|
||||
@return A pointer that owns an %Image of the type derived from the
|
||||
file. Caller must delete the returned object. If no image type
|
||||
could be determined, the pointer is 0.
|
||||
*/
|
||||
Image* open(const std::string& path) const;
|
||||
/*!
|
||||
@brief Create an %Image of the requested type by creating a new
|
||||
file. If the file already exists, it will be overwritten.
|
||||
@param type Type of the image to be created.
|
||||
@param path %Image file. The contents of the file are tested to
|
||||
determine the image type to open. File extension is ignored.
|
||||
@return A pointer that owns an %Image of the requested type. Caller
|
||||
must delete the returned object. If the image type is not
|
||||
supported, the pointer is 0.
|
||||
*/
|
||||
Image* create(Image::Type type, const std::string& path) const;
|
||||
/*!
|
||||
@brief Returns the image type of the provided file.
|
||||
@param path %Image file. The contents of the file are tested to
|
||||
determine the image type. File extension is ignored.
|
||||
@return %Image type of Image::none if the type is not recognized.
|
||||
*/
|
||||
Image::Type getType(const std::string& path) const;
|
||||
//@}
|
||||
|
||||
/*!
|
||||
@brief Get access to the image factory.
|
||||
|
||||
@ -180,43 +251,6 @@ namespace Exiv2 {
|
||||
*/
|
||||
static ImageFactory& instance();
|
||||
|
||||
/*!
|
||||
@brief Register an image prototype together with its type.
|
||||
|
||||
The image factory creates new images by cloning their associated
|
||||
prototypes. Additional images can be added by registering a prototype
|
||||
and its type. If called for a type which already exists in the list,
|
||||
the corresponding prototype is replaced.
|
||||
|
||||
@param type Image type.
|
||||
@param pImage Pointer to the prototype. Ownership is transfered to the
|
||||
factory.
|
||||
*/
|
||||
void registerImage(Image::Type type, Image* pImage);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Create an %Image of the appropriate type, derived from the
|
||||
contents of the stream is.
|
||||
@param is Image stream. The contents of the stream are tested to
|
||||
determine the image type to create.
|
||||
@return A pointer that owns an %Image of the type derived from the
|
||||
stream. If no image type could be determined, the pointer is 0.
|
||||
*/
|
||||
Image* create(std::istream& is) const;
|
||||
|
||||
/*!
|
||||
@brief Create an %Image of the requested type.
|
||||
|
||||
@param type Type of the image to be created.
|
||||
@return A pointer that owns an %Image of the requested type.
|
||||
If the image type is not supported, the pointer is 0.
|
||||
*/
|
||||
Image* create(Image::Type type) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Creators
|
||||
//@{
|
||||
@ -226,170 +260,362 @@ namespace Exiv2 {
|
||||
ImageFactory(const ImageFactory& rhs);
|
||||
//@}
|
||||
|
||||
//! Struct for storing image function pointers.
|
||||
struct ImageFcts
|
||||
{
|
||||
NewInstanceFct newInstance;
|
||||
IsThisTypeFct isThisType;
|
||||
ImageFcts(NewInstanceFct newInst, IsThisTypeFct isType)
|
||||
: newInstance(newInst), isThisType(isType) {}
|
||||
ImageFcts() : newInstance(0), isThisType(0) {}
|
||||
};
|
||||
|
||||
// DATA
|
||||
//! Pointer to the one and only instance of this class.
|
||||
static ImageFactory* pInstance_;
|
||||
//! Type used to store Image prototype classes
|
||||
typedef std::map<Image::Type, Image*> Registry;
|
||||
//! List of image types and corresponding prototypes.
|
||||
//! Type used to store Image creation functions
|
||||
typedef std::map<Image::Type, ImageFcts> Registry;
|
||||
//! List of image types and corresponding creation functions.
|
||||
Registry registry_;
|
||||
|
||||
}; // class ImageFactory
|
||||
|
||||
/*!
|
||||
@brief Helper class to access JPEG images
|
||||
@brief Abstract helper base class to access JPEG images
|
||||
*/
|
||||
class JpegImage : public Image {
|
||||
class JpegBase : public Image {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
JpegImage();
|
||||
//! Copy constructor
|
||||
JpegImage(const JpegImage& rhs);
|
||||
//! Destructor
|
||||
~JpegImage();
|
||||
//! Virtual destructor.
|
||||
virtual ~JpegBase();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Assignment operator
|
||||
JpegImage& operator=(const JpegImage& rhs);
|
||||
/*!
|
||||
@brief Read the Exif data from the file path into the internal
|
||||
data buffer.
|
||||
@param path Path to the file.
|
||||
@brief Read all metadata from the file into the internal
|
||||
data buffers. This method returns success even when
|
||||
no metadata is found in the image. Callers must therefore
|
||||
check the size of indivdual metadata types before
|
||||
accessing the data.
|
||||
@return 0 if successful;<BR>
|
||||
-1 if the file cannot be opened; or<BR>
|
||||
the return code of readExifData(std::istream& is)
|
||||
if the call to this function fails.
|
||||
1 if reading from the file failed
|
||||
(could be caused by invalid image);<BR>
|
||||
2 if the file does not contain a valid image;<BR>
|
||||
*/
|
||||
int readExifData(const std::string& path);
|
||||
int readMetadata();
|
||||
/*!
|
||||
@brief Read the Exif data from the stream into the internal
|
||||
data buffer.
|
||||
@param is Input stream to read from.
|
||||
@return 0 if successful;<BR>
|
||||
1 if reading from the stream failed (consult the stream state
|
||||
for more information);<BR>
|
||||
2 if the stream does not contain a JPEG image;<BR>
|
||||
3 if no Exif APP1 segment was found after SOI at the
|
||||
beginning of the input stream.
|
||||
@brief Write all buffered metadata to associated file. All existing
|
||||
metadata sections in the file are either replaced or erased.
|
||||
If data for a given metadata type has not been assigned,
|
||||
then that metadata type will be erased from the file.
|
||||
@return 0 if successful;<br>
|
||||
1 if reading from the file failed;<BR>
|
||||
2 if the associated file does not contain a valid image;<BR>
|
||||
3 if the temporary output file can not be written to;<BR>
|
||||
4 if renaming the temporary file fails;<br>
|
||||
*/
|
||||
int readExifData(std::istream& is);
|
||||
/*!
|
||||
@brief Set the Exif data. The data is copied into the internal
|
||||
data buffer.
|
||||
@param buf Pointer to the data buffer.
|
||||
@param size Number of characters in the data buffer.
|
||||
*/
|
||||
void setExifData(const char* buf, long size);
|
||||
int writeMetadata();
|
||||
void setExifData(const byte* buf, long size);
|
||||
void clearExifData();
|
||||
void setIptcData(const byte* buf, long size);
|
||||
void clearIptcData();
|
||||
void setComment(const std::string &comment);
|
||||
void clearComment();
|
||||
void setMetadata(const Image& image);
|
||||
void clearMetadata();
|
||||
int detach();
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Virtual copy construction
|
||||
Image* clone() const;
|
||||
bool good() const;
|
||||
long sizeExifData() const { return sizeExifData_; }
|
||||
const byte* exifData() const { return pExifData_; }
|
||||
long sizeIptcData() const { return sizeIptcData_; }
|
||||
const byte* iptcData() const { return pIptcData_; }
|
||||
std::string comment() const { return comment_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor for subclasses that have already opened a
|
||||
file stream on the specified path.
|
||||
@param path Full path to image file.
|
||||
@param fp File pointer to open file.
|
||||
*/
|
||||
JpegBase(const std::string& path, FILE* fp);
|
||||
/*!
|
||||
@brief Constructor that can either open an existing image or create
|
||||
a new image from scratch. If a new image is to be created, any
|
||||
existing file is overwritten
|
||||
@param path Full path to image file.
|
||||
@param create Specifies if an existing file should be opened (false)
|
||||
or if a new file should be created (true).
|
||||
@param initData Data to initialize newly created files. Only used
|
||||
when %create is true. Should contain the data for the smallest
|
||||
valid image of the calling subclass.
|
||||
@param dataSize Size of initData in bytes.
|
||||
*/
|
||||
JpegBase(const std::string& path, const bool create,
|
||||
const byte initData[], const size_t dataSize);
|
||||
//@}
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Determine if the content of the stream is a JPEG image.
|
||||
@param is Input stream to test.
|
||||
@brief Writes the image header (aka signature) to the file stream.
|
||||
@param ofp File stream that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
3 if the output file can not be written to;<BR>
|
||||
*/
|
||||
virtual int writeHeader(FILE* ofp) const =0;
|
||||
/*!
|
||||
@brief Determine if the content of the stream is of the type of this
|
||||
class.
|
||||
|
||||
The advance flag determines if the read position in the stream is
|
||||
moved (see below). This applies only if the type matches and the
|
||||
function returns true. If the type does not match, the stream
|
||||
position is not changed. However, if reading from the stream fails,
|
||||
the stream position is undefined. Consult the stream state to obtain
|
||||
more information in this case.
|
||||
|
||||
@param ifp Input file stream.
|
||||
@param advance Flag indicating whether the read position in the stream
|
||||
should be advanced by the number of characters read to
|
||||
analyse the image stream (true) or left at its original
|
||||
position (false). This applies only if the image type
|
||||
matches.
|
||||
@return true if the input stream starts with the JPEG SOI marker.
|
||||
The stream is not advanced in this case.<BR>
|
||||
false if the input stream does not begin with the JPEG SOI
|
||||
marker. The stream is not advanced.<BR>
|
||||
false if reading the first two bytes from the stream fails.
|
||||
Consult the stream state for more information. In this case,
|
||||
the stream may or may not have been advanced by 1 or 2
|
||||
characters.
|
||||
analyse the stream (true) or left at its original
|
||||
position (false). This applies only if the type matches.
|
||||
@return true if the stream data matches the type of this class;<BR>
|
||||
false if the stream data does not match.
|
||||
*/
|
||||
bool isThisType(std::istream& is, bool advance) const;
|
||||
/*!
|
||||
@brief Erase the Exif data from file path, which must contain a JPEG
|
||||
image. If an Exif APP1 section exists in the file, it is
|
||||
erased.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful;<br>
|
||||
-1 if the input file cannot be opened;<br>
|
||||
-3 if the temporary file cannot be opened;<br>
|
||||
-4 if renaming the temporary file fails; or<br>
|
||||
the return code of
|
||||
eraseExifData(std::ostream& os, std::istream& is) const
|
||||
if the call to this function fails.
|
||||
*/
|
||||
int eraseExifData(const std::string& path) const;
|
||||
/*!
|
||||
@brief Erase Exif data from the JPEG image is, write the resulting
|
||||
image to the output stream os. If an Exif APP1 section exists
|
||||
in the input file, it is erased.
|
||||
@param os Output stream to write to (e.g., a temporary file).
|
||||
@param is Input stream with the JPEG image from which the Exif data
|
||||
should be erased.
|
||||
@return 0 if successful;<BR>
|
||||
1 if reading from the input stream failed (consult the stream
|
||||
state for more information);<BR>
|
||||
2 if the input stream does not contain a JPEG image;<BR>
|
||||
3 if neither a JFIF APP0 segment nor a Exif APP1 segment was
|
||||
found after SOI at the beginning of the input stream;<BR>
|
||||
4 if writing to the output stream failed (consult the stream
|
||||
state for more information).
|
||||
*/
|
||||
int eraseExifData(std::ostream& os, std::istream& is) const;
|
||||
/*!
|
||||
@brief Write the Exif data to file path, which must contain a JPEG
|
||||
image. If an Exif APP1 section exists in the file, it is
|
||||
replaced. Otherwise, an Exif data section is created.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful;<br>
|
||||
-1 if the input file cannot be opened;<br>
|
||||
-3 if the temporary file cannot be opened;<br>
|
||||
-4 if renaming the temporary file fails; or<br>
|
||||
the return code of
|
||||
writeExifData(std::ostream& os, std::istream& is) const
|
||||
if the call to this function fails.
|
||||
*/
|
||||
int writeExifData(const std::string& path) const;
|
||||
/*!
|
||||
@brief Copy Exif data into the JPEG image is, write the resulting
|
||||
image to the output stream os. If an Exif APP1 section exists
|
||||
in the input file, it is replaced. Otherwise, an Exif data
|
||||
section is created.
|
||||
@param os Output stream to write to (e.g., a temporary file).
|
||||
@param is Input stream with the JPEG image to which the Exif data
|
||||
should be copied.
|
||||
@return 0 if successful;<BR>
|
||||
1 if reading from the input stream failed (consult the stream
|
||||
state for more information);<BR>
|
||||
2 if the input stream does not contain a JPEG image;<BR>
|
||||
3 if neither a JFIF APP0 segment nor a Exif APP1 segment was
|
||||
found after SOI at the beginning of the input stream;<BR>
|
||||
4 if writing to the output stream failed (consult the stream
|
||||
state for more information).
|
||||
*/
|
||||
int writeExifData(std::ostream& os, std::istream& is) const;
|
||||
//! Return the size of the Exif data buffer
|
||||
long sizeExifData() const { return sizeExifData_; }
|
||||
//! Return a read-only pointer to the Exif data buffer
|
||||
const char* exifData() const { return pExifData_; }
|
||||
virtual bool isThisType(FILE* ifp, bool advance) const =0;
|
||||
//@}
|
||||
|
||||
// Constant Data
|
||||
static const byte sos_; //!< JPEG SOS marker
|
||||
static const byte eoi_; //!< JPEG EOI marker
|
||||
static const byte app0_; //!< JPEG APP0 marker
|
||||
static const byte app1_; //!< JPEG APP1 marker
|
||||
static const byte app13_; //!< JPEG APP13 marker
|
||||
static const byte com_; //!< JPEG Comment marker
|
||||
static const char exifId_[]; //!< Exif identifier
|
||||
static const char jfifId_[]; //!< JFIF identifier
|
||||
static const char ps3Id_[]; //!< Photoshop marker
|
||||
static const char bimId_[]; //!< Photoshop marker
|
||||
static const uint16 iptc_; //!< Photoshop IPTC marker
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const uint16 soi_; // SOI marker
|
||||
static const uint16 app0_; // APP0 marker
|
||||
static const uint16 app1_; // APP1 marker
|
||||
static const char exifId_[]; // Exif identifier
|
||||
static const char jfifId_[]; // JFIF identifier
|
||||
FILE* fp_; //!< Image file (read write)
|
||||
const std::string path_; //!< Image file name
|
||||
long sizeExifData_; //!< Size of the Exif data buffer
|
||||
byte* pExifData_; //!< Exif data buffer
|
||||
long sizeIptcData_; //!< Size of the Iptc data buffer
|
||||
byte* pIptcData_; //!< IPTC data buffer
|
||||
std::string comment_; //!< JPEG comment
|
||||
|
||||
long sizeExifData_; // Size of the Exif data buffer
|
||||
char* pExifData_; // Exif data buffer
|
||||
// METHODS
|
||||
/*!
|
||||
@brief Advances file stream to one byte past the next Jpeg marker
|
||||
and returns the marker. This method should be called when the
|
||||
file stream is positioned one byte past the end of a Jpeg segment.
|
||||
@return the next Jpeg segment marker if successful;<BR>
|
||||
-1 if a maker was not found before EOF;<BR>
|
||||
*/
|
||||
int advanceToMarker() const;
|
||||
/*!
|
||||
@brief Locates Photoshop formated IPTC data in a memory buffer.
|
||||
Operates on raw data (rather than file streams) to simplify reuse.
|
||||
@param pPSData Pointer to buffer containing entire payload of
|
||||
Photoshop formated APP13 Jpeg segment.
|
||||
@param sizePSData Size in bytes of pPSData.
|
||||
@param record Output value that is set to the start of the IPTC
|
||||
data block within pPSData (may not be null).
|
||||
@param sizeHdr Output value that is set to the size of the header
|
||||
within the IPTC data block pointed to by record (may not
|
||||
be null).
|
||||
@param sizeIptc Output value that is set to the size of the actual
|
||||
IPTC data within the IPTC data block pointed to by record
|
||||
(may not be null).
|
||||
@return 0 if successful;<BR>
|
||||
1 if the pPSData buffer does not contain valid data;<BR>
|
||||
2 if no IPTC data was found in pPSData;<BR>
|
||||
*/
|
||||
int locateIptcData(const byte *pPSData,
|
||||
long sizePSData,
|
||||
const byte **record,
|
||||
uint16 *const sizeHdr,
|
||||
uint16 *const sizeIptc) const;
|
||||
/*!
|
||||
@brief Write to the associated file stream with the provided data.
|
||||
@param initData Data to be written to the associated file
|
||||
@param dataSize Size in bytes of data to be written
|
||||
@return 0 if successful;<BR>
|
||||
3 if the output file can not be written to;<BR>
|
||||
*/
|
||||
int initFile(const byte initData[], const size_t dataSize);
|
||||
/*!
|
||||
@brief Provides the main implementation of writeMetadata by
|
||||
writing all buffered metadata to associated file.
|
||||
@param os Output stream to write to (e.g., a temporary file).
|
||||
@return 0 if successful;<br>
|
||||
1 if reading from associated file failed;<BR>
|
||||
2 if the file does not contain a valid image;<BR>
|
||||
3 if the temporary output file can not be written to;<BR>
|
||||
*/
|
||||
int doWriteMetadata(FILE* ofp) const;
|
||||
|
||||
// NOT Implemented
|
||||
//! Default constructor.
|
||||
JpegBase();
|
||||
//! Copy constructor
|
||||
JpegBase(const JpegBase& rhs);
|
||||
//! Assignment operator
|
||||
JpegBase& operator=(const JpegBase& rhs);
|
||||
}; // class JpegBase
|
||||
|
||||
/*!
|
||||
@brief Helper class to access JPEG images
|
||||
*/
|
||||
class JpegImage : public JpegBase {
|
||||
friend Image* newJpegInstance(const std::string& path, FILE* fp);
|
||||
friend bool isJpegType(FILE* ifp, bool advance);
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor that can either open an existing Jpeg image or create
|
||||
a new image from scratch. If a new image is to be created, any
|
||||
existing file is overwritten. Since the constructor can not return
|
||||
a result, callers should check the %good method after object
|
||||
construction to determine success or failure.
|
||||
@param path Full path to image file.
|
||||
@param create Specifies if an existing file should be opened (false)
|
||||
or if a new file should be created (true).
|
||||
*/
|
||||
JpegImage(const std::string& path, const bool create);
|
||||
//! Destructor
|
||||
~JpegImage() {}
|
||||
//@}
|
||||
protected:
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Writes a Jpeg header (aka signature) to the file stream.
|
||||
@param ofp File stream that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
3 if the output file can not be written to;<BR>
|
||||
*/
|
||||
int writeHeader(FILE* ofp) const;
|
||||
/*!
|
||||
@brief Determine if the content of the file stream is a Jpeg image.
|
||||
See base class for more details.
|
||||
@param ifp Input file stream.
|
||||
@param advance Flag indicating whether the read position in the stream
|
||||
should be advanced by the number of characters read to
|
||||
analyse the stream (true) or left at its original
|
||||
position (false). This applies only if the type matches.
|
||||
@return true if the file stream data matches a Jpeg image;<BR>
|
||||
false if the stream data does not match.
|
||||
*/
|
||||
bool isThisType(FILE* ifp, bool advance) const;
|
||||
//@}
|
||||
private:
|
||||
// Constant data
|
||||
static const byte soi_; // SOI marker
|
||||
static const byte blank_[]; // Minimal Jpeg image
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to be used when a Jpeg file has already
|
||||
been opened. Meant for internal factory use.
|
||||
@param path Full path to opened image file.
|
||||
@param fp File pointer to open file.
|
||||
*/
|
||||
JpegImage(const std::string& path, FILE* fp) : JpegBase(path, fp) {}
|
||||
//@}
|
||||
|
||||
// NOT Implemented
|
||||
//! Default constructor
|
||||
JpegImage();
|
||||
//! Copy constructor
|
||||
JpegImage(const JpegImage& rhs);
|
||||
//! Assignment operator
|
||||
JpegImage& operator=(const JpegImage& rhs);
|
||||
}; // class JpegImage
|
||||
|
||||
//! Helper class to access %Exiv2 files
|
||||
class ExvImage : public JpegBase {
|
||||
friend Image* newExvInstance(const std::string& path, FILE* fp);
|
||||
friend bool isExvType(FILE* ifp, bool advance);
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor that can either open an existing Exv image or create
|
||||
a new image from scratch. If a new image is to be created, any
|
||||
existing file is overwritten. Since the constructor can not return
|
||||
a result, callers should check the %good method after object
|
||||
construction to determine success or failure.
|
||||
@param path Full path to image file.
|
||||
@param create Specifies if an existing file should be opened (false)
|
||||
or if a new file should be created (true).
|
||||
*/
|
||||
ExvImage(const std::string& path, const bool create);
|
||||
//! Destructor
|
||||
~ExvImage() {}
|
||||
//@}
|
||||
protected:
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Writes an Exv header (aka signature) to the file stream.
|
||||
@param ofp File stream that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
3 if the output file can not be written to;<BR>
|
||||
*/
|
||||
int writeHeader(FILE* ofp) const;
|
||||
/*!
|
||||
@brief Determine if the content of the file stream is a Exv image.
|
||||
See base class for more details.
|
||||
@param ifp Input file stream.
|
||||
@param advance Flag indicating whether the read position in the stream
|
||||
should be advanced by the number of characters read to
|
||||
analyse the stream (true) or left at its original
|
||||
position (false). This applies only if the type matches.
|
||||
@return true if the file stream data matches a Exv image;<BR>
|
||||
false if the stream data does not match.
|
||||
*/
|
||||
virtual bool isThisType(FILE* ifp, bool advance) const;
|
||||
//@}
|
||||
private:
|
||||
// Constant data
|
||||
static const char exiv2Id_[]; // Exv identifier
|
||||
static const byte blank_[]; // Minimal exiv file
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to be used when an Exv file has already
|
||||
been opened. Meant for internal factory use.
|
||||
@param path Full path to opened image file.
|
||||
@param fp File pointer to open file.
|
||||
*/
|
||||
ExvImage(const std::string& path, FILE* fp) : JpegBase(path, fp) {}
|
||||
//@}
|
||||
|
||||
// NOT Implemented
|
||||
//! Default constructor
|
||||
ExvImage();
|
||||
//! Copy constructor
|
||||
ExvImage(const ExvImage& rhs);
|
||||
//! Assignment operator
|
||||
ExvImage& operator=(const ExvImage& rhs);
|
||||
}; // class ExvImage
|
||||
|
||||
//! Helper class modelling the TIFF header structure.
|
||||
class TiffHeader {
|
||||
public:
|
||||
@ -405,7 +631,7 @@ namespace Exiv2 {
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Read the TIFF header from a data buffer. Returns 0 if successful.
|
||||
int read(const char* buf);
|
||||
int read(const byte* buf);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -422,7 +648,7 @@ namespace Exiv2 {
|
||||
@param buf The data buffer to write to.
|
||||
@return The number of bytes written.
|
||||
*/
|
||||
long copy(char* buf) const;
|
||||
long copy(byte* buf) const;
|
||||
//! Return the size of the TIFF header in bytes.
|
||||
long size() const { return 8; }
|
||||
//! Return the byte order (little or big endian).
|
||||
@ -442,95 +668,7 @@ namespace Exiv2 {
|
||||
uint16 tag_;
|
||||
uint32 offset_;
|
||||
|
||||
}; // class TiffHeader
|
||||
|
||||
//! Helper class to access %Exiv2 files
|
||||
class ExvFile {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Constructor
|
||||
ExvFile();
|
||||
//! Destructor
|
||||
~ExvFile();
|
||||
//! Copy constructor
|
||||
ExvFile(const ExvFile& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Assignment operator
|
||||
ExvFile& operator=(const ExvFile& rhs);
|
||||
/*!
|
||||
@brief Read the Exif data from the file path into the internal
|
||||
data buffer.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
int readExifData(const std::string& path);
|
||||
/*!
|
||||
@brief Read the Exif data from the stream is into the internal
|
||||
data buffer.
|
||||
@param is Input stream to read from.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
int readExifData(std::istream& is);
|
||||
/*!
|
||||
@brief Read the Exif data from the buffer buf which has size bytes.
|
||||
@param buf Pointer to the data buffer.
|
||||
@param size Number of characters in the data buffer.
|
||||
*/
|
||||
void setExifData(const char* buf, long size);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Write the Exif data to file path.
|
||||
@param path Path to the file.
|
||||
@return 0 if successful.
|
||||
*/
|
||||
int writeExifData(const std::string& path) const;
|
||||
//! Return the size of the Exif data in bytes.
|
||||
long sizeExifData() const { return sizeExifData_; }
|
||||
/*!
|
||||
@brief Return a read-only pointer to an Exif data buffer. Do not
|
||||
attempt to write to this buffer.
|
||||
*/
|
||||
const char* exifData() const { return pExifData_; }
|
||||
//@}
|
||||
|
||||
/*!
|
||||
@brief Determine if the content of the stream is of the type of this
|
||||
class.
|
||||
|
||||
The advance flag determines if the read position in the stream is
|
||||
moved (see below). This applies only if the type matches and the
|
||||
function returns true. If the type does not match, the stream
|
||||
position is not changed. However, if reading from the stream fails,
|
||||
the stream position is undefined. Consult the stream state to obtain
|
||||
more information in this case.
|
||||
|
||||
@param is Input stream.
|
||||
@param advance Flag indicating whether the read position in the stream
|
||||
should be advanced by the number of characters read to
|
||||
analyse the stream (true) or left at its original
|
||||
position (false). This applies only if the type matches.
|
||||
@return true if the stream data matches the type of this class;<BR>
|
||||
false if the stream data does not match.
|
||||
*/
|
||||
static bool isThisType(std::istream& is, bool advance =false);
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const uint16 app1_; // APP1 marker
|
||||
static const char exifId_[]; // Exif identifier
|
||||
|
||||
long sizeExifData_; // Size of the Exif data buffer
|
||||
char* pExifData_; // Exif data buffer
|
||||
|
||||
}; // class ExvFile
|
||||
|
||||
}; // class TiffHeader
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef IMAGE_HPP_
|
||||
|
||||
101
src/imagetest.sh
Executable file
101
src/imagetest.sh
Executable file
@ -0,0 +1,101 @@
|
||||
#! /bin/sh
|
||||
# Test driver for image file i/o
|
||||
|
||||
eraseTest()
|
||||
{
|
||||
src=$1
|
||||
test=${src}.etst
|
||||
good=${src}.egd
|
||||
|
||||
#setup
|
||||
cp $src $test
|
||||
|
||||
#run tests
|
||||
../src/metacopy $test $test
|
||||
|
||||
#check results
|
||||
diffCheck $test $good
|
||||
}
|
||||
|
||||
copyTest()
|
||||
{
|
||||
num=$1
|
||||
src=$2
|
||||
dst=$3
|
||||
test=${dst}.c${num}tst
|
||||
good=${dst}.c${num}gd
|
||||
|
||||
#setup
|
||||
cp $dst $test
|
||||
|
||||
#run tests
|
||||
../src/metacopy -a $src $test
|
||||
|
||||
#check results
|
||||
diffCheck $test $good
|
||||
}
|
||||
|
||||
iptcTest()
|
||||
{
|
||||
num=$1
|
||||
src=$2
|
||||
dst=$3
|
||||
test=${dst}.i${num}tst
|
||||
good=${dst}.i${num}gd
|
||||
|
||||
#setup
|
||||
cp $dst $test
|
||||
|
||||
#run tests
|
||||
../src/metacopy -ip $src $test
|
||||
|
||||
#check results
|
||||
diffCheck $test $good
|
||||
}
|
||||
|
||||
|
||||
# Make sure to pass the test file first and the know good file second
|
||||
diffCheck() {
|
||||
|
||||
test=$1
|
||||
good=$2
|
||||
|
||||
#run diff and check results
|
||||
diff -q --binary $test $good
|
||||
if [ $? -ne 0 ]; then
|
||||
let ++errors
|
||||
else
|
||||
rm $test
|
||||
fi
|
||||
}
|
||||
|
||||
test_files=("table.jpg" "smiley1.jpg" "smiley2.jpg")
|
||||
|
||||
let errors=0
|
||||
cd ../test
|
||||
echo
|
||||
|
||||
echo "Erase all tests..."
|
||||
foreach i ($test_files); eraseTest $i; end
|
||||
eraseTest "glider.exv" #extra test
|
||||
|
||||
echo "Copy all tests..."
|
||||
let c=0
|
||||
foreach src ($test_files)
|
||||
let ++c
|
||||
foreach dst ($test_files); copyTest $c $src $dst; end
|
||||
end
|
||||
|
||||
echo "Copy iptc tests..."
|
||||
let c=0
|
||||
foreach src ($test_files)
|
||||
let ++c
|
||||
foreach dst ($test_files); iptcTest $c $src $dst; end
|
||||
end
|
||||
|
||||
echo '---------------------------------------------------------'
|
||||
if [ $errors -eq 0 ]; then
|
||||
echo 'All test cases passed'
|
||||
else
|
||||
echo $errors 'test case(s) failed!'
|
||||
fi
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: makernote.cpp
|
||||
Version: $Name: $ $Revision: 1.22 $
|
||||
Version: $Name: $ $Revision: 1.23 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.22 $ $RCSfile: makernote.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.23 $ $RCSfile: makernote.cpp,v $")
|
||||
|
||||
// Define DEBUG_* to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -165,7 +165,7 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
int IfdMakerNote::read(const char* buf,
|
||||
int IfdMakerNote::read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
@ -206,7 +206,7 @@ namespace Exiv2 {
|
||||
return rc;
|
||||
} // IfdMakerNote::read
|
||||
|
||||
long IfdMakerNote::copy(char* buf, ByteOrder byteOrder, long offset)
|
||||
long IfdMakerNote::copy(byte* buf, ByteOrder byteOrder, long offset)
|
||||
{
|
||||
// Remember the new offset
|
||||
offset_ = offset;
|
||||
@ -222,7 +222,7 @@ namespace Exiv2 {
|
||||
return len;
|
||||
} // IfdMakerNote::copy
|
||||
|
||||
int IfdMakerNote::readHeader(const char* buf,
|
||||
int IfdMakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
@ -236,7 +236,7 @@ namespace Exiv2 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long IfdMakerNote::copyHeader(char* buf) const
|
||||
long IfdMakerNote::copyHeader(byte* buf) const
|
||||
{
|
||||
if (header_.size_ != 0) memcpy(buf, header_.pData_, header_.size_);
|
||||
return header_.size_;
|
||||
@ -309,7 +309,7 @@ namespace Exiv2 {
|
||||
MakerNote* MakerNoteFactory::create(const std::string& make,
|
||||
const std::string& model,
|
||||
bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset) const
|
||||
@ -386,7 +386,7 @@ namespace Exiv2 {
|
||||
#ifdef DEBUG_REGISTRY
|
||||
std::cerr << "Exact match (score: " << key.size() + 2 << ")\n";
|
||||
#endif
|
||||
return key.size() + 2;
|
||||
return static_cast<int>(key.size()) + 2;
|
||||
}
|
||||
std::string uKey = key;
|
||||
std::string uReg = regEntry;
|
||||
@ -448,7 +448,7 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
if (found) {
|
||||
count += ss.size();
|
||||
count += static_cast<int>(ss.size());
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_REGISTRY
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
@file makernote.hpp
|
||||
@brief Contains the Exif %MakerNote interface, IFD %MakerNote and a
|
||||
MakerNote factory
|
||||
@version $Name: $ $Revision: 1.20 $
|
||||
@version $Name: $ $Revision: 1.21 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 18-Feb-04, ahu: created
|
||||
@ -53,7 +53,7 @@ namespace Exiv2 {
|
||||
// type definitions
|
||||
|
||||
//! Type for a pointer to a function creating a makernote
|
||||
typedef MakerNote* (*CreateFct)(bool, const char*, long, ByteOrder, long);
|
||||
typedef MakerNote* (*CreateFct)(bool, const byte*, long, ByteOrder, long);
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
@ -137,7 +137,7 @@ namespace Exiv2 {
|
||||
start of the TIFF header) and encoded in byte order byteOrder.
|
||||
Return 0 if successful.
|
||||
*/
|
||||
virtual int read(const char* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset) =0;
|
||||
@ -147,7 +147,7 @@ namespace Exiv2 {
|
||||
in byte order byteOrder. Update internal offsets if necessary.
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
virtual long copy(char* buf, ByteOrder byteOrder, long offset) =0;
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder, long offset) =0;
|
||||
/*!
|
||||
@brief Add the entry to the makernote. No duplicate-check is performed,
|
||||
i.e., it is possible to add multiple entries with the same tag.
|
||||
@ -279,7 +279,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
virtual int read(const char* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
@ -291,10 +291,10 @@ namespace Exiv2 {
|
||||
@note The default implementation does nothing, assuming there is no
|
||||
header
|
||||
*/
|
||||
virtual int readHeader(const char* buf,
|
||||
virtual int readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder);
|
||||
virtual long copy(char* buf, ByteOrder byteOrder, long offset);
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder, long offset);
|
||||
void add(const Entry& entry) { ifd_.add(entry); }
|
||||
Entries::iterator begin() { return ifd_.begin(); }
|
||||
Entries::iterator end() { return ifd_.end(); }
|
||||
@ -319,7 +319,7 @@ namespace Exiv2 {
|
||||
number of characters written.
|
||||
@note The default implementation copies the header_ buffer.
|
||||
*/
|
||||
virtual long copyHeader(char* buf) const;
|
||||
virtual long copyHeader(byte* buf) const;
|
||||
/*!
|
||||
@brief Return the size of the makernote header in bytes.
|
||||
@note The default implementation returns the size of the header_
|
||||
@ -445,7 +445,7 @@ namespace Exiv2 {
|
||||
MakerNote* create(const std::string& make,
|
||||
const std::string& model,
|
||||
bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset) const;
|
||||
|
||||
193
src/metacopy.cpp
Normal file
193
src/metacopy.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
Abstract : Tester application for image file handling
|
||||
|
||||
File : metacopy.cpp
|
||||
Version : $Name: $ $Revision: 1.1 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History : 13-Jul-04, brad: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "types.hpp"
|
||||
#include "metacopy.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
// *****************************************************************************
|
||||
// Main
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
try {
|
||||
// Handle command line arguments
|
||||
Params params;
|
||||
if (params.getopt(argc, argv)) {
|
||||
params.usage();
|
||||
return 1;
|
||||
}
|
||||
if (params.help_) {
|
||||
params.help();
|
||||
return 2;
|
||||
}
|
||||
|
||||
Exiv2::Image* readImg = Exiv2::ImageFactory::instance().open(params.read_);
|
||||
if (!readImg) {
|
||||
std::cerr << params.progname() <<
|
||||
": Could not read file (" << params.read_ << ")\n";
|
||||
return 4;
|
||||
}
|
||||
if (readImg->readMetadata()) {
|
||||
std::cerr << params.progname() <<
|
||||
": Could not read metadata from (" << params.read_ << ")\n";
|
||||
return 5;
|
||||
}
|
||||
readImg->detach();
|
||||
|
||||
Exiv2::Image* writeImg = Exiv2::ImageFactory::instance().open(params.write_);
|
||||
if (!writeImg) {
|
||||
std::cerr << params.progname() <<
|
||||
": Could not read file (" << params.write_ << ")\n";
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (params.preserve_) {
|
||||
if (writeImg->readMetadata()) {
|
||||
std::cerr << params.progname() <<
|
||||
": Could not read metadata from (" << params.write_ << ")\n";
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
if (params.iptc_) {
|
||||
writeImg->setIptcData(readImg->iptcData(), readImg->sizeIptcData());
|
||||
}
|
||||
if (params.exif_) {
|
||||
writeImg->setExifData(readImg->exifData(), readImg->sizeExifData());
|
||||
}
|
||||
if (params.comment_) {
|
||||
writeImg->setComment(readImg->comment());
|
||||
}
|
||||
|
||||
if (writeImg->writeMetadata()) {
|
||||
std::cerr << params.progname() <<
|
||||
": Could not write metadata to (" << params.write_ << ")\n";
|
||||
return 8;
|
||||
}
|
||||
|
||||
delete readImg;
|
||||
delete writeImg;
|
||||
return 0;
|
||||
}
|
||||
catch (Exiv2::Error& e) {
|
||||
std::cerr << "Caught Exiv2 exception '" << e << "'\n";
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
int Params::option(int opt, const std::string& optarg, int optopt)
|
||||
{
|
||||
int rc = 0;
|
||||
switch (opt) {
|
||||
case 'h': help_ = true; break;
|
||||
case 'i': iptc_ = true; break;
|
||||
case 'e': exif_ = true; break;
|
||||
case 'c': comment_ = true; break;
|
||||
case 'p': preserve_ = true; break;
|
||||
case 'a':
|
||||
iptc_ =true;
|
||||
exif_ =true;
|
||||
comment_ =true;
|
||||
break;
|
||||
case ':':
|
||||
std::cerr << progname() << ": Option -" << static_cast<char>(optopt)
|
||||
<< " requires an argument\n";
|
||||
rc = 1;
|
||||
break;
|
||||
case '?':
|
||||
std::cerr << progname() << ": Unrecognized option -"
|
||||
<< static_cast<char>(optopt) << "\n";
|
||||
rc = 1;
|
||||
break;
|
||||
default:
|
||||
std::cerr << progname()
|
||||
<< ": getopt returned unexpected character code "
|
||||
<< std::hex << opt << "\n";
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int Params::nonoption(const std::string& argv)
|
||||
{
|
||||
if (!write_.empty()) {
|
||||
std::cerr << progname() << ": Unexpected extra argument (" << argv << ")\n";
|
||||
return 1;
|
||||
}
|
||||
if (first_) read_ = argv;
|
||||
else write_ = argv;
|
||||
first_ = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Params::getopt(int argc, char* const argv[])
|
||||
{
|
||||
int rc = Util::Getopt::getopt(argc, argv, optstring_);
|
||||
// Further consistency checks
|
||||
if (help_==false) {
|
||||
if (rc==0 && read_.empty() ) {
|
||||
std::cerr << progname() << ": Read and write files must be specified\n";
|
||||
rc = 1;
|
||||
}
|
||||
if (rc==0 && write_.empty() ) {
|
||||
std::cerr << progname() << ": Write file must be specified\n";
|
||||
rc = 1;
|
||||
}
|
||||
if (preserve_ && iptc_ && exif_ && comment_ ) {
|
||||
std::cerr << progname() << ": Option -p has no effect when all metadata types are specified.\n";
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
} // Params::getopt
|
||||
|
||||
|
||||
void Params::usage(std::ostream& os) const
|
||||
{
|
||||
os << "\nReads and writes raw metadata. Use -h option for help.\n"
|
||||
<< "Usage: " << progname()
|
||||
<< " [-iecaph] readfile writefile\n";
|
||||
}
|
||||
|
||||
void Params::help(std::ostream& os) const
|
||||
{
|
||||
usage(os);
|
||||
os << "\nOptions:\n"
|
||||
<< " -i Read Iptc data from readfile and write to writefile.\n"
|
||||
<< " -e Read Exif data from readfile and write to writefile.\n"
|
||||
<< " -c Read Jpeg comment from readfile and write to writefile.\n"
|
||||
<< " -a Read all metadata from readfile and write to writefile.\n"
|
||||
<< " -p Preserve existing metadata in writefile if not replaced.\n"
|
||||
<< " -h Display this help and exit.\n\n";
|
||||
} // Params::help
|
||||
|
||||
86
src/metacopy.hpp
Normal file
86
src/metacopy.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*!
|
||||
@file metacopy.hpp
|
||||
@brief Defines class Params, used for the command line handling
|
||||
@version $Name: $ $Revision: 1.1 $
|
||||
@author Brad Schick (brad) <schick@robotbattle.com>
|
||||
@date 13-Jul-04, brad: created
|
||||
*/
|
||||
#ifndef METACOPY_HPP_
|
||||
#define METACOPY_HPP_
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
class Params : public Util::Getopt {
|
||||
private:
|
||||
std::string optstring_;
|
||||
bool first_;
|
||||
|
||||
public:
|
||||
bool help_; //!< Help option flag.
|
||||
bool iptc_; //!< IPTC option flag.
|
||||
bool exif_; //!< Exif option flag.
|
||||
bool comment_; //!< JPEG comment option flag.
|
||||
bool preserve_; //!< Preserve existing metadata option flag.
|
||||
std::string read_; //!< Source file
|
||||
std::string write_; //!< Destination file
|
||||
|
||||
public:
|
||||
/*!
|
||||
@brief Default constructor. Note that optstring_ is initialized here.
|
||||
*/
|
||||
Params() : optstring_(":iecaph"),
|
||||
first_(true),
|
||||
help_(false),
|
||||
iptc_(false),
|
||||
exif_(false),
|
||||
comment_(false),
|
||||
preserve_(false)
|
||||
{}
|
||||
|
||||
/*!
|
||||
@brief Call Getopt::getopt() with optstring, to initiate command line
|
||||
argument parsing, perform consistency checks after all command line
|
||||
arguments are parsed.
|
||||
|
||||
@param argc Argument count as passed to main() on program invocation.
|
||||
@param argv Argument array as passed to main() on program invocation.
|
||||
|
||||
@return 0 if successful, >0 in case of errors.
|
||||
*/
|
||||
int getopt(int argc, char* const argv[]);
|
||||
|
||||
//! Handle options and their arguments.
|
||||
virtual int option(int opt, const std::string& optarg, int optopt);
|
||||
|
||||
//! Handle non-option parameters.
|
||||
virtual int nonoption(const std::string& argv);
|
||||
|
||||
//! Print a minimal usage note to an output stream.
|
||||
void usage(std::ostream& os =std::cout) const;
|
||||
|
||||
//! Print further usage explanations to an output stream.
|
||||
void help(std::ostream& os =std::cout) const;
|
||||
|
||||
}; // class Params
|
||||
|
||||
#endif // METACOPY_HPP_
|
||||
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: nikon1mn.cpp
|
||||
Version: $Name: $ $Revision: 1.2 $
|
||||
Version: $Name: $ $Revision: 1.3 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 17-May-04, ahu: created
|
||||
25-May-04, ahu: combined all Nikon formats in one component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.2 $ $RCSfile: nikonmn.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.3 $ $RCSfile: nikonmn.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -202,7 +202,7 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
int Nikon2MakerNote::readHeader(const char* buf,
|
||||
int Nikon2MakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
@ -219,7 +219,8 @@ namespace Exiv2 {
|
||||
int rc = 0;
|
||||
// Check the Nikon prefix
|
||||
if ( header_.size_ < 8
|
||||
|| std::string(header_.pData_, 6) != std::string("Nikon\0", 6)) {
|
||||
|| std::string(reinterpret_cast<char*>(header_.pData_), 6)
|
||||
!= std::string("Nikon\0", 6)) {
|
||||
rc = 2;
|
||||
}
|
||||
return rc;
|
||||
@ -387,7 +388,7 @@ namespace Exiv2 {
|
||||
absOffset_ = false;
|
||||
}
|
||||
|
||||
int Nikon3MakerNote::readHeader(const char* buf,
|
||||
int Nikon3MakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
@ -407,7 +408,8 @@ namespace Exiv2 {
|
||||
int rc = 0;
|
||||
// Check the Nikon prefix
|
||||
if ( header_.size_ < 18
|
||||
|| std::string(header_.pData_, 6) != std::string("Nikon\0", 6)) {
|
||||
|| std::string(reinterpret_cast<char*>(header_.pData_), 6)
|
||||
!= std::string("Nikon\0", 6)) {
|
||||
rc = 2;
|
||||
}
|
||||
return rc;
|
||||
@ -521,13 +523,14 @@ namespace Exiv2 {
|
||||
// free functions
|
||||
|
||||
MakerNote* createNikonMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
{
|
||||
// If there is no "Nikon" string it must be Nikon1 format
|
||||
if (len < 6 || std::string(buf, 6) != std::string("Nikon\0", 6)) {
|
||||
if (len < 6 || std::string(reinterpret_cast<const char*>(buf), 6)
|
||||
!= std::string("Nikon\0", 6)) {
|
||||
return new Nikon1MakerNote(alloc);
|
||||
}
|
||||
// If the "Nikon" string is not followed by a TIFF header, we assume
|
||||
|
||||
@ -28,10 +28,10 @@
|
||||
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
|
||||
Exif file format</a> by TsuruZoh Tachibanaya.<BR>
|
||||
Format 3: "EXIFutils Field Reference Guide".
|
||||
@version $Name: $ $Revision: 1.2 $
|
||||
@version $Name: $ $Revision: 1.3 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 17-May-04, ahu: created
|
||||
@date 17-May-04, ahu: created<BR>
|
||||
25-May-04, ahu: combined all Nikon formats in one component
|
||||
*/
|
||||
#ifndef NIKONMN_HPP_
|
||||
@ -78,7 +78,7 @@ namespace Exiv2 {
|
||||
this copy and is responsible to delete it!
|
||||
*/
|
||||
MakerNote* createNikonMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
@ -173,7 +173,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
int readHeader(const char* buf,
|
||||
int readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
@ -227,7 +227,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
int readHeader(const char* buf,
|
||||
int readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: sigmamn.cpp
|
||||
Version: $Name: $ $Revision: 1.6 $
|
||||
Version: $Name: $ $Revision: 1.7 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 02-Apr-04, ahu: created
|
||||
Credits: Sigma and Foveon MakerNote implemented according to the specification
|
||||
@ -29,7 +29,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: sigmamn.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: sigmamn.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -87,7 +87,7 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
int SigmaMakerNote::readHeader(const char* buf,
|
||||
int SigmaMakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
@ -108,8 +108,10 @@ namespace Exiv2 {
|
||||
int rc = 0;
|
||||
// Check the SIGMA or FOVEON prefix
|
||||
if ( header_.size_ < 10
|
||||
|| std::string(header_.pData_, 8) != std::string("SIGMA\0\0\0", 8)
|
||||
&& std::string(header_.pData_, 8) != std::string("FOVEON\0\0", 8)) {
|
||||
|| std::string(reinterpret_cast<char*>(header_.pData_), 8)
|
||||
!= std::string("SIGMA\0\0\0", 8)
|
||||
&& std::string(reinterpret_cast<char*>(header_.pData_), 8)
|
||||
!= std::string("FOVEON\0\0", 8)) {
|
||||
rc = 2;
|
||||
}
|
||||
return rc;
|
||||
@ -188,7 +190,7 @@ namespace Exiv2 {
|
||||
// free functions
|
||||
|
||||
MakerNote* createSigmaMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
@brief Sigma and Foveon MakerNote implemented according to the specification
|
||||
<a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html">
|
||||
SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon.
|
||||
@version $Name: $ $Revision: 1.5 $
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 02-Apr-04, ahu: created
|
||||
@ -72,7 +72,7 @@ namespace Exiv2 {
|
||||
this copy and is responsible to delete it!
|
||||
*/
|
||||
MakerNote* createSigmaMakerNote(bool alloc,
|
||||
const char* buf,
|
||||
const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
@ -96,7 +96,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
int readHeader(const char* buf,
|
||||
int readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: tags.cpp
|
||||
Version: $Name: $ $Revision: 1.28 $
|
||||
Version: $Name: $ $Revision: 1.29 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 15-Jan-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.28 $ $RCSfile: tags.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.29 $ $RCSfile: tags.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -779,7 +779,7 @@ namespace Exiv2 {
|
||||
value.copy(buf.pData_, bigEndian);
|
||||
// Hack: Skip the leading 8-Byte character code, truncate
|
||||
// trailing '\0's and let the stream take care of the remainder
|
||||
std::string userComment(buf.pData_ + 8, buf.size_ - 8);
|
||||
std::string userComment(reinterpret_cast<char*>(buf.pData_) + 8, buf.size_ - 8);
|
||||
std::string::size_type pos = userComment.find_last_not_of('\0');
|
||||
os << userComment.substr(0, pos + 1);
|
||||
}
|
||||
|
||||
@ -21,10 +21,10 @@
|
||||
/*!
|
||||
@file tags.hpp
|
||||
@brief Exif tag and type information
|
||||
@version $Name: $ $Revision: 1.22 $
|
||||
@version $Name: $ $Revision: 1.23 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Jan-04, ahu: created
|
||||
@date 15-Jan-04, ahu: created<BR>
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
#ifndef TAGS_HPP_
|
||||
|
||||
104
src/types.cpp
104
src/types.cpp
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: types.cpp
|
||||
Version: $Name: $ $Revision: 1.9 $
|
||||
Version: $Name: $ $Revision: 1.10 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: types.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: types.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -77,139 +77,139 @@ namespace Exiv2 {
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
uint16 getUShort(const char* buf, ByteOrder byteOrder)
|
||||
uint16 getUShort(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
return (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
|
||||
return (byte)buf[1] << 8 | (byte)buf[0];
|
||||
}
|
||||
else {
|
||||
return (unsigned char)buf[0] << 8 | (unsigned char)buf[1];
|
||||
return (byte)buf[0] << 8 | (byte)buf[1];
|
||||
}
|
||||
}
|
||||
|
||||
uint32 getULong(const char* buf, ByteOrder byteOrder)
|
||||
uint32 getULong(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
return (unsigned char)buf[3] << 24 | (unsigned char)buf[2] << 16
|
||||
| (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
|
||||
return (byte)buf[3] << 24 | (byte)buf[2] << 16
|
||||
| (byte)buf[1] << 8 | (byte)buf[0];
|
||||
}
|
||||
else {
|
||||
return (unsigned char)buf[0] << 24 | (unsigned char)buf[1] << 16
|
||||
| (unsigned char)buf[2] << 8 | (unsigned char)buf[3];
|
||||
return (byte)buf[0] << 24 | (byte)buf[1] << 16
|
||||
| (byte)buf[2] << 8 | (byte)buf[3];
|
||||
}
|
||||
}
|
||||
|
||||
URational getURational(const char* buf, ByteOrder byteOrder)
|
||||
URational getURational(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
uint32 nominator = getULong(buf, byteOrder);
|
||||
uint32 denominator = getULong(buf + 4, byteOrder);
|
||||
return std::make_pair(nominator, denominator);
|
||||
}
|
||||
|
||||
int16 getShort(const char* buf, ByteOrder byteOrder)
|
||||
int16 getShort(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
return (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
|
||||
return (byte)buf[1] << 8 | (byte)buf[0];
|
||||
}
|
||||
else {
|
||||
return (unsigned char)buf[0] << 8 | (unsigned char)buf[1];
|
||||
return (byte)buf[0] << 8 | (byte)buf[1];
|
||||
}
|
||||
}
|
||||
|
||||
int32 getLong(const char* buf, ByteOrder byteOrder)
|
||||
int32 getLong(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
return (unsigned char)buf[3] << 24 | (unsigned char)buf[2] << 16
|
||||
| (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
|
||||
return (byte)buf[3] << 24 | (byte)buf[2] << 16
|
||||
| (byte)buf[1] << 8 | (byte)buf[0];
|
||||
}
|
||||
else {
|
||||
return (unsigned char)buf[0] << 24 | (unsigned char)buf[1] << 16
|
||||
| (unsigned char)buf[2] << 8 | (unsigned char)buf[3];
|
||||
return (byte)buf[0] << 24 | (byte)buf[1] << 16
|
||||
| (byte)buf[2] << 8 | (byte)buf[3];
|
||||
}
|
||||
}
|
||||
|
||||
Rational getRational(const char* buf, ByteOrder byteOrder)
|
||||
Rational getRational(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
int32 nominator = getLong(buf, byteOrder);
|
||||
int32 denominator = getLong(buf + 4, byteOrder);
|
||||
return std::make_pair(nominator, denominator);
|
||||
}
|
||||
|
||||
long us2Data(char* buf, uint16 s, ByteOrder byteOrder)
|
||||
long us2Data(byte* buf, uint16 s, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
buf[0] = (char)(s & 0x00ff);
|
||||
buf[1] = (char)((s & 0xff00) >> 8);
|
||||
buf[0] = (byte)(s & 0x00ff);
|
||||
buf[1] = (byte)((s & 0xff00) >> 8);
|
||||
}
|
||||
else {
|
||||
buf[0] = (char)((s & 0xff00) >> 8);
|
||||
buf[1] = (char)(s & 0x00ff);
|
||||
buf[0] = (byte)((s & 0xff00) >> 8);
|
||||
buf[1] = (byte)(s & 0x00ff);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
long ul2Data(char* buf, uint32 l, ByteOrder byteOrder)
|
||||
long ul2Data(byte* buf, uint32 l, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
buf[0] = (char)(l & 0x000000ff);
|
||||
buf[1] = (char)((l & 0x0000ff00) >> 8);
|
||||
buf[2] = (char)((l & 0x00ff0000) >> 16);
|
||||
buf[3] = (char)((l & 0xff000000) >> 24);
|
||||
buf[0] = (byte)(l & 0x000000ff);
|
||||
buf[1] = (byte)((l & 0x0000ff00) >> 8);
|
||||
buf[2] = (byte)((l & 0x00ff0000) >> 16);
|
||||
buf[3] = (byte)((l & 0xff000000) >> 24);
|
||||
}
|
||||
else {
|
||||
buf[0] = (char)((l & 0xff000000) >> 24);
|
||||
buf[1] = (char)((l & 0x00ff0000) >> 16);
|
||||
buf[2] = (char)((l & 0x0000ff00) >> 8);
|
||||
buf[3] = (char)(l & 0x000000ff);
|
||||
buf[0] = (byte)((l & 0xff000000) >> 24);
|
||||
buf[1] = (byte)((l & 0x00ff0000) >> 16);
|
||||
buf[2] = (byte)((l & 0x0000ff00) >> 8);
|
||||
buf[3] = (byte)(l & 0x000000ff);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
long ur2Data(char* buf, URational l, ByteOrder byteOrder)
|
||||
long ur2Data(byte* buf, URational l, ByteOrder byteOrder)
|
||||
{
|
||||
long o = ul2Data(buf, l.first, byteOrder);
|
||||
o += ul2Data(buf+o, l.second, byteOrder);
|
||||
return o;
|
||||
}
|
||||
|
||||
long s2Data(char* buf, int16 s, ByteOrder byteOrder)
|
||||
long s2Data(byte* buf, int16 s, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
buf[0] = (char)(s & 0x00ff);
|
||||
buf[1] = (char)((s & 0xff00) >> 8);
|
||||
buf[0] = (byte)(s & 0x00ff);
|
||||
buf[1] = (byte)((s & 0xff00) >> 8);
|
||||
}
|
||||
else {
|
||||
buf[0] = (char)((s & 0xff00) >> 8);
|
||||
buf[1] = (char)(s & 0x00ff);
|
||||
buf[0] = (byte)((s & 0xff00) >> 8);
|
||||
buf[1] = (byte)(s & 0x00ff);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
long l2Data(char* buf, int32 l, ByteOrder byteOrder)
|
||||
long l2Data(byte* buf, int32 l, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
buf[0] = (char)(l & 0x000000ff);
|
||||
buf[1] = (char)((l & 0x0000ff00) >> 8);
|
||||
buf[2] = (char)((l & 0x00ff0000) >> 16);
|
||||
buf[3] = (char)((l & 0xff000000) >> 24);
|
||||
buf[0] = (byte)(l & 0x000000ff);
|
||||
buf[1] = (byte)((l & 0x0000ff00) >> 8);
|
||||
buf[2] = (byte)((l & 0x00ff0000) >> 16);
|
||||
buf[3] = (byte)((l & 0xff000000) >> 24);
|
||||
}
|
||||
else {
|
||||
buf[0] = (char)((l & 0xff000000) >> 24);
|
||||
buf[1] = (char)((l & 0x00ff0000) >> 16);
|
||||
buf[2] = (char)((l & 0x0000ff00) >> 8);
|
||||
buf[3] = (char)(l & 0x000000ff);
|
||||
buf[0] = (byte)((l & 0xff000000) >> 24);
|
||||
buf[1] = (byte)((l & 0x00ff0000) >> 16);
|
||||
buf[2] = (byte)((l & 0x0000ff00) >> 8);
|
||||
buf[3] = (byte)(l & 0x000000ff);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
long r2Data(char* buf, Rational l, ByteOrder byteOrder)
|
||||
long r2Data(byte* buf, Rational l, ByteOrder byteOrder)
|
||||
{
|
||||
long o = l2Data(buf, l.first, byteOrder);
|
||||
o += l2Data(buf+o, l.second, byteOrder);
|
||||
return o;
|
||||
}
|
||||
|
||||
void hexdump(std::ostream& os, const char* buf, long len, long offset)
|
||||
void hexdump(std::ostream& os, const byte* buf, long len, long offset)
|
||||
{
|
||||
const std::string::size_type pos = 8 + 16 * 3 + 2;
|
||||
const std::string align(pos, ' ');
|
||||
@ -221,7 +221,7 @@ namespace Exiv2 {
|
||||
<< i + offset << " ";
|
||||
std::ostringstream ss;
|
||||
do {
|
||||
unsigned char c = buf[i];
|
||||
byte c = buf[i];
|
||||
os << std::setw(2) << std::setfill('0')
|
||||
<< std::hex << (int)c << " ";
|
||||
ss << ((int)c >= 31 && (int)c < 127 ? buf[i] : '.');
|
||||
|
||||
@ -21,10 +21,10 @@
|
||||
/*!
|
||||
@file types.hpp
|
||||
@brief Type definitions for %Exiv2 and related functionality
|
||||
@version $Name: $ $Revision: 1.15 $
|
||||
@version $Name: $ $Revision: 1.16 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@date 09-Jan-04, ahu: created<BR>
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
#ifndef TYPES_HPP_
|
||||
@ -54,6 +54,8 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
//! 1 byte unsigned integer type.
|
||||
typedef unsigned char byte;
|
||||
//! 2 byte unsigned integer type.
|
||||
typedef unsigned short uint16;
|
||||
//! 4 byte unsigned integer type.
|
||||
@ -132,33 +134,33 @@ namespace Exiv2 {
|
||||
//! Default constructor
|
||||
DataBuf() : size_(0), pData_(0) {}
|
||||
//! Constructor with an initial buffer size
|
||||
DataBuf(long size) : size_(size), pData_(new char[size]) {}
|
||||
DataBuf(long size) : size_(size), pData_(new byte[size]) {}
|
||||
//! Destructor, deletes the allocated buffer
|
||||
~DataBuf() { delete[] pData_; }
|
||||
//! Allocate a data buffer of the given size
|
||||
void alloc(long size)
|
||||
{ delete[] pData_; size_ = size; pData_ = new char[size]; }
|
||||
{ if( size > size_ ){delete[] pData_; size_ = size; pData_ = new byte[size];} }
|
||||
//! The current size of the buffer
|
||||
long size_;
|
||||
//! Pointer to the buffer, 0 if none has been allocated
|
||||
char* pData_;
|
||||
byte* pData_;
|
||||
}; // class DataBuf
|
||||
|
||||
// *****************************************************************************
|
||||
// free functions
|
||||
|
||||
//! Read a 2 byte unsigned short value from the data buffer
|
||||
uint16 getUShort(const char* buf, ByteOrder byteOrder);
|
||||
uint16 getUShort(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 4 byte unsigned long value from the data buffer
|
||||
uint32 getULong(const char* buf, ByteOrder byteOrder);
|
||||
uint32 getULong(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read an 8 byte unsigned rational value from the data buffer
|
||||
URational getURational(const char* buf, ByteOrder byteOrder);
|
||||
URational getURational(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 2 byte signed short value from the data buffer
|
||||
int16 getShort(const char* buf, ByteOrder byteOrder);
|
||||
int16 getShort(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 4 byte signed long value from the data buffer
|
||||
int32 getLong(const char* buf, ByteOrder byteOrder);
|
||||
int32 getLong(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read an 8 byte signed rational value from the data buffer
|
||||
Rational getRational(const char* buf, ByteOrder byteOrder);
|
||||
Rational getRational(const byte* buf, ByteOrder byteOrder);
|
||||
|
||||
//! Output operator for our fake rational
|
||||
std::ostream& operator<<(std::ostream& os, const Rational& r);
|
||||
@ -173,39 +175,39 @@ namespace Exiv2 {
|
||||
@brief Convert an unsigned short to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long us2Data(char* buf, uint16 s, ByteOrder byteOrder);
|
||||
long us2Data(byte* buf, uint16 s, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Convert an unsigned long to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long ul2Data(char* buf, uint32 l, ByteOrder byteOrder);
|
||||
long ul2Data(byte* buf, uint32 l, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Convert an unsigned rational to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long ur2Data(char* buf, URational l, ByteOrder byteOrder);
|
||||
long ur2Data(byte* buf, URational l, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Convert a signed short to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long s2Data(char* buf, int16 s, ByteOrder byteOrder);
|
||||
long s2Data(byte* buf, int16 s, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Convert a signed long to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long l2Data(char* buf, int32 l, ByteOrder byteOrder);
|
||||
long l2Data(byte* buf, int32 l, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Convert a signed rational to data, write the data to the buffer,
|
||||
return number of bytes written.
|
||||
*/
|
||||
long r2Data(char* buf, Rational l, ByteOrder byteOrder);
|
||||
long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
|
||||
|
||||
/*!
|
||||
@brief Print len bytes from buf in hex and ASCII format to the given
|
||||
stream, prefixed with the position in the buffer adjusted by
|
||||
offset.
|
||||
*/
|
||||
void hexdump(std::ostream& os, const char* buf, long len, long offset =0);
|
||||
void hexdump(std::ostream& os, const byte* buf, long len, long offset =0);
|
||||
|
||||
/*!
|
||||
@brief Return the greatest common denominator of integers a and b.
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: utils.cpp
|
||||
Version: $Name: $ $Revision: 1.8 $
|
||||
Version: $Name: $ $Revision: 1.9 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 08-Dec-03, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: utils.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: utils.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -96,15 +96,15 @@ int Getopt::getopt(int argc, char* const argv[], const std::string& optstring)
|
||||
if (path == "") return ".";
|
||||
// Strip trailing slashes
|
||||
std::string p = path;
|
||||
while (p.length() > 1 && p[p.length()-1] == '/') {
|
||||
while (p.length() > 1 && p[p.length()-1] == SEPERATOR_CHR) {
|
||||
p = p.substr(0, p.length()-1);
|
||||
}
|
||||
if (p == "/") return "/";
|
||||
std::string::size_type idx = p.rfind('/');
|
||||
if (p == SEPERATOR_STR) return SEPERATOR_STR;
|
||||
std::string::size_type idx = p.rfind(SEPERATOR_CHR);
|
||||
if (idx == std::string::npos) return ".";
|
||||
if (idx == 0) return "/";
|
||||
if (idx == 0) return SEPERATOR_STR;
|
||||
p = p.substr(0, idx);
|
||||
while (p.length() > 1 && p[p.length()-1] == '/') {
|
||||
while (p.length() > 1 && p[p.length()-1] == SEPERATOR_CHR) {
|
||||
p = p.substr(0, p.length()-1);
|
||||
}
|
||||
return p;
|
||||
@ -115,11 +115,11 @@ int Getopt::getopt(int argc, char* const argv[], const std::string& optstring)
|
||||
if (path == "") return ".";
|
||||
// Strip trailing slashes
|
||||
std::string p = path;
|
||||
while (p.length() > 1 && p[p.length()-1] == '/') {
|
||||
while (p.length() > 1 && p[p.length()-1] == SEPERATOR_CHR) {
|
||||
p = p.substr(0, p.length()-1);
|
||||
}
|
||||
if (p == "/") return p;
|
||||
std::string::size_type idx = p.rfind('/');
|
||||
if (p == SEPERATOR_STR) return p;
|
||||
std::string::size_type idx = p.rfind(SEPERATOR_CHR);
|
||||
if (idx != std::string::npos) p = p.substr(idx+1);
|
||||
if (delsuffix) p = p.substr(0, p.length() - suffix(p).length());
|
||||
return p;
|
||||
|
||||
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: value.cpp
|
||||
Version: $Name: $ $Revision: 1.7 $
|
||||
Version: $Name: $ $Revision: 1.8 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: value.cpp,v $")
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: value.cpp,v $")
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -108,10 +108,10 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DataValue::read(const char* buf, long len, ByteOrder byteOrder)
|
||||
void DataValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
// byteOrder not needed
|
||||
value_ = std::string(buf, len);
|
||||
value_ = std::string(reinterpret_cast<const char*>(buf), len);
|
||||
}
|
||||
|
||||
void DataValue::read(const std::string& buf)
|
||||
@ -124,10 +124,12 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
|
||||
long DataValue::copy(char* buf, ByteOrder byteOrder) const
|
||||
long DataValue::copy(byte* buf, ByteOrder byteOrder) const
|
||||
{
|
||||
// byteOrder not needed
|
||||
return static_cast<long>(value_.copy(buf, value_.size()));
|
||||
return static_cast<long>(
|
||||
value_.copy(reinterpret_cast<char*>(buf), value_.size())
|
||||
);
|
||||
}
|
||||
|
||||
long DataValue::size() const
|
||||
@ -144,7 +146,7 @@ namespace Exiv2 {
|
||||
{
|
||||
std::string::size_type end = value_.size();
|
||||
for (std::string::size_type i = 0; i != end; ++i) {
|
||||
os << static_cast<int>(static_cast<unsigned char>(value_[i]))
|
||||
os << static_cast<int>(static_cast<byte>(value_[i]))
|
||||
<< " ";
|
||||
}
|
||||
return os;
|
||||
@ -158,10 +160,10 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AsciiValue::read(const char* buf, long len, ByteOrder byteOrder)
|
||||
void AsciiValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
// byteOrder not needed
|
||||
value_ = std::string(buf, len);
|
||||
value_ = std::string(reinterpret_cast<const char*>(buf), len);
|
||||
}
|
||||
|
||||
void AsciiValue::read(const std::string& buf)
|
||||
@ -170,10 +172,12 @@ namespace Exiv2 {
|
||||
if (value_[value_.size()-1] != '\0') value_ += '\0';
|
||||
}
|
||||
|
||||
long AsciiValue::copy(char* buf, ByteOrder byteOrder) const
|
||||
long AsciiValue::copy(byte* buf, ByteOrder byteOrder) const
|
||||
{
|
||||
// byteOrder not needed
|
||||
return static_cast<long>(value_.copy(buf, value_.size()));
|
||||
return static_cast<long>(
|
||||
value_.copy(reinterpret_cast<char*>(buf), value_.size())
|
||||
);
|
||||
}
|
||||
|
||||
long AsciiValue::size() const
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file value.hpp
|
||||
@brief Value interface and concrete subclasses
|
||||
@version $Name: $ $Revision: 1.11 $
|
||||
@version $Name: $ $Revision: 1.12 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@ -75,7 +75,7 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
*/
|
||||
virtual void read(const char* buf, long len, ByteOrder byteOrder) =0;
|
||||
virtual void read(const byte* buf, long len, ByteOrder byteOrder) =0;
|
||||
/*!
|
||||
@brief Set the value from a string buffer. The format of the string
|
||||
corresponds to that of the write() method, i.e., a string
|
||||
@ -106,7 +106,7 @@ namespace Exiv2 {
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@return Number of characters written.
|
||||
*/
|
||||
virtual long copy(char* buf, ByteOrder byteOrder) const =0;
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
|
||||
//! Return the number of components of the value
|
||||
virtual long count() const =0;
|
||||
//! Return the size of the value in bytes
|
||||
@ -218,7 +218,7 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
*/
|
||||
virtual void read(const char* buf,
|
||||
virtual void read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
//! Set the data from a string of integer values (e.g., "0 1 2 3")
|
||||
@ -240,7 +240,7 @@ namespace Exiv2 {
|
||||
@param byteOrder Byte order. Not needed.
|
||||
@return Number of characters written.
|
||||
*/
|
||||
virtual long copy(char* buf, ByteOrder byteOrder =invalidByteOrder) const;
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
|
||||
virtual long count() const { return size(); }
|
||||
virtual long size() const;
|
||||
virtual DataValue* clone() const;
|
||||
@ -281,7 +281,7 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
*/
|
||||
virtual void read(const char* buf,
|
||||
virtual void read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
/*!
|
||||
@ -307,7 +307,7 @@ namespace Exiv2 {
|
||||
@param byteOrder Byte order. Not used.
|
||||
@return Number of characters written.
|
||||
*/
|
||||
virtual long copy(char* buf, ByteOrder byteOrder =invalidByteOrder) const;
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
|
||||
virtual long count() const { return size(); }
|
||||
virtual long size() const;
|
||||
virtual AsciiValue* clone() const;
|
||||
@ -366,7 +366,7 @@ namespace Exiv2 {
|
||||
//@{
|
||||
//! Assignment operator.
|
||||
ValueType<T>& operator=(const ValueType<T>& rhs);
|
||||
virtual void read(const char* buf, long len, ByteOrder byteOrder);
|
||||
virtual void read(const byte* buf, long len, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Set the data from a string of values of type T (e.g.,
|
||||
"0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
|
||||
@ -378,7 +378,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual long copy(char* buf, ByteOrder byteOrder) const;
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder) const;
|
||||
virtual long count() const { return static_cast<long>(value_.size()); }
|
||||
virtual long size() const;
|
||||
virtual ValueType<T>* clone() const;
|
||||
@ -432,40 +432,40 @@ namespace Exiv2 {
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@return A value of type T.
|
||||
*/
|
||||
template<typename T> T getValue(const char* buf, ByteOrder byteOrder);
|
||||
template<typename T> T getValue(const byte* buf, ByteOrder byteOrder);
|
||||
// Specialization for a 2 byte unsigned short value.
|
||||
template<>
|
||||
inline uint16 getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline uint16 getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getUShort(buf, byteOrder);
|
||||
}
|
||||
// Specialization for a 4 byte unsigned long value.
|
||||
template<>
|
||||
inline uint32 getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline uint32 getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getULong(buf, byteOrder);
|
||||
}
|
||||
// Specialization for an 8 byte unsigned rational value.
|
||||
template<>
|
||||
inline URational getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline URational getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getURational(buf, byteOrder);
|
||||
}
|
||||
// Specialization for a 2 byte signed short value.
|
||||
template<>
|
||||
inline int16 getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline int16 getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getShort(buf, byteOrder);
|
||||
}
|
||||
// Specialization for a 4 byte signed long value.
|
||||
template<>
|
||||
inline int32 getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline int32 getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getLong(buf, byteOrder);
|
||||
}
|
||||
// Specialization for an 8 byte signed rational value.
|
||||
template<>
|
||||
inline Rational getValue(const char* buf, ByteOrder byteOrder)
|
||||
inline Rational getValue(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
return getRational(buf, byteOrder);
|
||||
}
|
||||
@ -482,13 +482,13 @@ namespace Exiv2 {
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@return The number of bytes written to the buffer.
|
||||
*/
|
||||
template<typename T> long toData(char* buf, T t, ByteOrder byteOrder);
|
||||
template<typename T> long toData(byte* buf, T t, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Specialization to write an unsigned short to the data buffer.
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, uint16 t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, uint16 t, ByteOrder byteOrder)
|
||||
{
|
||||
return us2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -497,7 +497,7 @@ namespace Exiv2 {
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, uint32 t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, uint32 t, ByteOrder byteOrder)
|
||||
{
|
||||
return ul2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -506,7 +506,7 @@ namespace Exiv2 {
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, URational t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, URational t, ByteOrder byteOrder)
|
||||
{
|
||||
return ur2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -515,7 +515,7 @@ namespace Exiv2 {
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, int16 t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, int16 t, ByteOrder byteOrder)
|
||||
{
|
||||
return s2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -524,7 +524,7 @@ namespace Exiv2 {
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, int32 t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, int32 t, ByteOrder byteOrder)
|
||||
{
|
||||
return l2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -533,7 +533,7 @@ namespace Exiv2 {
|
||||
Return the number of bytes written.
|
||||
*/
|
||||
template<>
|
||||
inline long toData(char* buf, Rational t, ByteOrder byteOrder)
|
||||
inline long toData(byte* buf, Rational t, ByteOrder byteOrder)
|
||||
{
|
||||
return r2Data(buf, t, byteOrder);
|
||||
}
|
||||
@ -548,7 +548,7 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ValueType<T>::read(const char* buf, long len, ByteOrder byteOrder)
|
||||
void ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
value_.clear();
|
||||
for (long i = 0; i < len; i += TypeInfo::typeSize(typeId())) {
|
||||
@ -568,7 +568,7 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
long ValueType<T>::copy(char* buf, ByteOrder byteOrder) const
|
||||
long ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const
|
||||
{
|
||||
long offset = 0;
|
||||
typename ValueList::const_iterator end = value_.end();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user