Skip to content

Commit

Permalink
Update QOI to its final specification
Browse files Browse the repository at this point in the history
  • Loading branch information
laurelkeys committed Dec 20, 2021
1 parent 4d96098 commit 8db2eca
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 48 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ set(TEV_SOURCES
include/tev/imageio/ImageLoader.h src/imageio/ImageLoader.cpp
include/tev/imageio/ImageSaver.h src/imageio/ImageSaver.cpp
include/tev/imageio/PfmImageLoader.h src/imageio/PfmImageLoader.cpp
include/tev/imageio/QoiImageLoader.h src/imageio/QoiImageLoader.cpp src/imageio/QoiImplementation.c
include/tev/imageio/QoiImageLoader.h src/imageio/QoiImageLoader.cpp
include/tev/imageio/QoiImageSaver.h src/imageio/QoiImageSaver.cpp
include/tev/imageio/StbiHdrImageSaver.h src/imageio/StbiHdrImageSaver.cpp
include/tev/imageio/StbiImageLoader.h src/imageio/StbiImageLoader.cpp
Expand Down
2 changes: 1 addition & 1 deletion dependencies/qoi
Submodule qoi updated 6 files
+5 −1 .gitignore
+28 −10 README.md
+286 −245 qoi.h
+258 −131 qoibench.c
+11 −1 qoiconv.c
+51 −0 qoifuzz.c
54 changes: 20 additions & 34 deletions src/imageio/QoiImageLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <tev/ThreadPool.h>

#define QOI_NO_STDIO
#define QOI_IMPLEMENTATION
#include <qoi.h>

using namespace filesystem;
Expand Down Expand Up @@ -66,42 +67,27 @@ Task<vector<ImageData>> QoiImageLoader::load(istream& iStream, const path&, cons
resultData.channels = makeNChannels(numChannels, size);
resultData.hasPremultipliedAlpha = false;

// QOI uses a bitmap 0000rgba for 'colorspace', where a bit 1 indicates linear,
// however, it is purely informative (meaning it has no effect in en/decoding).
// Thus, we interpret the default 0x0 value to mean: sRGB encoded RGB channels
// with linear encoded alpha channel:
bool isSRGBChannel[4] = {true, true, true, false};
switch (desc.colorspace) {
case 0x0: // case QOI_SRGB:
case QOI_SRGB_LINEAR_ALPHA:
break;
case QOI_LINEAR:
isSRGBChannel[0] = false;
isSRGBChannel[1] = false;
isSRGBChannel[2] = false;
break;
default:
// FIXME: should we handle "per-channel" encoding information or just the two cases above?
// Another option is assuming all values except for QOI_LINEAR mean QOI_SRGB_LINEAR_ALPHA.
// throw invalid_argument{tfm::format("Unsupported QOI colorspace: %X", desc.colorspace)};
isSRGBChannel[0] = (desc.colorspace & 0x8) == 0x0; // R channel => 0000rgba & 1000 = r000
isSRGBChannel[1] = (desc.colorspace & 0x4) == 0x0; // G channel => 0000rgba & 0100 = 0g00
isSRGBChannel[2] = (desc.colorspace & 0x2) == 0x0; // B channel => 0000rgba & 0010 = 00b0
isSRGBChannel[3] = (desc.colorspace & 0x1) == 0x0; // A channel => 0000rgba & 0001 = 000a
break;
}

co_await gThreadPool->parallelForAsync<size_t>(0, numPixels, [&](size_t i) {
auto typedData = reinterpret_cast<unsigned char*>(decodedData);
size_t baseIdx = i * numChannels;
for (int c = 0; c < numChannels; ++c) {
if (isSRGBChannel[c]) {
resultData.channels[c].at(i) = toLinear((typedData[baseIdx + c]) / 255.0f);
} else {
if (desc.colorspace == QOI_LINEAR) {
co_await gThreadPool->parallelForAsync<size_t>(0, numPixels, [&](size_t i) {
auto typedData = reinterpret_cast<unsigned char*>(decodedData);
size_t baseIdx = i * numChannels;
for (int c = 0; c < numChannels; ++c) {
resultData.channels[c].at(i) = (typedData[baseIdx + c]) / 255.0f;
}
}
}, priority);
}, priority);
} else {
co_await gThreadPool->parallelForAsync<size_t>(0, numPixels, [&](size_t i) {
auto typedData = reinterpret_cast<unsigned char*>(decodedData);
size_t baseIdx = i * numChannels;
for (int c = 0; c < numChannels; ++c) {
if (c == 3) {
resultData.channels[c].at(i) = (typedData[baseIdx + c]) / 255.0f;
} else {
resultData.channels[c].at(i) = toLinear((typedData[baseIdx + c]) / 255.0f);
}
}
}, priority);
}

co_return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/imageio/QoiImageSaver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void QoiImageSaver::save(ostream& oStream, const path&, const vector<char>& data
.width = static_cast<unsigned int>(imageSize.x()),
.height = static_cast<unsigned int>(imageSize.y()),
.channels = static_cast<unsigned char>(nChannels),
.colorspace = QOI_SRGB_LINEAR_ALPHA,
.colorspace = QOI_SRGB,
};
int sizeInBytes = 0;
void *encodedData = qoi_encode(data.data(), &desc, &sizeInBytes);
Expand Down
11 changes: 0 additions & 11 deletions src/imageio/QoiImplementation.c

This file was deleted.

0 comments on commit 8db2eca

Please sign in to comment.