Skip to content

Commit f833b24

Browse files
committed
Gamut decoding update, remove coil, remove vulkan
1 parent 34c4e43 commit f833b24

File tree

21 files changed

+2892
-1257
lines changed

21 files changed

+2892
-1257
lines changed

app/src/main/java/com/radzivon/bartoshyk/avif/MainActivity.kt

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ import android.os.Bundle
3232
import android.util.Log
3333
import android.util.Size
3434
import androidx.appcompat.app.AppCompatActivity
35+
import androidx.lifecycle.lifecycleScope
3536
import com.radzivon.bartoshyk.avif.coder.HeifCoder
3637
import com.radzivon.bartoshyk.avif.coder.PreferredColorConfig
3738
import com.radzivon.bartoshyk.avif.coder.ScaleMode
3839
import com.radzivon.bartoshyk.avif.coder.ToneMapper
3940
import com.radzivon.bartoshyk.avif.databinding.ActivityMainBinding
4041
import com.radzivon.bartoshyk.avif.databinding.BindingImageViewBinding
42+
import kotlinx.coroutines.Dispatchers
43+
import kotlinx.coroutines.launch
4144
import okio.FileNotFoundException
4245
import okio.buffer
4346
import okio.sink
@@ -88,34 +91,39 @@ class MainActivity : AppCompatActivity() {
8891
*/
8992

9093
// HDR EXAMPLES - https://us.zonerama.com/williamskeaguidingphotography/Photo/1000120226/1004888131
91-
val coder = HeifCoder(this, toneMapper = ToneMapper.LOGARITHMIC)
92-
val allFiles1 = getAllFilesFromAssets().filter { it.contains(".avif") || it.contains(".heic") }
93-
val allFiles2 = getAllFilesFromAssets(path = "hdr").filter { it.contains(".avif") || it.contains(".heic") }
94-
val allFiles = mutableListOf<String>()
95-
allFiles.addAll(allFiles2)
96-
allFiles.addAll(allFiles1)
97-
for (file in allFiles) {
98-
try {
99-
val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
100-
val buffer = this.assets.open(file).source().buffer()
101-
.readByteArray()
102-
val size = coder.getSize(buffer)
103-
if (size != null) {
104-
val bitmap = coder.decodeSampled(
105-
buffer,
106-
if (size.width > 1800 || size.height > 1800) size.width / 2 else size.width,
107-
if (size.width > 1800 || size.height > 1800) size.height / 2 else size.height,
108-
PreferredColorConfig.HARDWARE,
109-
ScaleMode.RESIZE
110-
)
111-
imageView.root.setImageBitmap(bitmap)
112-
binding.scrollViewContainer.addView(imageView.root)
113-
}
114-
} catch (e: Exception) {
115-
if (e is FileNotFoundException || e is java.io.FileNotFoundException) {
94+
lifecycleScope.launch(Dispatchers.IO) {
95+
val coder = HeifCoder(this@MainActivity, toneMapper = ToneMapper.LOGARITHMIC)
96+
val allFiles1 = getAllFilesFromAssets().filter { it.contains(".avif") || it.contains(".heic") }
97+
val allFiles2 = getAllFilesFromAssets(path = "hdr").filter { it.contains(".avif") || it.contains(".heic") }
98+
var allFiles = mutableListOf<String>()
99+
allFiles.addAll(allFiles2)
100+
allFiles.addAll(allFiles1)
101+
// allFiles = allFiles.filter { it.contains("test_avif.avif") }.toMutableList()
102+
for (file in allFiles) {
103+
try {
104+
val buffer = this@MainActivity.assets.open(file).source().buffer()
105+
.readByteArray()
106+
val size = coder.getSize(buffer)
107+
if (size != null) {
108+
val bitmap = coder.decodeSampled(
109+
buffer,
110+
if (size.width > 1800 || size.height > 1800) size.width / 2 else size.width,
111+
if (size.width > 1800 || size.height > 1800) size.height / 2 else size.height,
112+
PreferredColorConfig.HARDWARE,
113+
ScaleMode.RESIZE
114+
)
115+
lifecycleScope.launch(Dispatchers.Main) {
116+
val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
117+
imageView.root.setImageBitmap(bitmap)
118+
binding.scrollViewContainer.addView(imageView.root)
119+
}
120+
}
121+
} catch (e: Exception) {
122+
if (e is FileNotFoundException || e is java.io.FileNotFoundException) {
116123

117-
} else {
118-
throw e
124+
} else {
125+
throw e
126+
}
119127
}
120128
}
121129
}

avif-coder/src/main/cpp/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ add_library(coder SHARED coder.cpp JniException.cpp SizeScaler.cpp
1919
colorspace/HDRTransferAdapter.cpp
2020
imagebits/CopyUnalignedRGBA.cpp JniDecoder.cpp imagebits/Rgba8ToF16.cpp
2121
imagebits/Rgb565.cpp JniBitmap.cpp ReformatBitmap.cpp Support.cpp IccRecognizer.cpp
22-
HardwareBuffersCompat.cpp VulkanRunner.cpp imagebits/half.cpp
22+
HardwareBuffersCompat.cpp imagebits/half.cpp
2323
imagebits/half.hpp imagebits/RgbaU16toHF.cpp
24-
imagebits/RGBAlpha.cpp colorspace/CoderCms.cpp
24+
imagebits/RGBAlpha.cpp
2525
hwy/aligned_allocator.cc hwy/nanobenchmark.cc hwy/per_target.cc hwy/print.cc hwy/targets.cc
26-
hwy/timer.cc)
26+
hwy/timer.cc
27+
algo/sleef-hwy.cpp)
2728

2829
add_library(libaom STATIC IMPORTED)
2930
add_library(libx265 STATIC IMPORTED)

avif-coder/src/main/cpp/JniDecoder.cpp

Lines changed: 82 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
#include "ReformatBitmap.h"
2828
#include "IccRecognizer.h"
2929
#include "thread"
30-
#include "VulkanRunner.h"
3130
#include <android/asset_manager_jni.h>
3231
#include "imagebits/RGBAlpha.h"
3332
#include "imagebits/RgbaU16toHF.h"
33+
#include "Eigen/Eigen"
3434

3535
using namespace std;
3636

@@ -174,162 +174,92 @@ jobject decodeImplementationNative(JNIEnv *env, jobject thiz,
174174
convertUseICC(dstARGB, stride, imageWidth, imageHeight, profile.data(),
175175
profile.size(),
176176
useBitmapHalf16Floats, &stride);
177-
} else if ((colorProfile == "BT2020_PQ" || colorProfile == "DISPLAY_P3_PQ" ||
178-
colorProfile == "BT2020_HLG" || colorProfile == "DISPLAY_P3_HLG" ||
179-
colorProfile.find("SMPTE_428") != std::string::npos) && hasNCLX && (nclx)) {
180-
bool isVulkanLoaded = loadVulkanRunner();
181-
bool vulkanWorkerDone = false;
182-
if (assetManager != nullptr && isVulkanLoaded) {
183-
std::string kernel = "SMPTE2084.comp.spv";
184-
185-
if (colorProfile.find("HLG") != std::string::npos) {
186-
kernel = "HLG.comp.spv";
187-
} else if (colorProfile.find("SMPTE_428") != std::string::npos) {
188-
kernel = "SMPTE428.comp.spv";
189-
}
190-
191-
float primaries[3][2] = {{static_cast<float>(nclx->color_primary_red_x),
192-
static_cast<float>(nclx->color_primary_red_y)},
193-
{static_cast<float>(nclx->color_primary_green_x),
194-
static_cast<float>(nclx->color_primary_green_y)},
195-
{static_cast<float>(nclx->color_primary_blue_x),
196-
static_cast<float>(nclx->color_primary_blue_y)}};
197-
float whitePoint[2] = {static_cast<float>(nclx->color_primary_white_x),
198-
static_cast<float>(nclx->color_primary_white_y)};
199-
200-
float lumaPrimaries[3];
201-
202-
if (colorProfile.find("BT2020") != std::string::npos) {
203-
memcpy(lumaPrimaries, Rec2020LumaPrimaries, sizeof(float) * 3);
204-
} else {
205-
memcpy(lumaPrimaries, DisplayP3LumaPrimaries, sizeof(float) * 3);
206-
}
207-
208-
ColorSpaceProfile srcProfile(primaries, whitePoint, Rec2020LumaPrimaries,
209-
Rec2020WhitePointNits);
210-
CmsMatrix dstMatrix = CmsMatrix(rec709Profile->primaries, rec709Profile->illuminant);
211-
CmsMatrix srcMatrix = CmsMatrix(srcProfile.primaries, srcProfile.illuminant);
212-
CmsMatrix trns = dstMatrix.inverted() * srcMatrix;
213-
214-
ShaderEotfData shaderData = {
215-
.toneMapper = toneMapper,
216-
.oetfCurve = 1,
217-
};
218-
219-
memcpy(shaderData.lumaPrimaries, lumaPrimaries, sizeof(float) * 3);
220-
221-
if (colorProfile == "DISPLAY_P3_PQ" || colorProfile == "DISPLAY_P3_HLG" ||
222-
colorProfile.find("BT2020") != std::string::npos) {
223-
shaderData.oetfCurve = 2;
224-
}
225-
226-
for (int i = 0; i < 3; ++i) {
227-
for (int j = 0; j < 3; ++j) {
228-
shaderData.colorMatrix[i][j] = trns.getMatrix()[i * 3 + j];
229-
}
230-
}
231-
232-
vulkanWorkerDone = VulkanRunnerWithData(kernel, assetManager,
233-
reinterpret_cast<uint8_t *>(dstARGB.data()),
234-
imageWidth,
235-
imageHeight, stride,
236-
useBitmapHalf16Floats ? RgbaF16 : RgbaU8,
237-
reinterpret_cast<void *>(&shaderData),
238-
sizeof(ShaderEotfData));
239-
}
240-
if (!vulkanWorkerDone) {
241-
ColorSpaceProfile srcProfile(Rec2020Primaries, IlluminantD65,
242-
Rec2020LumaPrimaries,
243-
Rec2020WhitePointNits);
244-
GammaCurve gammaCurve = Rec2020;
245-
HDRTransferFunction function = PQ;
246-
if (colorProfile == "DISPLAY_P3_PQ" || colorProfile == "DISPLAY_P3_HLG") {
247-
gammaCurve = DCIP3;
248-
}
249-
250-
if (colorProfile.find("HLG") != std::string::npos) {
251-
function = HLG;
252-
} else if (colorProfile.find("SMPTE_428") != std::string::npos) {
253-
function = SMPTE428;
254-
gammaCurve = DCIP3;
255-
}
256-
HDRTransferAdapter hdrTransferAdapter(
257-
reinterpret_cast<uint8_t *>(dstARGB.data()),
258-
stride, imageWidth, imageHeight, useBitmapHalf16Floats,
259-
useBitmapHalf16Floats ? 16 : 8, gammaCurve, function, toneMapper, &srcProfile,
260-
rec709Profile, 2.2f);
261-
hdrTransferAdapter.transfer();
262-
}
263-
} else if (colorProfile == "BT2020" || colorProfile == "BT709" ||
264-
colorProfile == "DISPLAY_P3") {
265-
bool isVulkanLoaded = loadVulkanRunner();
266-
bool vulkanWorkerDone = false;
267-
268-
ColorSpaceProfile *srcProfile = rec2020Profile;
269-
if (colorProfile == "BT709") {
270-
srcProfile = rec709Profile;
177+
} else if (hasNCLX && nclx &&
178+
nclx->transfer_characteristics != heif_transfer_characteristic_unspecified &&
179+
nclx->color_primaries != heif_color_primaries_unspecified) {
180+
Eigen::Matrix<float, 3, 2> primaries;
181+
if (nclx->color_primaries != heif_color_primaries_unspecified) {
182+
primaries << static_cast<float>(nclx->color_primary_red_x),
183+
static_cast<float>(nclx->color_primary_red_y),
184+
static_cast<float>(nclx->color_primary_green_x),
185+
static_cast<float>(nclx->color_primary_green_y),
186+
static_cast<float>(nclx->color_primary_blue_x),
187+
static_cast<float>(nclx->color_primary_blue_y);
188+
} else {
189+
primaries = getSRGBPrimaries();
271190
}
272-
CmsMatrix dstMatrix = CmsMatrix(rec709Profile->primaries, rec709Profile->illuminant);
273-
CmsMatrix srcMatrix = CmsMatrix(srcProfile->primaries, srcProfile->illuminant);
274-
CmsMatrix trns = dstMatrix.inverted() * srcMatrix;
275-
276-
float lumaPrimaries[3];
277-
278-
if (colorProfile.find("BT2020") != std::string::npos) {
279-
memcpy(lumaPrimaries, Rec2020LumaPrimaries, sizeof(float) * 3);
280-
} else if (colorProfile.find("BT709") != std::string::npos) {
281-
memcpy(lumaPrimaries, Rec709LumaPrimaries, sizeof(float) * 3);
191+
Eigen::Vector2f whitePoint;
192+
if (nclx->color_primaries != heif_color_primaries_unspecified) {
193+
whitePoint << static_cast<float>(nclx->color_primary_white_x),
194+
static_cast<float>(nclx->color_primary_white_y);
282195
} else {
283-
memcpy(lumaPrimaries, DisplayP3LumaPrimaries, sizeof(float) * 3);
196+
whitePoint = getIlluminantD65();
284197
}
285198

286-
if (isVulkanLoaded) {
287-
ShaderGammaData shaderData = {
288-
.oetfCurve = 3,
289-
.gamma = 2.4,
290-
};
291-
292-
if (colorProfile.find("P3") != std::string::npos) {
293-
shaderData.gamma = 2.6f;
294-
} else if (colorProfile.find("709") != std::string::npos) {
295-
shaderData.gamma = 2.0f;
296-
}
297-
298-
memcpy(shaderData.lumaPrimaries, lumaPrimaries, sizeof(float) * 3);
299-
300-
for (int i = 0; i < 3; ++i) {
301-
for (int j = 0; j < 3; ++j) {
302-
shaderData.colorMatrix[i][j] = trns.getMatrix()[i * 3 + j];
303-
}
304-
}
305-
string kernel = "GammaOetf.comp.spv";
306-
vulkanWorkerDone = VulkanRunnerWithData(kernel, assetManager,
307-
reinterpret_cast<uint8_t *>(dstARGB.data()),
308-
imageWidth,
309-
imageHeight, stride,
310-
useBitmapHalf16Floats ? RgbaF16 : RgbaU8,
311-
reinterpret_cast<void *>(&shaderData),
312-
sizeof(ShaderGammaData));
313-
}
314-
if (!vulkanWorkerDone) {
315-
HDRTransferFunction function = GAMMA_TRANSFER;
316-
float gamma = 2.4f;
317-
if (colorProfile.find("P3") != std::string::npos) {
318-
gamma = 2.6f;
319-
} else if (colorProfile.find("709") != std::string::npos) {
320-
gamma = 2.0f;
321-
}
322-
323-
HDRTransferAdapter hdrTransferAdapter(
324-
reinterpret_cast<uint8_t *>(dstARGB.data()),
325-
stride, imageWidth, imageHeight, useBitmapHalf16Floats,
326-
useBitmapHalf16Floats ? 16 : 8, sRGB, function, toneMapper, srcProfile,
327-
rec709Profile, gamma);
328-
hdrTransferAdapter.transfer();
199+
Eigen::Matrix3f srgbXyz = GamutRgbToXYZ(getSRGBPrimaries(), getIlluminantD65());
200+
Eigen::Matrix3f srcXyz = GamutRgbToXYZ(primaries, whitePoint);
201+
202+
Eigen::Matrix3f conversion = srgbXyz.inverse() * srgbXyz;
203+
204+
GammaCurve gammaCurve = sRGB;
205+
GamutTransferFunction function = SKIP;
206+
207+
const float gamma = 1.0f;
208+
209+
if (nclx->transfer_characteristics ==
210+
heif_transfer_characteristic_ITU_R_BT_2100_0_HLG) {
211+
function = HLG;
212+
} else if (nclx->transfer_characteristics ==
213+
heif_transfer_characteristic_SMPTE_ST_428_1) {
214+
function = SMPTE428;
215+
} else if (nclx->transfer_characteristics ==
216+
heif_transfer_characteristic_ITU_R_BT_2100_0_PQ) {
217+
function = PQ;
218+
} else if (nclx->transfer_characteristics == heif_transfer_characteristic_linear) {
219+
function = SKIP;
220+
} else if (nclx->transfer_characteristics ==
221+
heif_transfer_characteristic_ITU_R_BT_470_6_System_M) {
222+
function = Gamma2p2;
223+
} else if (nclx->transfer_characteristics ==
224+
heif_transfer_characteristic_ITU_R_BT_470_6_System_B_G) {
225+
function = Gamma2p8;
226+
} else if (nclx->transfer_characteristics ==
227+
heif_transfer_characteristic_ITU_R_BT_601_6) {
228+
function = EOTF_BT601;
229+
} else if (
230+
nclx->transfer_characteristics == heif_transfer_characteristic_ITU_R_BT_709_5 ||
231+
nclx->transfer_characteristics ==
232+
heif_transfer_characteristic_ITU_R_BT_2020_2_10bit ||
233+
nclx->transfer_characteristics ==
234+
heif_transfer_characteristic_ITU_R_BT_2020_2_12bit) {
235+
function = EOTF_BT709;
236+
} else if (nclx->transfer_characteristics == heif_transfer_characteristic_SMPTE_240M) {
237+
function = EOTF_SMPTE240;
238+
} else if (nclx->transfer_characteristics ==
239+
heif_transfer_characteristic_logarithmic_100) {
240+
function = EOTF_LOG100;
241+
} else if (nclx->transfer_characteristics ==
242+
heif_transfer_characteristic_logarithmic_100_sqrt10) {
243+
function = EOTF_LOG100SRT10;
244+
} else if (
245+
nclx->transfer_characteristics == heif_transfer_characteristic_IEC_61966_2_1 ||
246+
nclx->transfer_characteristics == heif_transfer_characteristic_IEC_61966_2_4) {
247+
function = EOTF_IEC_61966;
248+
} else if (nclx->transfer_characteristics ==
249+
heif_transfer_characteristic_ITU_R_BT_1361) {
250+
function = EOTF_BT1361;
251+
} else if (nclx->transfer_characteristics == heif_transfer_characteristic_unspecified) {
252+
function = EOTF_BT709;
329253
}
330-
} else if (colorProfile == "LINEAR_SRGB") {
331-
convertUseICC(dstARGB, stride, imageWidth, imageHeight, &linearSRGB[0],
332-
sizeof(linearSRGB), useBitmapHalf16Floats, &stride);
254+
HDRTransferAdapter hdrTransferAdapter(
255+
reinterpret_cast<uint8_t *>(dstARGB.data()),
256+
stride, imageWidth, imageHeight, useBitmapHalf16Floats,
257+
useBitmapHalf16Floats ? 16 : 8, gammaCurve, function,
258+
toneMapper,
259+
&conversion,
260+
gamma,
261+
getIlluminantD65() != whitePoint);
262+
hdrTransferAdapter.transfer();
333263
}
334264

335265
string imageConfig = useBitmapHalf16Floats ? "RGBA_F16" : "ARGB_8888";

0 commit comments

Comments
 (0)