mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-06-03 17:08:08 -04:00
RAW: Allow preview loading
This patch addresses reports of performance issues on large raw collections. Programs that generate previews must use the plugin correctly. **Setting quality to 0 may return a different image than in the past** (Nothing changes for all other quality values): the plugin loads the embedded thumbnail and, in case of error, decodes the image with quality 1. When compiled with libRAW 0.21+, the plugin automatically select the largest preview from the ones in the file.
This commit is contained in:
parent
c97ee00f5e
commit
1982557a55
@ -581,6 +581,66 @@ void setParams(QImageIOHandler *handler, LibRaw *rawProcessor)
|
|||||||
params.use_fuji_rotate = T_SR(quality) ? 0 : 1;
|
params.use_fuji_rotate = T_SR(quality) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadTHUMB(QImageIOHandler *handler, QImage &img)
|
||||||
|
{
|
||||||
|
std::unique_ptr<LibRaw> rawProcessor(new LibRaw);
|
||||||
|
|
||||||
|
// *** Open the stream
|
||||||
|
auto device = handler->device();
|
||||||
|
#ifndef EXCLUDE_LibRaw_QIODevice
|
||||||
|
LibRaw_QIODevice stream(device);
|
||||||
|
if (rawProcessor->open_datastream(&stream) != LIBRAW_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
auto ba = device->readAll();
|
||||||
|
if (rawProcessor->open_buffer(ba.data(), ba.size()) != LIBRAW_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LIBRAW_VERSION < LIBRAW_MAKE_VERSION(0, 21, 0))
|
||||||
|
// *** Unpacking selected thumbnail
|
||||||
|
if (rawProcessor->unpack_thumb() != LIBRAW_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// *** Search for the bigger thumbnail
|
||||||
|
auto &&tlist = rawProcessor->imgdata.thumbs_list;
|
||||||
|
auto idx = 0;
|
||||||
|
for (auto n = 1; n < std::min(tlist.thumbcount, LIBRAW_THUMBNAIL_MAXCOUNT); ++n) {
|
||||||
|
if (tlist.thumblist[n].twidth > tlist.thumblist[idx].twidth)
|
||||||
|
idx = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** Unpacking selected thumbnail
|
||||||
|
if (rawProcessor->unpack_thumb_ex(idx) != LIBRAW_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// *** Convert to QImage
|
||||||
|
pi_unique_ptr processedImage(rawProcessor->dcraw_make_mem_thumb(), LibRaw::dcraw_clear_mem);
|
||||||
|
if (processedImage == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto ba = QByteArray(reinterpret_cast<const char *>(processedImage->data), qsizetype(processedImage->data_size));
|
||||||
|
if (ba.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (processedImage->type == LIBRAW_IMAGE_BITMAP) {
|
||||||
|
// clang-format off
|
||||||
|
auto header = QString::fromUtf8("P%1\n%2 %3\n%4\n") // taken from KDcraw
|
||||||
|
.arg(processedImage->colors == 3 ? QLatin1String("6") : QLatin1String("5"))
|
||||||
|
.arg(processedImage->width)
|
||||||
|
.arg(processedImage->height)
|
||||||
|
.arg((1 << processedImage->bits)-1);
|
||||||
|
// clang-format on
|
||||||
|
ba.prepend(header.toLatin1());
|
||||||
|
}
|
||||||
|
return img.loadFromData(ba);
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadRAW(QImageIOHandler *handler, QImage &img)
|
bool LoadRAW(QImageIOHandler *handler, QImage &img)
|
||||||
{
|
{
|
||||||
std::unique_ptr<LibRaw> rawProcessor(new LibRaw);
|
std::unique_ptr<LibRaw> rawProcessor(new LibRaw);
|
||||||
@ -679,6 +739,11 @@ bool LoadRAW(QImageIOHandler *handler, QImage &img)
|
|||||||
if (params.output_color == 7) {
|
if (params.output_color == 7) {
|
||||||
img.setColorSpace(QColorSpace(QColorSpace::DisplayP3));
|
img.setColorSpace(QColorSpace(QColorSpace::DisplayP3));
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
if (params.output_color == 8) {
|
||||||
|
img.setColorSpace(QColorSpace(QColorSpace::Bt2020));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// *** Set the metadata
|
// *** Set the metadata
|
||||||
@ -756,7 +821,16 @@ bool RAWHandler::read(QImage *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QImage img;
|
QImage img;
|
||||||
if (!LoadRAW(this, img)) {
|
auto ok = false;
|
||||||
|
if (m_quality == 0) {
|
||||||
|
ok = LoadTHUMB(this, img);
|
||||||
|
if (!ok && !dev->isSequential())
|
||||||
|
dev->seek(m_startPos);
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
|
ok = LoadRAW(this, img);
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,8 @@ private:
|
|||||||
* @note It is safe to set both W and A: W is used if camera white balance is found, otherwise A is used.
|
* @note It is safe to set both W and A: W is used if camera white balance is found, otherwise A is used.
|
||||||
*
|
*
|
||||||
* When quality is a positive value, a value between 0 and 100 is expected. The values are interpreted as follows:
|
* When quality is a positive value, a value between 0 and 100 is expected. The values are interpreted as follows:
|
||||||
* - 00-09: I = 0, C = 1, B = 0, W = 1, A = 1, H = 1 (Linear, sRGB, 8-bits, Camera White, Auto White, Half-size)
|
* - 00 : Embedded preview, if fails same as Half-Size (01-09)
|
||||||
|
* - 01-09: I = 0, C = 1, B = 0, W = 1, A = 1, H = 1 (Linear, sRGB, 8-bits, Camera White, Auto White, Half-size)
|
||||||
* - 10-19: I = 0, C = 1, B = 0, W = 1, A = 1, H = 0 (Linear, sRGB, 8-bits, Camera White, Auto White)
|
* - 10-19: I = 0, C = 1, B = 0, W = 1, A = 1, H = 0 (Linear, sRGB, 8-bits, Camera White, Auto White)
|
||||||
* - 20-29: I = 3, C = 1, B = 0, W = 1, A = 1, H = 0 (AHD, sRGB, 8-bits, Camera White, Auto White)
|
* - 20-29: I = 3, C = 1, B = 0, W = 1, A = 1, H = 0 (AHD, sRGB, 8-bits, Camera White, Auto White)
|
||||||
* - 30-39: I = 3, C = 1, B = 1, W = 1, A = 1, H = 0 (AHD, sRGB, 16-bits, Camera White, Auto White) [Default]
|
* - 30-39: I = 3, C = 1, B = 1, W = 1, A = 1, H = 0 (AHD, sRGB, 16-bits, Camera White, Auto White) [Default]
|
||||||
@ -72,11 +73,12 @@ private:
|
|||||||
* - >= 90: I = 11, C = 4, B = 1, W = 1, A = 1, H = 0 (DHT, ProPhoto, 16-bits, Camera White, Auto White)
|
* - >= 90: I = 11, C = 4, B = 1, W = 1, A = 1, H = 0 (DHT, ProPhoto, 16-bits, Camera White, Auto White)
|
||||||
*
|
*
|
||||||
* When the quality is -1, default quality is used.
|
* When the quality is -1, default quality is used.
|
||||||
|
* @sa m_subType
|
||||||
*/
|
*/
|
||||||
qint32 m_quality;
|
qint32 m_quality;
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
* \brief m_startPos
|
* @brief m_startPos
|
||||||
* The initial device position to allow multi image load (cache value).
|
* The initial device position to allow multi image load (cache value).
|
||||||
*/
|
*/
|
||||||
qint64 m_startPos;
|
qint64 m_startPos;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user