Implement DNG bad pixels constant for LibRaw
Works if the FixBadPixelsConstant is zero, as implemented for dcraw. Other constant values may be implemented in the future.
This commit is contained in:
parent
d96809ecab
commit
d13badbbe0
@ -6935,28 +6935,6 @@ it under the terms of the one of two licenses as you choose:
|
||||
((int *)mask)[i] = getint(type);
|
||||
black = 0;
|
||||
break;
|
||||
case 51008: /* OpcodeList1 */
|
||||
{
|
||||
unsigned oldOrder = order;
|
||||
order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7
|
||||
unsigned ntags = get4(); // read the number of opcodes
|
||||
if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310)
|
||||
while (ntags-- && !ifp->eof) {
|
||||
unsigned opcode = get4();
|
||||
fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
|
||||
if (opcode == 4) { // FixBadPixelsConstant
|
||||
fseek (ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte
|
||||
if(get4() == 0) { // if raw 0 values should be treated as bad pixels, set zero_is_bad to true (1). That's the only value currently supported by rt
|
||||
zero_is_bad = 1;
|
||||
}
|
||||
} else {
|
||||
fseek (ifp, get4(), SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
order = oldOrder;
|
||||
break;
|
||||
}
|
||||
case 51009: /* OpcodeList2 */
|
||||
meta_offset = ftell(ifp);
|
||||
break;
|
||||
|
@ -168,10 +168,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::uint32_t readFixBadPixelsConstant(TagValueReader &reader)
|
||||
{
|
||||
reader.seekRelative(12); // Skip DNG spec version, flags, and tag size.
|
||||
return reader.readUInt();
|
||||
}
|
||||
|
||||
GainMap readGainMap(TagValueReader &reader)
|
||||
{
|
||||
reader.seekRelative(4); // skip 4 bytes as we know that the opcode 4 takes 4 byte
|
||||
reader.seekRelative(8); // skip 8 bytes as they don't interest us currently
|
||||
reader.seekRelative(12); // Skip DNG spec version, flags, and tag size.
|
||||
GainMap gainMap;
|
||||
gainMap.Top = reader.readUInt();
|
||||
gainMap.Left = reader.readUInt();
|
||||
@ -196,7 +201,11 @@ GainMap readGainMap(TagValueReader &reader)
|
||||
return gainMap;
|
||||
}
|
||||
|
||||
void readOpcodesList(const Exiv2::Value &value, std::vector<GainMap> &gainMaps)
|
||||
void readOpcodesList(
|
||||
const Exiv2::Value &value,
|
||||
std::uint32_t *fixBadPixelsConstant,
|
||||
bool *hasFixBadPixelsConstant,
|
||||
std::vector<GainMap> *gainMaps)
|
||||
{
|
||||
TagValueReader reader(value);
|
||||
std::uint32_t ntags = reader.readUInt(); // read the number of opcodes
|
||||
@ -205,8 +214,16 @@ void readOpcodesList(const Exiv2::Value &value, std::vector<GainMap> &gainMaps)
|
||||
}
|
||||
while (ntags-- && !reader.isEnd()) {
|
||||
unsigned opcode = reader.readUInt();
|
||||
if (opcode == 9 && gainMaps.size() < 4) {
|
||||
gainMaps.push_back(readGainMap(reader));
|
||||
if (opcode == 4 && (fixBadPixelsConstant || hasFixBadPixelsConstant)) {
|
||||
const auto constant = readFixBadPixelsConstant(reader);
|
||||
if (fixBadPixelsConstant) {
|
||||
*fixBadPixelsConstant = constant;
|
||||
}
|
||||
if (hasFixBadPixelsConstant) {
|
||||
*hasFixBadPixelsConstant = true;
|
||||
}
|
||||
} else if (opcode == 9 && gainMaps && gainMaps->size() < 4) {
|
||||
gainMaps->push_back(readGainMap(reader));
|
||||
} else {
|
||||
reader.seekRelative(8); // skip 8 bytes as they don't interest us currently
|
||||
reader.seekRelative(reader.readUInt());
|
||||
@ -826,16 +843,20 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) :
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t dngVersion = 0;
|
||||
std::uint32_t dngVersion = 0;
|
||||
if (find_exif_tag("Exif.Image.DNGVersion") && pos->count() == 4) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
dngVersion = (dngVersion << 8) + static_cast<uint32_t>(to_long(pos, i));
|
||||
dngVersion = (dngVersion << 8) + static_cast<std::uint32_t>(to_long(pos, i));
|
||||
}
|
||||
}
|
||||
|
||||
// Read gain maps.
|
||||
// Read DNG OpcodeList1.
|
||||
if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList1") || find_exif_tag("Exif.Image.OpcodeList1"))) {
|
||||
readOpcodesList(pos->value(), &fixBadPixelsConstant, &hasFixBadPixelsConstant_, nullptr);
|
||||
}
|
||||
// Read DNG OpcodeList2.
|
||||
if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList2") || find_exif_tag("Exif.Image.OpcodeList2"))) {
|
||||
readOpcodesList(pos->value(), gain_maps_);
|
||||
readOpcodesList(pos->value(), nullptr, nullptr, &gain_maps_);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
if (settings->verbose) {
|
||||
@ -1078,6 +1099,16 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const
|
||||
set_exif(exif, "Exif.Photo.DateTimeOriginal", buf);
|
||||
}
|
||||
|
||||
std::uint32_t FramesData::getFixBadPixelsConstant() const
|
||||
{
|
||||
return fixBadPixelsConstant;
|
||||
}
|
||||
|
||||
bool FramesData::hasFixBadPixelsConstant() const
|
||||
{
|
||||
return hasFixBadPixelsConstant_;
|
||||
}
|
||||
|
||||
std::vector<GainMap> FramesData::getGainMaps() const
|
||||
{
|
||||
return gain_maps_;
|
||||
|
@ -60,6 +60,8 @@ private:
|
||||
time_t modTimeStamp;
|
||||
bool isPixelShift;
|
||||
bool isHDR;
|
||||
std::uint32_t fixBadPixelsConstant;
|
||||
bool hasFixBadPixelsConstant_{false};
|
||||
std::vector<GainMap> gain_maps_;
|
||||
int w_;
|
||||
int h_;
|
||||
@ -90,6 +92,8 @@ public:
|
||||
std::string getOrientation() const override;
|
||||
Glib::ustring getFileName() const override;
|
||||
int getRating() const override;
|
||||
std::uint32_t getFixBadPixelsConstant() const override;
|
||||
bool hasFixBadPixelsConstant() const override;
|
||||
std::vector<GainMap> getGainMaps() const override;
|
||||
void getDimensions(int &w, int &h) const override;
|
||||
|
||||
|
@ -1439,7 +1439,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
|
||||
|
||||
int totBP = 0; // Hold count of bad pixels to correct
|
||||
|
||||
if (ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica)
|
||||
if (ri->zeroIsBad() || (getMetaData()->hasFixBadPixelsConstant() && getMetaData()->getFixBadPixelsConstant() == 0)) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica)
|
||||
bitmapBads.reset(new PixelsMap(W, H));
|
||||
totBP = findZeroPixels(*bitmapBads);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@ -159,6 +160,8 @@ public:
|
||||
static FramesMetaData* fromFile(const Glib::ustring& fname);
|
||||
|
||||
virtual Glib::ustring getFileName() const = 0;
|
||||
virtual std::uint32_t getFixBadPixelsConstant() const = 0;
|
||||
virtual bool hasFixBadPixelsConstant() const = 0;
|
||||
virtual std::vector<GainMap> getGainMaps() const = 0;
|
||||
virtual void getDimensions(int &w, int &h) const = 0;
|
||||
};
|
||||
|
@ -362,6 +362,16 @@ int CacheImageData::save (const Glib::ustring& fname)
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t CacheImageData::getFixBadPixelsConstant() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CacheImageData::hasFixBadPixelsConstant() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<GainMap> CacheImageData::getGainMaps() const
|
||||
{
|
||||
return std::vector<GainMap>();
|
||||
|
@ -117,6 +117,8 @@ public:
|
||||
bool getHDR() const override { return isHDR; }
|
||||
std::string getImageType() const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; }
|
||||
rtengine::IIOSampleFormat getSampleFormat() const override { return sampleFormat; }
|
||||
std::uint32_t getFixBadPixelsConstant() const override;
|
||||
bool hasFixBadPixelsConstant() const override;
|
||||
std::vector<GainMap> getGainMaps() const override;
|
||||
void getDimensions(int &w, int &h) const override
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user