Skip to content

Commit

Permalink
refactor(heif): properly release native resources
Browse files Browse the repository at this point in the history
  • Loading branch information
gotson committed Sep 29, 2023
1 parent 1fc3ee6 commit 1c19914
Showing 1 changed file with 16 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,25 @@ public static BasicInfo getBasicInfo(final ImageInputStream stream) throws HeifE
var data = arena.allocate(heifData.length);
data.copyFrom(MemorySegment.ofArray(heifData));

var heifContext = heif_h.heif_context_alloc();
MemorySegment heifContext = null;
MemorySegment handle = null;
try {
heif_h.heif_init(arena, MemorySegment.NULL);
heifContext = heif_h.heif_context_alloc();
checkError(heif_h.heif_context_read_from_memory_without_copy(arena, heifContext, data, heifData.length, MemorySegment.NULL));
var frameCount = heif_h.heif_context_get_number_of_top_level_images(heifContext);
var handlePtr = arena.allocate(C_POINTER);
checkError(heif_h.heif_context_get_primary_image_handle(arena, heifContext, handlePtr));
var handle = handlePtr.get(C_POINTER, 0);
handle = handlePtr.get(C_POINTER, 0);
var width = heif_h.heif_image_handle_get_width(handle);
var height = heif_h.heif_image_handle_get_height(handle);
var hasAlpha = heif_h.heif_image_handle_has_alpha_channel(handle) > 0;

return new BasicInfo(width, height, hasAlpha, null, frameCount);
} finally {
heif_h.heif_context_free(heifContext);
if (heifContext != null) heif_h.heif_context_free(heifContext);
if (handle != null) heif_h.heif_image_handle_release(handle);
heif_h.heif_deinit();
}
} catch (IOException e) {
throw new HeifException("Couldn't get stream content", e);
Expand All @@ -102,8 +107,11 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W
var data = arena.allocate(heifData.length);
data.copyFrom(MemorySegment.ofArray(heifData));

var heifContext = heif_h.heif_context_alloc();
MemorySegment heifContext = null;
MemorySegment handle = null;
try {
heif_h.heif_init(arena, MemorySegment.NULL);
heifContext = heif_h.heif_context_alloc();
checkError(heif_h.heif_context_read_from_memory_without_copy(arena, heifContext, data, heifData.length, MemorySegment.NULL));

var imageIds = arena.allocateArray(C_INT, info.frameCount());
Expand All @@ -112,7 +120,7 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W

var handlePtr = arena.allocate(C_POINTER);
checkError(heif_h.heif_context_get_image_handle(arena, heifContext, imageId, handlePtr));
var handle = handlePtr.get(C_POINTER, 0);
handle = handlePtr.get(C_POINTER, 0);
var width = heif_h.heif_image_handle_get_width(handle);
var height = heif_h.heif_image_handle_get_height(handle);

Expand All @@ -136,15 +144,13 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W
var ssOffX = param != null ? param.getSubsamplingXOffset() : 0;
var ssOffY = param != null ? param.getSubsamplingYOffset() : 0;

// heif_image_crop doesn't seem to work and produces garbage image - handling subimage manually
var offset = 0;
for (int row = sourceRegion.y + ssOffY; row < sourceRegion.y + sourceRegion.height; row += ssY) {
if (offset >= pixelsRaster.length) break;
for (int col = sourceRegion.x + ssOffX; col < sourceRegion.x + sourceRegion.width; col += ssX) {
if (offset >= pixelsRaster.length) break;
int pixel = pixelsArray[(row * width) + col];
pixelsRaster[offset++] = pixel;
// pixelsBuffer.get(pixelsRaster, offset++, 1);

}
}
Expand All @@ -156,7 +162,9 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W
raster.setDataElements(0, 0, raster.getWidth(), raster.getHeight(), pixelsRaster);
}
} finally {
heif_h.heif_context_free(heifContext);
if (heifContext != null) heif_h.heif_context_free(heifContext);
if (handle != null) heif_h.heif_image_handle_release(handle);
heif_h.heif_deinit();
}

} catch (IOException e) {
Expand Down

0 comments on commit 1c19914

Please sign in to comment.