Skip to content

Commit

Permalink
Reworked color profiles, decoding and embedding
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Mar 8, 2024
1 parent 965e74f commit 9d86b72
Show file tree
Hide file tree
Showing 45 changed files with 5,146 additions and 5,171 deletions.
83 changes: 33 additions & 50 deletions app/src/main/java/com/radzivon/bartoshyk/avif/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,58 +93,41 @@ class MainActivity : AppCompatActivity() {

// HDR EXAMPLES - https://us.zonerama.com/williamskeaguidingphotography/Photo/1000120226/1004888131
lifecycleScope.launch(Dispatchers.IO) {
val buffer = this@MainActivity.assets.open("test_2.jpg").source().buffer().readByteArray()
var bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.size)
val coder = HeifCoder()
val allFiles1 = getAllFilesFromAssets().filter { it.contains(".avif") || it.contains(".heic") }
val allFiles2 = getAllFilesFromAssets(path = "hdr").filter { it.contains(".avif") || it.contains(".heic") }
var allFiles = mutableListOf<String>()
allFiles.addAll(allFiles2)
allFiles.addAll(allFiles1)
for (file in allFiles) {
try {
Log.d("AVIF", "start processing $file")
val buffer = this@MainActivity.assets.open(file).source().buffer()
.readByteArray()
val size = coder.getSize(buffer)
if (size != null) {
val bitmap = coder.decodeSampled(
buffer,
if (size.width > 1800 || size.height > 1800) size.width / 2 else size.width,
if (size.width > 1800 || size.height > 1800) size.height / 2 else size.height,
PreferredColorConfig.RGBA_8888,
ScaleMode.RESIZE
)
coder.encodeAvif(bitmap)
lifecycleScope.launch(Dispatchers.Main) {
val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
imageView.root.setImageBitmap(bitmap)
binding.scrollViewContainer.addView(imageView.root)
}
}
} catch (e: Exception) {
if (e is FileNotFoundException || e is java.io.FileNotFoundException) {

bitmap = bitmap.scale(bitmap.width / 2, bitmap.height / 2)
.copy(Bitmap.Config.RGBA_1010102, true)
lifecycleScope.launch(Dispatchers.Main) {
val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
imageView.root.setImageBitmap(bitmap)
binding.scrollViewContainer.addView(imageView.root)
}
val coder = HeifCoder(null, toneMapper = ToneMapper.LOGARITHMIC)
val avif = coder.encodeAvif(bitmap)
val decodedAvif = coder.decode(avif)
lifecycleScope.launch(Dispatchers.Main) {
val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
imageView.root.setImageBitmap(decodedAvif)
binding.scrollViewContainer.addView(imageView.root)
} else {
throw e
}
}
}
// val allFiles1 = getAllFilesFromAssets().filter { it.contains(".avif") || it.contains(".heic") }
// val allFiles2 = getAllFilesFromAssets(path = "hdr").filter { it.contains(".avif") || it.contains(".heic") }
// var allFiles = mutableListOf<String>()
// allFiles.addAll(allFiles2)
// allFiles.addAll(allFiles1)
// for (file in allFiles) {
// try {
// Log.d("AVIF", "start processing $file")
// val buffer = this@MainActivity.assets.open(file).source().buffer()
// .readByteArray()
// val size = coder.getSize(buffer)
// if (size != null) {
// val bitmap = coder.decodeSampled(
// buffer,
// if (size.width > 1800 || size.height > 1800) size.width / 2 else size.width,
// if (size.width > 1800 || size.height > 1800) size.height / 2 else size.height,
// PreferredColorConfig.RGBA_8888,
// ScaleMode.RESIZE
// )
// coder.encodeAvif(bitmap)
// lifecycleScope.launch(Dispatchers.Main) {
// val imageView = BindingImageViewBinding.inflate(layoutInflater, binding.scrollViewContainer, false)
// imageView.root.setImageBitmap(bitmap)
// binding.scrollViewContainer.addView(imageView.root)
// }
// }
// } catch (e: Exception) {
// if (e is FileNotFoundException || e is java.io.FileNotFoundException) {
//
// } else {
// throw e
// }
// }
// }
}

// https://wh.aimuse.online/creatives/IMUSE_03617fe2db82a584166_27/TT_a9d21ff1061d785347935fef/68f06252.avif
Expand Down
2 changes: 1 addition & 1 deletion avif-coder/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ add_library(coder SHARED coder.cpp JniException.cpp SizeScaler.cpp
icc/cmsps2.c icc/cmssamp.c icc/cmssm.c icc/cmstypes.c icc/cmsvirt.c
icc/cmswtpnt.c icc/cmsxform.c colorspace/colorspace.cpp
imagebits/RgbaF16bitToNBitU16.cpp imagebits/RgbaF16bitNBitU8.cpp imagebits/Rgb1010102.cpp
colorspace/HDRTransferAdapter.cpp
colorspace/GamutAdapter.cpp
imagebits/CopyUnalignedRGBA.cpp JniDecoder.cpp imagebits/Rgba8ToF16.cpp
imagebits/Rgb565.cpp JniBitmap.cpp ReformatBitmap.cpp Support.cpp IccRecognizer.cpp
HardwareBuffersCompat.cpp imagebits/half.cpp
Expand Down
110 changes: 55 additions & 55 deletions avif-coder/src/main/cpp/HardwareBuffersCompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,67 +46,67 @@ AHardwareBufferToHardwareBufferFunc AHardwareBuffer_toHardwareBuffer_compat = nu
AHardwareBufferDescribeFunc AHardwareBuffer_describe_compat = nullptr;

bool loadAHardwareBuffersAPI() {
// Bitmap doesn't support wrapping before 29 API
if (androidOSVersion() < 29) {
return false;
}
std::lock_guard guard(dlMutex);
if (alreadyHdBuffersLoaded) {
return AHardwareBuffer_allocate_compat != nullptr
&& AHardwareBuffer_isSupported_compat != nullptr
&& AHardwareBuffer_unlock_compat != nullptr
&& AHardwareBuffer_release_compat != nullptr
&& AHardwareBuffer_lock_compat != nullptr
&& AHardwareBuffer_toHardwareBuffer_compat != nullptr
&& AHardwareBuffer_describe_compat != nullptr;
}
alreadyHdBuffersLoaded = true;
void *hhl = dlopen("libandroid.so", RTLD_NOW);
if (!hhl) {
return false;
}
// Bitmap doesn't support wrapping before 29 API
if (androidOSVersion() < 29) {
return false;
}
std::lock_guard guard(dlMutex);
if (alreadyHdBuffersLoaded) {
return AHardwareBuffer_allocate_compat != nullptr
&& AHardwareBuffer_isSupported_compat != nullptr
&& AHardwareBuffer_unlock_compat != nullptr
&& AHardwareBuffer_release_compat != nullptr
&& AHardwareBuffer_lock_compat != nullptr
&& AHardwareBuffer_toHardwareBuffer_compat != nullptr
&& AHardwareBuffer_describe_compat != nullptr;
}
alreadyHdBuffersLoaded = true;
void *hhl = dlopen("libandroid.so", RTLD_NOW);
if (!hhl) {
return false;
}

AHardwareBuffer_allocate_compat = (AHardwareBufferAllocateFunc) dlsym(hhl,
"AHardwareBuffer_allocate");
if (AHardwareBuffer_allocate_compat == nullptr) {
return false;
}
AHardwareBuffer_allocate_compat = (AHardwareBufferAllocateFunc) dlsym(hhl,
"AHardwareBuffer_allocate");
if (AHardwareBuffer_allocate_compat == nullptr) {
return false;
}

AHardwareBuffer_isSupported_compat = (AHardwareBufferIsSupportedFunc) dlsym(hhl,
"AHardwareBuffer_isSupported");
if (AHardwareBuffer_isSupported_compat == nullptr) {
return false;
}
AHardwareBuffer_isSupported_compat = (AHardwareBufferIsSupportedFunc) dlsym(hhl,
"AHardwareBuffer_isSupported");
if (AHardwareBuffer_isSupported_compat == nullptr) {
return false;
}

AHardwareBuffer_unlock_compat = (AHardwareBufferUnlockFunc) dlsym(hhl,
"AHardwareBuffer_unlock");
if (AHardwareBuffer_unlock_compat == nullptr) {
return false;
}
AHardwareBuffer_unlock_compat = (AHardwareBufferUnlockFunc) dlsym(hhl,
"AHardwareBuffer_unlock");
if (AHardwareBuffer_unlock_compat == nullptr) {
return false;
}

AHardwareBuffer_release_compat = (AHardwareBufferReleaseFunc) dlsym(hhl,
"AHardwareBuffer_release");
if (AHardwareBuffer_release_compat == nullptr) {
return false;
}
AHardwareBuffer_release_compat = (AHardwareBufferReleaseFunc) dlsym(hhl,
"AHardwareBuffer_release");
if (AHardwareBuffer_release_compat == nullptr) {
return false;
}

AHardwareBuffer_lock_compat = (AHardwareBufferLockFunc) dlsym(hhl,
"AHardwareBuffer_lock");
if (AHardwareBuffer_lock_compat == nullptr) {
return false;
}
AHardwareBuffer_lock_compat = (AHardwareBufferLockFunc) dlsym(hhl,
"AHardwareBuffer_lock");
if (AHardwareBuffer_lock_compat == nullptr) {
return false;
}

AHardwareBuffer_toHardwareBuffer_compat = (AHardwareBufferToHardwareBufferFunc) dlsym(hhl,
"AHardwareBuffer_toHardwareBuffer");
if (AHardwareBuffer_toHardwareBuffer_compat == nullptr) {
return false;
}
AHardwareBuffer_toHardwareBuffer_compat = (AHardwareBufferToHardwareBufferFunc) dlsym(hhl,
"AHardwareBuffer_toHardwareBuffer");
if (AHardwareBuffer_toHardwareBuffer_compat == nullptr) {
return false;
}

AHardwareBuffer_describe_compat = (AHardwareBufferDescribeFunc) dlsym(hhl,
"AHardwareBuffer_describe");
if (AHardwareBuffer_describe_compat == nullptr) {
return false;
}
AHardwareBuffer_describe_compat = (AHardwareBufferDescribeFunc) dlsym(hhl,
"AHardwareBuffer_describe");
if (AHardwareBuffer_describe_compat == nullptr) {
return false;
}

return true;
return true;
}
16 changes: 8 additions & 8 deletions avif-coder/src/main/cpp/HardwareBuffersCompat.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,32 @@
bool loadAHardwareBuffersAPI();

typedef int (*AHardwareBufferAllocateFunc)(
const AHardwareBuffer_Desc *_Nonnull desc, AHardwareBuffer *_Nullable *_Nonnull outBuffer
const AHardwareBuffer_Desc *_Nonnull desc, AHardwareBuffer *_Nullable *_Nonnull outBuffer
);

typedef int (*AHardwareBufferIsSupportedFunc)(
const AHardwareBuffer_Desc *_Nonnull desc
const AHardwareBuffer_Desc *_Nonnull desc
);

typedef int (*AHardwareBufferReleaseFunc)(
AHardwareBuffer *_Nonnull buffer
AHardwareBuffer *_Nonnull buffer
);

typedef int (*AHardwareBufferUnlockFunc)(
AHardwareBuffer *_Nonnull buffer, int32_t *_Nullable fence
AHardwareBuffer *_Nonnull buffer, int32_t *_Nullable fence
);

typedef int (*AHardwareBufferLockFunc)(
AHardwareBuffer *_Nonnull buffer, uint64_t usage, int32_t fence,
const ARect *_Nullable rect, void *_Nullable *_Nonnull outVirtualAddress
AHardwareBuffer *_Nonnull buffer, uint64_t usage, int32_t fence,
const ARect *_Nullable rect, void *_Nullable *_Nonnull outVirtualAddress
);

typedef void (*AHardwareBufferDescribeFunc)(
const AHardwareBuffer *_Nonnull buffer, AHardwareBuffer_Desc *_Nonnull outDesc
const AHardwareBuffer *_Nonnull buffer, AHardwareBuffer_Desc *_Nonnull outDesc
);

typedef jobject (*AHardwareBufferToHardwareBufferFunc)(
JNIEnv *env, AHardwareBuffer *hardwareBuffer
JNIEnv *env, AHardwareBuffer *hardwareBuffer
);

extern AHardwareBufferAllocateFunc AHardwareBuffer_allocate_compat;
Expand Down
2 changes: 1 addition & 1 deletion avif-coder/src/main/cpp/IccRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void RecognizeICC(std::shared_ptr<heif_image_handle> &handle,
transfer == heif_transfer_characteristic_ITU_R_BT_2100_0_PQ) {
colorSpaceName = "DISPLAY_P3_PQ";
} else if (colorPrimaries == heif_color_primaries_SMPTE_EG_432_1 &&
transfer == heif_transfer_characteristic_IEC_61966_2_1) {
transfer == heif_transfer_characteristic_ITU_R_BT_709_5) {
colorSpaceName = "DISPLAY_P3";
} else if (colorPrimaries == heif_color_primaries_ITU_R_BT_2020_2_and_2100_0) {
colorSpaceName = "BT2020";
Expand Down
6 changes: 3 additions & 3 deletions avif-coder/src/main/cpp/IccRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
#include <string>
#include "heif.h"

void RecognizeICC(std::shared_ptr<heif_image_handle>& handle,
std::shared_ptr<heif_image>& image,
void RecognizeICC(std::shared_ptr<heif_image_handle> &handle,
std::shared_ptr<heif_image> &image,
std::vector<uint8_t> &iccProfile,
std::string &colorSpaceName,
heif_color_profile_nclx **colorProfileNclx,
bool* hasNclx);
bool *hasNclx);

#endif //AVIF_ICCRECOGNIZER_H
Loading

0 comments on commit 9d86b72

Please sign in to comment.