diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 1553c0347..2d3aa5d73 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -1213,7 +1213,9 @@ SAMPLEFORMAT_1;8 bits non signé SAMPLEFORMAT_2;16 bits non signé SAMPLEFORMAT_4;LogLuv 24 bits SAMPLEFORMAT_8;LogLuv 32 bits -SAMPLEFORMAT_16;32 bits à virgule flottante +SAMPLEFORMAT_16;16 bits à virgule flottante +SAMPLEFORMAT_32;24 bits à virgule flottante +SAMPLEFORMAT_64;32 bits à virgule flottante SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà SAVEDLG_FILEFORMAT;Format de fichier SAVEDLG_FORCEFORMATOPTS;Forcer les options d'enregistrement diff --git a/rtdata/languages/default b/rtdata/languages/default index a50b89443..dd1128029 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1350,11 +1350,13 @@ QINFO_ISO;ISO QINFO_NOEXIF;Exif data not available. QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) SAMPLEFORMAT_0;Unknown data format -SAMPLEFORMAT_1;Unsigned 8 bits -SAMPLEFORMAT_2;Unsigned 16 bits -SAMPLEFORMAT_4;LogLuv 24 bits -SAMPLEFORMAT_8;LogLuv 32 bits -SAMPLEFORMAT_16;32 bits floating point +SAMPLEFORMAT_1;8-bit unsigned +SAMPLEFORMAT_2;16-bit unsigned +SAMPLEFORMAT_4;24-bit LogLuv +SAMPLEFORMAT_8;32-bit LogLuv +SAMPLEFORMAT_16;16-bit floating-point +SAMPLEFORMAT_32;24-bit floating-point +SAMPLEFORMAT_64;32-bit floating-point SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists SAVEDLG_FILEFORMAT;File format SAVEDLG_FORCEFORMATOPTS;Force saving options diff --git a/rtengine/curves.h b/rtengine/curves.h index 08f534896..6b5119a26 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -75,8 +75,8 @@ inline void setLutVal(const LUTf &lut, float &rval, float &gval, float &bval) { if (!OOG(rval) || !OOG(gval) || !OOG(bval)) { rval = lut[std::max(rval, 0.f)]; - gval = lut[std::max(rval, 0.f)]; - bval = lut[std::max(rval, 0.f)]; + gval = lut[std::max(gval, 0.f)]; + bval = lut[std::max(bval, 0.f)]; } else { setLutVal(lut, rval); setLutVal(lut, gval); diff --git a/rtengine/image16.cc b/rtengine/image16.cc index c545497e3..68dd4bb40 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -76,7 +76,7 @@ void Image16::getScanline (int row, unsigned char* buffer, int bps) /* * void Image16::setScanline (int row, unsigned char* buffer, int bps, int minValue[3], int maxValue[3]); - * has not been implemented yet, because as of now, this method is called for IIOSF_FLOAT sample format only + * has not been implemented yet, because as of now, this method is called for IIOSF_FLOATxx sample format only */ void Image16::setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples, float *minValue, float *maxValue) { diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 7ec9ba8cc..844c4df08 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -495,7 +495,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* const rtexif::Tag* const hdr = mnote->findTag("HDR"); if (hdr) { - if (hdr->toInt() > 0 && hdr->toInt(2) > 0) { + if (hdr->toInt() > 0) { isHDR = true; #if PRINT_HDR_PS_DETECTION printf("HDR detected ! -> \"HDR\" tag found\n"); @@ -573,28 +573,51 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* sampleFormat = IIOSF_UNSIGNED_SHORT; } } else if (sampleformat == SAMPLEFORMAT_IEEEFP) { - /* - * Not yet supported - * - if (bitspersample==16) { - sampleFormat = IIOSF_HALF; - isHDR = true; - }*/ - if (bitspersample == 32) { - sampleFormat = IIOSF_FLOAT; + if (bitspersample==16) { + sampleFormat = IIOSF_FLOAT16; isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); +#endif + } + else if (bitspersample == 24) { + sampleFormat = IIOSF_FLOAT24; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); +#endif + } + else if (bitspersample == 32) { + sampleFormat = IIOSF_FLOAT32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); #endif } } } else if (photometric == PHOTOMETRIC_CFA) { if (sampleformat == SAMPLEFORMAT_IEEEFP) { - sampleFormat = IIOSF_FLOAT; - isHDR = true; + if (bitspersample == 16) { + sampleFormat = IIOSF_FLOAT16; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); #endif + } + else if (bitspersample == 24) { + sampleFormat = IIOSF_FLOAT24; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); +#endif + } + else if (bitspersample == 32) { + sampleFormat = IIOSF_FLOAT32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); +#endif + } } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { if (bitspersample == 8) { // shouldn't occur... sampleFormat = IIOSF_UNSIGNED_CHAR; @@ -604,7 +627,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* } } else if (photometric == 34892 || photometric == 32892 /* Linear RAW (see DNG spec ; 32892 seem to be a flaw from Sony's ARQ files) */) { if (sampleformat == SAMPLEFORMAT_IEEEFP) { - sampleFormat = IIOSF_FLOAT; + sampleFormat = IIOSF_FLOAT32; isHDR = true; #if PRINT_HDR_PS_DETECTION printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 4aaeb3e24..e79678194 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -51,8 +51,13 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned return; } + // The DNG decoder convert to 32 bits float data even if the file contains 16 or 24 bits data. + // DNG_HalfToFloat and DNG_FP24ToFloat from dcraw.cc can be used to manually convert + // from 16 and 24 bits to 32 bits float respectively switch (sampleFormat) { - case (IIOSF_FLOAT): { + case (IIOSF_FLOAT16): + case (IIOSF_FLOAT24): + case (IIOSF_FLOAT32): { int ix = 0; float* sbuffer = (float*) buffer; diff --git a/rtengine/imageformat.h b/rtengine/imageformat.h index 2c9bb480d..cd86d536d 100644 --- a/rtengine/imageformat.h +++ b/rtengine/imageformat.h @@ -32,7 +32,9 @@ typedef enum IIO_Sample_Format { //IIOSF_HALF , // OpenEXR & NVidia's Half Float, not yet supported IIOSF_LOGLUV24 = 1 << 2, IIOSF_LOGLUV32 = 1 << 3, - IIOSF_FLOAT = 1 << 4 + IIOSF_FLOAT16 = 1 << 4, + IIOSF_FLOAT24 = 1 << 5, + IIOSF_FLOAT32 = 1 << 6 } IIOSampleFormat; typedef enum IIO_Sample_Arrangement { diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 1d07fbc84..6c70869ec 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -705,15 +705,16 @@ int ImageIO::getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, return IMIO_SUCCESS; } } else if (samplesperpixel == 3 && sampleformat == SAMPLEFORMAT_IEEEFP) { - /* - * Not yet supported - * - if (bitspersample==16) { - sFormat = IIOSF_HALF; + if (bitspersample==16) { + sFormat = IIOSF_FLOAT16; return IMIO_SUCCESS; - }*/ + } + if (bitspersample == 24) { + sFormat = IIOSF_FLOAT24; + return IMIO_SUCCESS; + } if (bitspersample == 32) { - sFormat = IIOSF_FLOAT; + sFormat = IIOSF_FLOAT32; return IMIO_SUCCESS; } } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 61bf90b31..7fa55cfb7 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -128,7 +128,9 @@ int StdImageSource::load (const Glib::ustring &fname) case (IIOSF_LOGLUV24): case (IIOSF_LOGLUV32): - case (IIOSF_FLOAT): { + case (IIOSF_FLOAT16): + case (IIOSF_FLOAT24): + case (IIOSF_FLOAT32): { img = new Imagefloat; break; } @@ -224,7 +226,7 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagement if (embedded) { in = embedded; } else { - if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT)) { + if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT16 | IIOSF_FLOAT24 | IIOSF_FLOAT32)) { skipTransform = true; } else { in = ICCStore::getInstance()->getsRGBProfile (); @@ -237,7 +239,7 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagement if (in == nullptr && embedded) { in = embedded; } else if (in == nullptr) { - if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT)) { + if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT16 | IIOSF_FLOAT24 | IIOSF_FLOAT32)) { skipTransform = true; } else { in = ICCStore::getInstance()->getsRGBProfile (); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index ff5607b02..0715ccfd6 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -463,22 +463,34 @@ Tag* TagDirectory::findTag (const char* name, bool lookUpward) const return t; } + Tag* foundTag = nullptr; + int tagDistance = 10000; + for (auto tag : tags) { if (tag->isDirectory()) { TagDirectory *dir; int i = 0; + // Find the shortest path to that tag while ((dir = tag->getDirectory(i)) != nullptr) { TagDirectory *dir = tag->getDirectory(); Tag* t = dir->findTag (name); if (t) { - return t; + int currTagDistance = t->getDistanceFrom(this); + if (currTagDistance < tagDistance) { + tagDistance = currTagDistance; + foundTag = t; + } } ++i; } } } + if (foundTag) { + return foundTag; + } + if (lookUpward && parent) { Tag* t = parent->findTagUpward(name); @@ -1420,6 +1432,20 @@ Tag::~Tag () } } +int Tag::getDistanceFrom(const TagDirectory *root) +{ + int i = 0; + TagDirectory *currTagDir = parent; + while (currTagDir != nullptr && currTagDir != root) { + ++i; + if (parent->getParent() == currTagDir) { + break; + } + currTagDir = parent->getParent(); + } + return i; +} + void Tag::setInt (int v, int ofs, TagType astype) { diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 52411b33c..1beba92ec 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -281,15 +281,15 @@ public: } // read/write value - int toInt (int ofs = 0, TagType astype = INVALID) const; - void fromInt (int v); - double toDouble (int ofs = 0) const; - double* toDoubleArray (int ofs = 0) const; - void toRational (int& num, int& denom, int ofs = 0) const; - void toString (char* buffer, int ofs = 0) const; - void fromString (const char* v, int size = -1); - void setInt (int v, int ofs = 0, TagType astype = LONG); - + int toInt (int ofs = 0, TagType astype = INVALID) const; + void fromInt (int v); + double toDouble (int ofs = 0) const; + double* toDoubleArray (int ofs = 0) const; + void toRational (int& num, int& denom, int ofs = 0) const; + void toString (char* buffer, int ofs = 0) const; + void fromString (const char* v, int size = -1); + void setInt (int v, int ofs = 0, TagType astype = LONG); + int getDistanceFrom (const TagDirectory *root); // additional getter/setter for more comfortable use std::string valueToString ();