Improved Panasonic RW2 decoder: now uses a dedicated PanasonicRaw tag table and reads Exif data from embedded preview image.
This commit is contained in:
parent
808494f0a1
commit
afe8efcc31
2
doc/templates/Makefile
vendored
2
doc/templates/Makefile
vendored
@ -52,7 +52,7 @@ TABLES = Exif \
|
||||
Nikon1 Nikon2 Nikon3 \
|
||||
Olympus OlympusCs OlympusEq OlympusRd OlympusRd2 \
|
||||
OlympusIp OlympusFi OlympusFe1 OlympusRi \
|
||||
Panasonic \
|
||||
Panasonic PanasonicRaw \
|
||||
Pentax \
|
||||
Sigma \
|
||||
Sony
|
||||
|
||||
7
doc/templates/tags-panasonic.html.in
vendored
7
doc/templates/tags-panasonic.html.in
vendored
@ -13,6 +13,13 @@ __index2__
|
||||
</div>
|
||||
__Panasonic__
|
||||
</div>
|
||||
<h2>Panasonic RAW Tags defined in Exiv2</h2>
|
||||
<div>
|
||||
<p>Tags found in IFD0 of Panasonic RAW and RW2 images.</p>
|
||||
<p>Click on a column header to sort the table.</p>
|
||||
</div>
|
||||
__PanasonicRaw__
|
||||
</div>
|
||||
<!-- closes content -->
|
||||
|
||||
</body>
|
||||
|
||||
@ -324,4 +324,38 @@ namespace Exiv2 {
|
||||
|
||||
} // PanasonicMakerNote::print0x0023
|
||||
|
||||
// Panasonic MakerNote Tag Info
|
||||
const TagInfo PanasonicMakerNote::tagInfoRaw_[] = {
|
||||
TagInfo(0x0001, "Version", N_("Version"), N_("Panasonic raw version"), panaRawIfdId, panaRaw, undefined, printExifVersion),
|
||||
TagInfo(0x0002, "SensorWidth", N_("Sensor Width"), N_("Sensor width"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0003, "SensorHeight", N_("Sensor Height"), N_("Sensor height"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0004, "SensorTopBorder", N_("Sensor Top Border"), N_("Sensor top border"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0005, "SensorLeftBorder", N_("Sensor Left Border"), N_("Sensor left border"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0006, "ImageHeight", N_("Image Height"), N_("Image height"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0007, "ImageWidth", N_("Image Width"), N_("Image width"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0011, "RedBalance", N_("Red Balance"), N_("Red balance (found in Digilux 2 RAW images)"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0012, "BlueBalance", N_("Blue Balance"), N_("Blue balance"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0017, "ISOSpeed", N_("ISO Speed"), N_("ISO speed setting"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0024, "WBRedLevel", N_("WB Red Level"), N_("WB red level"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0025, "WBGreenLevel", N_("WB Green Level"), N_("WB green level"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0026, "WBBlueLevel", N_("WB Blue Level"), N_("WB blue level"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x002e, "PreviewImage", N_("Preview Image"), N_("Preview image"), panaRawIfdId, panaRaw, undefined, printValue),
|
||||
TagInfo(0x010f, "Make", N_("Manufacturer"), N_("The manufacturer of the recording equipment"), panaRawIfdId, panaRaw, asciiString, printValue),
|
||||
TagInfo(0x0110, "Model", N_("Model"), N_("The model name or model number of the equipment"), panaRawIfdId, panaRaw, asciiString, printValue),
|
||||
TagInfo(0x0111, "StripOffsets", N_("Strip Offsets"), N_("Strip offsets"), panaRawIfdId, panaRaw, unsignedLong, printValue),
|
||||
TagInfo(0x0112, "Orientation", N_("Orientation"), N_("Orientation"), panaRawIfdId, panaRaw, unsignedShort, print0x0112),
|
||||
TagInfo(0x0116, "RowsPerStrip", N_("Rows Per Strip"), N_("The number of rows per strip"), panaRawIfdId, panaRaw, unsignedShort, printValue),
|
||||
TagInfo(0x0117, "StripByteCounts", N_("Strip Byte Counts"), N_("Strip byte counts"), panaRawIfdId, panaRaw, unsignedLong, printValue),
|
||||
TagInfo(0x0118, "RawDataOffset", N_("Raw Data Offset"), N_("Raw data offset"), panaRawIfdId, panaRaw, unsignedLong, printValue),
|
||||
TagInfo(0x8769, "ExifTag", N_("Exif IFD Pointer"), N_("A pointer to the Exif IFD"), panaRawIfdId, panaRaw, unsignedLong, printValue),
|
||||
TagInfo(0x8825, "GPSTag", N_("GPS Info IFD Pointer"), N_("A pointer to the GPS Info IFD"), panaRawIfdId, panaRaw, unsignedLong, printValue),
|
||||
// End of list marker
|
||||
TagInfo(0xffff, "(UnknownPanasonicRawTag)", "(UnknownPanasonicRawTag)", N_("Unknown PanasonicRaw tag"), panaRawIfdId, panaRaw, invalidTypeId, printValue)
|
||||
};
|
||||
|
||||
const TagInfo* PanasonicMakerNote::tagListRaw()
|
||||
{
|
||||
return tagInfoRaw_;
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
@ -55,6 +55,8 @@ namespace Exiv2 {
|
||||
public:
|
||||
//! Return read-only list of built-in Panasonic tags
|
||||
static const TagInfo* tagList();
|
||||
//! Return read-only list of built-in Panasonic RAW image tags (IFD0)
|
||||
static const TagInfo* tagListRaw();
|
||||
|
||||
//! @name Print functions for Panasonic %MakerNote tags
|
||||
//@{
|
||||
@ -65,8 +67,10 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! Tag information
|
||||
//! Makernote tag list
|
||||
static const TagInfo tagInfo_[];
|
||||
//! Taglist for IFD0 of Panasonic RAW images
|
||||
static const TagInfo tagInfoRaw_[];
|
||||
|
||||
}; // class PanasonicMakerNote
|
||||
|
||||
|
||||
@ -283,7 +283,7 @@ namespace {
|
||||
{ "Exif.Olympus.ThumbnailImage", 0 }, // 4
|
||||
{ "Exif.Olympus2.ThumbnailImage", 0 }, // 5
|
||||
{ "Exif.Minolta.Thumbnail", 0 }, // 6
|
||||
{ "Exif.Image.0x002e", 0 } // 7
|
||||
{ "Exif.PanasonicRaw.PreviewImage", 0 } // 7
|
||||
};
|
||||
|
||||
const LoaderTiff::Param LoaderTiff::param_[] = {
|
||||
|
||||
@ -42,6 +42,7 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
#include "tiffcomposite_int.hpp"
|
||||
#include "tiffimage_int.hpp"
|
||||
#include "image.hpp"
|
||||
#include "preview.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
@ -63,7 +64,8 @@ namespace Exiv2 {
|
||||
|
||||
int Rw2Image::pixelWidth() const
|
||||
{
|
||||
ExifData::const_iterator imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.0x0007"));
|
||||
ExifData::const_iterator imageWidth =
|
||||
exifData_.findKey(Exiv2::ExifKey("Exif.PanasonicRaw.SensorWidth"));
|
||||
if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
|
||||
return imageWidth->toLong();
|
||||
}
|
||||
@ -72,7 +74,8 @@ namespace Exiv2 {
|
||||
|
||||
int Rw2Image::pixelHeight() const
|
||||
{
|
||||
ExifData::const_iterator imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.0x0006"));
|
||||
ExifData::const_iterator imageHeight =
|
||||
exifData_.findKey(Exiv2::ExifKey("Exif.PanasonicRaw.SensorHeight"));
|
||||
if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
|
||||
return imageHeight->toLong();
|
||||
}
|
||||
@ -118,6 +121,33 @@ namespace Exiv2 {
|
||||
io_->mmap(),
|
||||
io_->size());
|
||||
setByteOrder(bo);
|
||||
|
||||
// A lot more metadata is hidden in the embedded preview image
|
||||
// Todo: This should go into the Rw2Parser, but for that it needs the Image
|
||||
PreviewManager loader(*this);
|
||||
PreviewPropertiesList list = loader.getPreviewProperties();
|
||||
// Todo: What if there are more preview images?
|
||||
if (list.size() > 1) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: RW2 image contains more than one preview. None used.\n";
|
||||
#endif
|
||||
}
|
||||
if (list.size() != 1) return;
|
||||
ExifData exifData;
|
||||
PreviewImage preview = loader.getPreviewImage(*list.begin());
|
||||
Image::AutoPtr image = ImageFactory::open(preview.pData(), preview.size());
|
||||
if (image.get() == 0) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to open RW2 preview image.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
image->readMetadata();
|
||||
for (ExifData::const_iterator pos = image->exifData().begin();
|
||||
pos != image->exifData().end(); ++pos) {
|
||||
exifData_.add(*pos);
|
||||
}
|
||||
|
||||
} // Rw2Image::readMetadata
|
||||
|
||||
void Rw2Image::writeMetadata()
|
||||
@ -140,7 +170,7 @@ namespace Exiv2 {
|
||||
xmpData,
|
||||
pData,
|
||||
size,
|
||||
Tag::root,
|
||||
Tag::pana,
|
||||
TiffMapping::findDecoder,
|
||||
&rw2Header);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ try {
|
||||
}
|
||||
|
||||
IfdId ifdId = ExifTags::ifdIdByIfdItem(item);
|
||||
if (ExifTags::isMakerIfd(ifdId)) {
|
||||
if (ExifTags::isExifIfd(ifdId) || ExifTags::isMakerIfd(ifdId)) {
|
||||
ExifTags::taglist(std::cout, ifdId);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -132,6 +132,7 @@ namespace Exiv2 {
|
||||
{ olympusFe9IfdId, "Makernote", "OlympusFe9", OlympusMakerNote::tagListFe },
|
||||
{ olympusRiIfdId, "Makernote", "OlympusRi", OlympusMakerNote::tagListRi },
|
||||
{ panasonicIfdId, "Makernote", "Panasonic", PanasonicMakerNote::tagList },
|
||||
{ panaRawIfdId, "PanaRaw", "PanasonicRaw", PanasonicMakerNote::tagListRaw },
|
||||
{ pentaxIfdId, "Makernote", "Pentax", PentaxMakerNote::tagList },
|
||||
{ sigmaIfdId, "Makernote", "Sigma", SigmaMakerNote::tagList },
|
||||
{ sonyIfdId, "Makernote", "Sony", SonyMakerNote::tagList },
|
||||
@ -155,6 +156,7 @@ namespace Exiv2 {
|
||||
{ iopTags, "Interoperability", N_("Interoperability information") },
|
||||
{ makerTags, "Makernote", N_("Vendor specific information") },
|
||||
{ dngTags, "DngTags", N_("Adobe DNG tags") },
|
||||
{ panaRaw, "PanasonicRaw", N_("Panasonic RAW tags") },
|
||||
{ lastSectionId, "(LastSection)", N_("Last section") }
|
||||
};
|
||||
|
||||
@ -1690,8 +1692,9 @@ namespace Exiv2 {
|
||||
case subImage1Id:
|
||||
case subImage2Id:
|
||||
case subImage3Id:
|
||||
case subImage4Id: rc = true; break;
|
||||
default: rc = false; break;
|
||||
case subImage4Id:
|
||||
case panaRawIfdId: rc = true; break;
|
||||
default: rc = false; break;
|
||||
}
|
||||
return rc;
|
||||
} // ExifTags::isExifIfd
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Exiv2 {
|
||||
enum SectionId { sectionIdNotSet,
|
||||
imgStruct, recOffset, imgCharacter, otherTags, exifFormat,
|
||||
exifVersion, imgConfig, userInfo, relatedFile, dateTime,
|
||||
captureCond, gpsTags, iopTags, makerTags, dngTags,
|
||||
captureCond, gpsTags, iopTags, makerTags, dngTags, panaRaw,
|
||||
lastSectionId };
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
@ -79,6 +79,7 @@ namespace Exiv2 {
|
||||
{ 8, "SubImage2" },
|
||||
{ 9, "SubImage3" },
|
||||
{ 10, "SubImage4" },
|
||||
{ 64, "PanasonicRaw" },
|
||||
{ 256, "MakerNote" },
|
||||
// 257 not needed (olympmn)
|
||||
{ 258, "Fujifilm" },
|
||||
|
||||
@ -77,6 +77,9 @@ namespace Exiv2 {
|
||||
Todo: what exactly are these and where should they go?
|
||||
Are they going to be mapped to the second part of an Exif key or are they
|
||||
the second part of the key?
|
||||
|
||||
@note Groups with ids > mn are Makernote groups and get treated slightly
|
||||
differently.
|
||||
*/
|
||||
namespace Group {
|
||||
const uint16_t none = 0; //!< Dummy group
|
||||
@ -90,6 +93,7 @@ namespace Exiv2 {
|
||||
const uint16_t subimg2 = 8; //!< 2nd TIFF SubIFD in IFD0
|
||||
const uint16_t subimg3 = 9; //!< 3rd TIFF SubIFD in IFD0
|
||||
const uint16_t subimg4 = 10; //!< 4th TIFF SubIFD in IFD0
|
||||
const uint16_t panaraw = 64; //!< IFD0 of Panasonic RAW images
|
||||
const uint16_t mn = 256; //!< Makernote
|
||||
const uint16_t ignr = 511; //!< Read but do not decode
|
||||
}
|
||||
@ -104,6 +108,7 @@ namespace Exiv2 {
|
||||
const uint32_t root = 0x20000; //!< Special tag: root IFD
|
||||
const uint32_t next = 0x30000; //!< Special tag: next IFD
|
||||
const uint32_t all = 0x40000; //!< Special tag: all tags in a group
|
||||
const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@ -313,7 +313,13 @@ namespace Exiv2 {
|
||||
{ Tag::root, Group::minocso, Group::minoltamn, 0x0001 },
|
||||
{ Tag::root, Group::minocsn, Group::minoltamn, 0x0003 },
|
||||
{ Tag::root, Group::minocs7, Group::minoltamn, 0x0004 },
|
||||
{ Tag::root, Group::minocs5, Group::minoltamn, 0x0114 }
|
||||
{ Tag::root, Group::minocs5, Group::minoltamn, 0x0114 },
|
||||
// ---------------------------------------------------------
|
||||
// Panasonic RW2 raw images
|
||||
{ Tag::pana, Group::none, Group::none, Tag::pana },
|
||||
{ Tag::pana, Group::panaraw, Group::none, Tag::pana },
|
||||
{ Tag::pana, Group::exif, Group::panaraw, 0x8769 },
|
||||
{ Tag::pana, Group::gps, Group::panaraw, 0x8825 }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -572,6 +578,19 @@ namespace Exiv2 {
|
||||
{ Tag::all, Group::minocs7, newTiffArrayElement<ttUnsignedShort, bigEndian> },
|
||||
{ Tag::all, Group::minocs5, newTiffArrayElement<ttUnsignedShort, bigEndian> },
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Root directory of Panasonic RAW images
|
||||
{ Tag::pana, Group::none, newTiffDirectory<Group::panaraw> },
|
||||
|
||||
// IFD0 of Panasonic RAW images
|
||||
{ 0x8769, Group::panaraw, newTiffSubIfd<Group::exif> },
|
||||
{ 0x8825, Group::panaraw, newTiffSubIfd<Group::gps> },
|
||||
// { 0x0111, Group::panaraw, newTiffImageData<0x0117, Group::panaraw> },
|
||||
// { 0x0117, Group::panaraw, newTiffImageSize<0x0111, Group::panaraw> },
|
||||
{ Tag::next, Group::panaraw, newTiffDirectory<Group::ignr> },
|
||||
{ Tag::all, Group::panaraw, newTiffEntry },
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tags which are not de/encoded
|
||||
{ Tag::next, Group::ignr, newTiffDirectory<Group::ignr> },
|
||||
{ Tag::all, Group::ignr, newTiffEntry }
|
||||
|
||||
@ -149,7 +149,8 @@ namespace Exiv2 {
|
||||
olympusFe1IfdId, olympusFe2IfdId, olympusFe3IfdId, olympusFe4IfdId,
|
||||
olympusFe5IfdId, olympusFe6IfdId, olympusFe7IfdId, olympusFe8IfdId,
|
||||
olympusFe9IfdId, olympusRiIfdId,
|
||||
panasonicIfdId, pentaxIfdId, sigmaIfdId, sonyIfdId,
|
||||
panasonicIfdId, panaRawIfdId,
|
||||
pentaxIfdId, sigmaIfdId, sonyIfdId,
|
||||
lastIfdId };
|
||||
|
||||
//! Container for binary data
|
||||
|
||||
Loading…
Reference in New Issue
Block a user