Skip to content

Commit

Permalink
Properly handle HDR photos
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Sep 3, 2023
1 parent 85f693c commit 6e2b49b
Show file tree
Hide file tree
Showing 22 changed files with 2,599 additions and 169 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ local.properties
/libyuv/build-arm64-v8a/yuvconstants
/libyuv/build-armeabi-v7a/yuvconstants
/libyuv/build-x86_64/yuvconstants
libyuv
libyuv
lide265
libheif
x265
aom
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Library provides simple interface to decode or encode ( create ) AVIF and HEIF i
Very fast and convinient to use AVIF in android apps with api version 24+
26+. Based on libheif, libde265, libx265, libyuv, libaom and libdav1d

Correctly handles ICC, and color profiles. Fully supports HDR images, 10, 12 bit
The most features AVIF, HEIF library in android

# Usage example

```kotlin
Expand Down Expand Up @@ -57,12 +60,14 @@ libdav1d:
- meson
- ninja
- cmake
- nasm

libyuv, de265, x265, aom:

- ndk
- ninja
- cmake
- nasm

libheif:
- ndk
Expand Down
Binary file not shown.
Binary file added app/src/main/assets/bbb_alpha_inverted.avif
Binary file not shown.
Binary file added app/src/main/assets/hdr_cosmos07296_12bit.avif
Binary file not shown.
Binary file not shown.
Binary file added app/src/main/assets/pngtree.avif
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class MainActivity : AppCompatActivity() {

// Example of a call to a native method

val buffer = this.assets.open("heic_icc.heic").source().buffer().readByteArray()
val buffer = this.assets.open("sdr_cosmos12920_cicp1-13-6_yuv444_full_qp20.avif").source().buffer().readByteArray()
// assert(HeifCoder().isAvif(buffer))
val bitmap = HeifCoder().decode(buffer)
// val opts = BitmapFactory.Options()
Expand Down
5 changes: 1 addition & 4 deletions avif-coder/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ target_link_libraries(cpufeatures dl)
list(APPEND EXTRA_LIBS cpufeatures)

include(CheckCXXCompilerFlag)
if(ANDROID_ABI STREQUAL armeabi-v7a)
set_source_files_properties(coder.cpp PROPERTIES COMPILE_FLAGS -mfpu=neon)
add_definitions("-DHAVE_NEON=1")
elseif(ANDROID_ABI STREQUAL arm64-v8a)
if(ANDROID_ABI STREQUAL arm64-v8a)
set_target_properties(coder PROPERTIES COMPILE_FLAGS -mfpu=neon)
add_definitions("-DHAVE_NEON=1")
endif()
Expand Down
67 changes: 67 additions & 0 deletions avif-coder/src/main/cpp/attenuate_alpha.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// Created by Radzivon Bartoshyk on 03/09/2023.
//

#include "attenuate_alpha.h"

#if HAVE_NEON

#include <cstdint>
#include <arm_neon.h>

void premultiply_alpha_NEON(uint16_t *rgba_data, int numPixels) {
// Process pixels in batches of 8 using NEON
int batchSize = numPixels / 8;
uint16x8_t alpha_mult, r, g, b;

uint16_t *pixel = rgba_data;

uint16x8_t neon_const_32768 = vdupq_n_u16(32768);

auto pixels = rgba_data;
for (int i = 0; i < batchSize; i += 8) {
uint16x8_t alpha = vld1q_u16(pixels + 3); // Load alpha values
uint16x8_t red = vld1q_u16(pixels + i); // Load red values
uint16x8_t green = vld1q_u16(pixels + 1); // Load green values
uint16x8_t blue = vld1q_u16(pixels + 2); // Load blue values

// Perform the premultiplication
red = vmulq_u16(red, alpha);
green = vmulq_u16(green, alpha);
blue = vmulq_u16(blue, alpha);

// Divide the result by 65536 (shift right by 16)
red = vshrq_n_u16(red, 16);
green = vshrq_n_u16(green, 16);
blue = vshrq_n_u16(blue, 16);

// Store the premultiplied values back to memory
vst1q_u16(pixels + i, red);
vst1q_u16(pixels + i + 1, green);
vst1q_u16(pixels + i + 2, blue);

pixels += 4;
}


for (int i = batchSize; i < numPixels; i++) {
uint16_t alpha = pixel[3];
pixel[0] = (pixel[0] * alpha + 32768) >> 16;
pixel[1] = (pixel[1] * alpha + 32768) >> 16;
pixel[2] = (pixel[2] * alpha + 32768) >> 16;
pixel += 4;
}
}

#endif

void premultiply_alpha64(uint16_t *rgba_data, int num_pixels) {
uint16_t *pixel = rgba_data;
for (int i = 0; i < num_pixels; ++i) {
uint16_t alpha = pixel[3];
pixel[0] = (pixel[0] * alpha + 32768) >> 16;
pixel[1] = (pixel[1] * alpha + 32768) >> 16;
pixel[2] = (pixel[2] * alpha + 32768) >> 16;
pixel += 4;
}
}
15 changes: 15 additions & 0 deletions avif-coder/src/main/cpp/attenuate_alpha.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Created by Radzivon Bartoshyk on 03/09/2023.
//

#ifndef AVIF_ATTENUATE_ALPHA_H
#define AVIF_ATTENUATE_ALPHA_H

#include <cstdint>

void premultiply_alpha64(uint16_t *rgba_data, int num_pixels);
#if HAVE_NEON
void premultiply_alpha_NEON(uint16_t *rgba_data, int numPixels);
#endif

#endif //AVIF_ATTENUATE_ALPHA_H
Loading

0 comments on commit 6e2b49b

Please sign in to comment.