Skip to content

Commit 5429bdd

Browse files
committed
Fix building for coil
1 parent 86666e5 commit 5429bdd

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class MainActivity : AppCompatActivity() {
3636

3737
// Example of a call to a native method
3838
//
39-
val buffer = this.assets.open("hato-wide-gamut.avif").source().buffer().readByteArray()
39+
val buffer = this.assets.open("test_1.avif").source().buffer().readByteArray()
4040
// assert(HeifCoder().isAvif(buffer))
4141
val size = HeifCoder().getSize(buffer)!!
4242
val bitmap = HeifCoder().decodeSampled(buffer, size.width / 3, size.height / 3)
@@ -45,10 +45,18 @@ class MainActivity : AppCompatActivity() {
4545
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
4646
// opts.inPreferredConfig = Bitmap.Config.RGBA_F16
4747
// }
48+
binding.imageView.setImageBitmap(bitmap)
4849
val encoded = HeifCoder().encodeAvif(bitmap)
4950
val decodedSample = HeifCoder().decode(encoded)
5051
binding.imageView.setImageBitmap(decodedSample)
5152

53+
// binding.imageView.load("https://wh.aimuse.online/creatives/IMUSE_03617fe2db82a584166_27/TT_a9d21ff1061d785347935fef/68f06252.avif",
54+
// imageLoader = ImageLoader.Builder(this)
55+
// .components {
56+
// add(HeifDecoder.Factory())
57+
// }
58+
// .build())
59+
5260
// binding.imageView.setImageBitmap(bitmap)
5361
// binding.imageView.setImageBitmap(cc16)
5462
// val avif12DepthBuffer =

avif-coder-coil/src/main/java/com/github/awxkee/avifcoil/HeifDecoder.kt

+18-6
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ import coil.size.Scale
1515
import coil.size.pxOrElse
1616
import com.radzivon.bartoshyk.avif.coder.HeifCoder
1717
import kotlinx.coroutines.runInterruptible
18-
import okio.ByteString
18+
import okio.ByteString.Companion.encodeUtf8
1919

2020
class HeifDecoder(
2121
private val source: SourceResult,
2222
private val options: Options,
2323
private val imageLoader: ImageLoader,
24-
private val sourceData: ByteArray,
2524
) : Decoder {
2625

2726
override suspend fun decode(): DecodeResult? = runInterruptible {
27+
val sourceData = source.source.source().readByteArray()
2828
val originalSize = HeifCoder().getSize(sourceData) ?: return@runInterruptible null
2929
val dstWidth = options.size.width.pxOrElse { 0 }
3030
val dstHeight = options.size.height.pxOrElse { 0 }
@@ -115,10 +115,22 @@ class HeifDecoder(
115115
options: Options,
116116
imageLoader: ImageLoader
117117
): Decoder? {
118-
val originalBytes = result.source.source().readByteArray()
119-
if (HeifCoder().isSupportedImage(originalBytes)) {
120-
return HeifDecoder(result, options, imageLoader, originalBytes)
121-
} else return null
118+
return if (AVAILABLE_BRANDS.any {
119+
result.source.source().rangeEquals(4, it)
120+
}) HeifDecoder(result, options, imageLoader) else null
121+
}
122+
123+
companion object {
124+
private val MIF = "ftypmif1".encodeUtf8()
125+
private val MSF = "ftypmsf1".encodeUtf8()
126+
private val HEIC = "ftypheic".encodeUtf8()
127+
private val HEIX = "ftypheix".encodeUtf8()
128+
private val HEVC = "ftyphevc".encodeUtf8()
129+
private val HEVX = "ftyphevx".encodeUtf8()
130+
private val AVIF = "ftypavif".encodeUtf8()
131+
private val AVIS = "ftypavis".encodeUtf8()
132+
133+
private val AVAILABLE_BRANDS = listOf(MIF, MSF, HEIC, HEIX, HEVC, HEVX, AVIF, AVIS)
122134
}
123135
}
124136

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

+17-14
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
9595
std::copy(reinterpret_cast<uint8_t *>(addr),
9696
reinterpret_cast<uint8_t *>(addr) + info.height * info.stride, sourceData.data());
9797

98+
AndroidBitmap_unlockPixels(env, bitmap);
99+
98100
heif_image *image;
99101
heif_chroma chroma = heif_chroma_interleaved_RGBA;
100102
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_F16 &&
@@ -104,7 +106,6 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
104106
result = heif_image_create((int) info.width, (int) info.height, heif_colorspace_RGB,
105107
chroma, &image);
106108
if (result.code != heif_error_Ok) {
107-
AndroidBitmap_unlockPixels(env, bitmap);
108109
throwCantEncodeImageException(env, result.message);
109110
return static_cast<jbyteArray>(nullptr);
110111
}
@@ -123,15 +124,15 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
123124
result = heif_image_add_plane(image, heif_channel_interleaved, (int) info.width,
124125
(int) info.height, bitDepth);
125126
if (result.code != heif_error_Ok) {
126-
AndroidBitmap_unlockPixels(env, bitmap);
127127
throwCantEncodeImageException(env, result.message);
128128
return static_cast<jbyteArray>(nullptr);
129129
}
130130
int stride;
131131
uint8_t *imgData = heif_image_get_plane(image, heif_channel_interleaved, &stride);
132132
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
133-
libyuv::ARGBCopy(sourceData.data(), (int) info.stride, imgData,
134-
stride, (int) info.width, (int) info.height);
133+
libyuv::ARGBCopy(sourceData.data(), (int) info.stride,
134+
imgData,
135+
stride, (int) info.width, (int) info.height);
135136
} else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
136137
libyuv::RGB565ToARGB(sourceData.data(), (int) info.stride, imgData,
137138
stride, (int) info.width, (int) info.height);
@@ -178,21 +179,22 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
178179
for (int y = 0; y < info.height; ++y) {
179180

180181
auto srcPtr = reinterpret_cast<uint16_t *>(srcData);
181-
auto dstPtr = reinterpret_cast<uint64_t *>(data64Ptr);
182+
auto dstPtr = reinterpret_cast<uint16_t *>(data64Ptr);
182183

183184
for (int x = 0; x < info.width; ++x) {
184185
auto alpha = half_to_float(srcPtr[3]);
185-
tmpR = (uint16_t) (half_to_float(srcPtr[0]) / scale / (alpha != 0 ? alpha : 1));
186-
tmpG = (uint16_t) (half_to_float(srcPtr[1]) / scale / (alpha != 0 ? alpha : 1));
187-
tmpB = (uint16_t) (half_to_float(srcPtr[2]) / scale / (alpha != 0 ? alpha : 1));
186+
tmpR = (uint16_t) (half_to_float(srcPtr[0]) / scale);
187+
tmpG = (uint16_t) (half_to_float(srcPtr[1]) / scale);
188+
tmpB = (uint16_t) (half_to_float(srcPtr[2]) / scale);
188189
tmpA = (uint16_t) (alpha / scale);
189-
uint64_t color =
190-
((uint64_t) tmpA & 0xffff) << 48 | ((uint64_t) tmpB & 0xffff) << 32 |
191-
((uint64_t) tmpG & 0xffff) << 16 | ((uint64_t) tmpR & 0xffff);
192-
dstPtr[0] = color;
190+
191+
dstPtr[0] = tmpR;
192+
dstPtr[1] = tmpG;
193+
dstPtr[2] = tmpB;
194+
dstPtr[3] = tmpA;
193195

194196
srcPtr += 4;
195-
dstPtr += 1;
197+
dstPtr += 4;
196198
}
197199

198200
srcData += info.stride;
@@ -242,7 +244,6 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
242244
dstARGB.reset();
243245
}
244246
}
245-
AndroidBitmap_unlockPixels(env, bitmap);
246247

247248
heif_image_handle *handle;
248249
std::shared_ptr<heif_encoding_options> options(heif_encoding_options_alloc(),
@@ -251,6 +252,8 @@ jbyteArray encodeBitmap(JNIEnv *env, jobject thiz,
251252
});
252253
options->version = 5;
253254
options->image_orientation = heif_orientation_normal;
255+
options->output_nclx_profile = nullptr;
256+
options->save_two_colr_boxes_when_ICC_and_nclx_available = false;
254257

255258
result = heif_context_encode_image(ctx.get(), image, encoder.get(), options.get(), &handle);
256259
options.reset();

0 commit comments

Comments
 (0)