Make requested changes

This commit is contained in:
xiota 2024-04-16 15:49:40 +00:00
parent 1ad5ec3e9e
commit 4d715cf281
4 changed files with 64 additions and 66 deletions

View File

@ -24,6 +24,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <fcntl.h> #include <fcntl.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <png.h> #include <png.h>
@ -31,10 +32,7 @@
#include <tiffio.h> #include <tiffio.h>
#ifdef LIBJXL #ifdef LIBJXL
#include <fstream>
#include "jxl/decode.h"
#include "jxl/decode_cxx.h" #include "jxl/decode_cxx.h"
#include "jxl/resizable_parallel_runner.h"
#include "jxl/resizable_parallel_runner_cxx.h" #include "jxl/resizable_parallel_runner_cxx.h"
#endif #endif
@ -832,17 +830,16 @@ int ImageIO::loadTIFF (const Glib::ustring &fname)
#ifdef LIBJXL #ifdef LIBJXL
#define _PROFILE_ JXL_COLOR_PROFILE_TARGET_ORIGINAL #define _PROFILE_ JXL_COLOR_PROFILE_TARGET_ORIGINAL
// adapted from libjxl // adapted from libjxl
int ImageIO::loadJxl(const Glib::ustring &fname) int ImageIO::loadJXL(const Glib::ustring &fname)
{ {
if (pl) { if (pl) {
pl->setProgressStr("PROGRESSBAR_LOADJXL"); pl->setProgressStr("PROGRESSBAR_LOADJXL");
pl->setProgress(0.0); pl->setProgress(0.0);
} }
std::vector<uint8_t> icc_profile; std::vector<std::uint8_t> icc_profile;
std::vector<std::uint8_t> buffer;
gpointer buffer = nullptr; std::size_t buffer_size = 0;
size_t buffer_size = 0;
JxlBasicInfo info = {}; JxlBasicInfo info = {};
JxlPixelFormat format = {}; JxlPixelFormat format = {};
@ -852,28 +849,25 @@ int ImageIO::loadJxl(const Glib::ustring &fname)
format.endianness = JXL_NATIVE_ENDIAN; format.endianness = JXL_NATIVE_ENDIAN;
format.align = 0; format.align = 0;
// get file contents std::string const contents = Glib::file_get_contents(fname);
std::ifstream instream(fname.c_str(), std::ios::in | std::ios::binary); std::vector<std::uint8_t> const compressed(contents.begin(), contents.end());
std::vector<uint8_t> compressed(
(std::istreambuf_iterator<char>(instream)),
std::istreambuf_iterator<char>());
instream.close();
// multi-threaded parallel runner. // multi-threaded parallel runner.
auto runner = JxlResizableParallelRunnerMake(nullptr); auto runner = JxlResizableParallelRunnerMake(nullptr);
auto dec = JxlDecoderMake(nullptr); auto dec = JxlDecoderMake(nullptr);
if (JXL_DEC_SUCCESS != if (JXL_DEC_SUCCESS !=
JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO |
JXL_DEC_COLOR_ENCODING | JXL_DEC_COLOR_ENCODING |
JXL_DEC_FULL_IMAGE)) { JXL_DEC_FULL_IMAGE)) {
g_printerr("Error: JxlDecoderSubscribeEvents failed\n"); g_printerr("Error: JxlDecoderSubscribeEvents failed\n");
return IMIO_HEADERERROR; return IMIO_HEADERERROR;
} }
if (JXL_DEC_SUCCESS != if (JXL_DEC_SUCCESS !=
JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner,
runner.get())) { runner.get())) {
g_printerr("Error: JxlDecoderSetParallelRunner failed\n"); g_printerr("Error: JxlDecoderSetParallelRunner failed\n");
return IMIO_HEADERERROR; return IMIO_HEADERERROR;
} }
@ -897,31 +891,32 @@ int ImageIO::loadJxl(const Glib::ustring &fname)
// check for ICC profile // check for ICC profile
deleteLoadedProfileData(); deleteLoadedProfileData();
embProfile = nullptr; embProfile = nullptr;
size_t icc_size = 0; std::size_t icc_size = 0;
if (JXL_DEC_SUCCESS != if (JXL_DEC_SUCCESS !=
#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0)
JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size)
#else #else
JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size)
#endif #endif
) { ) {
g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n");
} }
if (icc_size > 0) { if (icc_size > 0) {
icc_profile.resize(icc_size); icc_profile.resize(icc_size);
if (JXL_DEC_SUCCESS != if (JXL_DEC_SUCCESS !=
#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0)
JxlDecoderGetColorAsICCProfile( JxlDecoderGetColorAsICCProfile(
dec.get(), &format, _PROFILE_, dec.get(), &format, _PROFILE_,
icc_profile.data(), icc_profile.size()) icc_profile.data(), icc_profile.size())
#else #else
JxlDecoderGetColorAsICCProfile( JxlDecoderGetColorAsICCProfile(
dec.get(), _PROFILE_, dec.get(), _PROFILE_,
icc_profile.data(), icc_profile.size()) icc_profile.data(), icc_profile.size())
#endif #endif
) { ) {
g_printerr( g_printerr(
"Warning: JxlDecoderGetColorAsICCProfile failed\n"); "Warning: JxlDecoderGetColorAsICCProfile failed\n");
} else { } else {
@ -932,7 +927,10 @@ int ImageIO::loadJxl(const Glib::ustring &fname)
g_printerr("Warning: Empty ICC data.\n"); g_printerr("Warning: Empty ICC data.\n");
} }
} else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) {
format.data_type = JXL_TYPE_FLOAT; // Note: If this assert is ever triggered, it should be changed
// to an assignment. We want the maximum bit depth the decoder
// can provide regardless of the original encoding intent.
assert(format.data_type == JXL_TYPE_FLOAT);
if (JXL_DEC_SUCCESS != if (JXL_DEC_SUCCESS !=
JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) {
@ -940,20 +938,19 @@ int ImageIO::loadJxl(const Glib::ustring &fname)
return IMIO_READERROR; return IMIO_READERROR;
} }
buffer = g_malloc(buffer_size); buffer.resize(buffer_size);
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer, buffer_size)) {
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer.data(), buffer.size())) {
g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n");
g_free(buffer);
return IMIO_READERROR; return IMIO_READERROR;
} }
} else if (status == JXL_DEC_FULL_IMAGE || } else if (status == JXL_DEC_FULL_IMAGE ||
status == JXL_DEC_FRAME) { status == JXL_DEC_FRAME) {
// Nothing to do. If the image is an animation, more full frames // Nothing to do. If the image is an animation, more full frames
// may be decoded. This example only keeps the first one. // may be decoded. This example only keeps the first one.
break;
} else if (status == JXL_DEC_SUCCESS) { } else if (status == JXL_DEC_SUCCESS) {
// All decoding successfully finished. // Decoding complete. Decoder will be released automatically.
// It's not required to call JxlDecoderReleaseInput(dec.get())
// since the decoder will be destroyed.
break; break;
} else if (status == JXL_DEC_NEED_MORE_INPUT) { } else if (status == JXL_DEC_NEED_MORE_INPUT) {
g_printerr("Error: Already provided all input\n"); g_printerr("Error: Already provided all input\n");
@ -967,26 +964,24 @@ int ImageIO::loadJxl(const Glib::ustring &fname)
} }
} // end grand decode loop } // end grand decode loop
unsigned int width = info.xsize; std::size_t width = info.xsize;
unsigned int height = info.ysize; std::size_t height = info.ysize;
allocate(width, height); allocate(width, height);
int line_length = width * 3 * 4; std::size_t line_length = width * 3 * 4;
for (size_t row = 0; row < height; ++row) { for (std::size_t row = 0; row < height; ++row) {
setScanline (row, ((const unsigned char*)buffer) + (row * line_length), 32); setScanline(row, ((const unsigned char*)buffer.data()) + (row * line_length), 32);
if (pl && !(row % 100)) { if (pl && !(row % 100)) {
pl->setProgress ((double)(row) / height); pl->setProgress((double)(row) / height);
} }
} }
g_free(buffer);
if (pl) { if (pl) {
pl->setProgressStr ("PROGRESSBAR_READY"); pl->setProgressStr("PROGRESSBAR_READY");
pl->setProgress (1.0); pl->setProgress(1.0);
} }
return IMIO_SUCCESS; return IMIO_SUCCESS;
@ -1484,7 +1479,7 @@ int ImageIO::load (const Glib::ustring &fname)
return loadJPEG (fname); return loadJPEG (fname);
#ifdef LIBJXL #ifdef LIBJXL
} else if (hasJxlExtension(fname)) { } else if (hasJxlExtension(fname)) {
return loadJxl(fname); return loadJXL(fname);
#endif #endif
} else if (hasTiffExtension(fname)) { } else if (hasTiffExtension(fname)) {
return loadTIFF (fname); return loadTIFF (fname);

View File

@ -91,7 +91,7 @@ public:
int save (const Glib::ustring &fname) const; int save (const Glib::ustring &fname) const;
#ifdef LIBJXL #ifdef LIBJXL
int loadJxl (const Glib::ustring &fname); int loadJXL (const Glib::ustring &fname);
#endif #endif
int loadPNG (const Glib::ustring &fname); int loadPNG (const Glib::ustring &fname);

View File

@ -240,8 +240,7 @@ bool hasJpegExtension(const Glib::ustring& filename)
#ifdef LIBJXL #ifdef LIBJXL
bool hasJxlExtension(const Glib::ustring& filename) bool hasJxlExtension(const Glib::ustring& filename)
{ {
const Glib::ustring extension = getFileExtension(filename); return getFileExtension(filename) == "jxl";
return extension == "jxl";
} }
#endif #endif

View File

@ -182,12 +182,12 @@ Glib::ustring Thumbnail::xmpSidecarPath(const Glib::ustring &imagePath)
return rtengine::Exiv2Metadata::xmpSidecarPath(imagePath); return rtengine::Exiv2Metadata::xmpSidecarPath(imagePath);
} }
void Thumbnail::_generateThumbnailImage () void Thumbnail::_generateThumbnailImage()
{ {
// delete everything loaded into memory // delete everything loaded into memory
delete tpp; delete tpp;
tpp = nullptr; tpp = nullptr;
delete [] lastImg; delete[] lastImg;
lastImg = nullptr; lastImg = nullptr;
tw = options.maxThumbnailWidth; tw = options.maxThumbnailWidth;
th = options.maxThumbnailHeight; th = options.maxThumbnailHeight;
@ -211,21 +211,24 @@ void Thumbnail::_generateThumbnailImage ()
bool quick = false; bool quick = false;
rtengine::eSensorType sensorType = rtengine::ST_NONE; rtengine::eSensorType sensorType = rtengine::ST_NONE;
if ( initial_ && options.internalThumbIfUntouched) {
if (initial_ && options.internalThumbIfUntouched) {
quick = true; quick = true;
tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, tw, th, 1, TRUE); tpp = rtengine::Thumbnail::loadQuickFromRaw(fname, sensorType, tw, th, 1, TRUE);
} }
if ( tpp == nullptr ) { if (!tpp) {
quick = false; quick = false;
tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); tpp = rtengine::Thumbnail::loadFromRaw(fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw));
} }
cfs.sensortype = sensorType; cfs.sensortype = sensorType;
if (tpp) { if (tpp) {
cfs.format = FT_Raw; cfs.format = FT_Raw;
cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL;
infoFromImage (fname); infoFromImage(fname);
if (!quick) { if (!quick) {
cfs.width = tpp->full_width; cfs.width = tpp->full_width;
cfs.height = tpp->full_height; cfs.height = tpp->full_height;
@ -234,7 +237,8 @@ void Thumbnail::_generateThumbnailImage ()
if (!tpp) { if (!tpp) {
// this will load formats supported by imagio (jpg, png, jxl, and tiff) // this will load formats supported by imagio (jpg, png, jxl, and tiff)
tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer);
if (tpp) { if (tpp) {
cfs.format = FT_Custom; cfs.format = FT_Custom;
infoFromImage(fname); infoFromImage(fname);
@ -243,12 +247,12 @@ void Thumbnail::_generateThumbnailImage ()
if (tpp) { if (tpp) {
tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul); tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul);
_saveThumbnail (); _saveThumbnail();
cfs.supported = true; cfs.supported = true;
cfs.save (getCacheFileName ("data", ".txt")); cfs.save(getCacheFileName("data", ".txt"));
generateExifDateTimeStrings (); generateExifDateTimeStrings();
} }
} }
@ -718,10 +722,10 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro
MyMutex::MyLock lock(mutex); MyMutex::MyLock lock(mutex);
if ( tpp == nullptr ) { if (!tpp) {
_loadThumbnail(); _loadThumbnail();
if ( tpp == nullptr ) { if (!tpp) {
return nullptr; return nullptr;
} }
} }
@ -755,7 +759,7 @@ rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::Pro
_generateThumbnailImage(); _generateThumbnailImage();
if ( tpp == nullptr ) { if (!tpp) {
return nullptr; return nullptr;
} }
@ -961,7 +965,7 @@ void Thumbnail::_loadThumbnail(bool firstTrial)
_loadThumbnail (false); _loadThumbnail (false);
} }
if (tpp == nullptr) { if (!tpp) {
return; return;
} }
} else if (!succ) { } else if (!succ) {