Skip to content

Commit

Permalink
fix(heif): decoding issue when width is not aligned
Browse files Browse the repository at this point in the history
  • Loading branch information
gotson committed Nov 1, 2023
1 parent 507787b commit dffc40b
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.gotson.nightmonkeys.heif;

import com.github.gotson.nightmonkeys.heif.lib.HeifError;
import com.github.gotson.nightmonkeys.heif.lib.enums.HeifChroma;
import com.github.gotson.nightmonkeys.heif.lib.enums.HeifColorSpace;
import com.github.gotson.nightmonkeys.heif.lib.enums.HeifErrorCode;
import com.github.gotson.nightmonkeys.heif.lib.enums.HeifFiletypeResult;
import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h;
Expand All @@ -21,8 +23,6 @@
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.C_INT;
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.C_POINTER;
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.heif_channel_interleaved;
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.heif_chroma_interleaved_RGBA;
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.heif_colorspace_RGB;
import static com.github.gotson.nightmonkeys.heif.lib.panama.heif_h.heif_get_version;

/**
Expand Down Expand Up @@ -129,10 +129,14 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W
var height = heif_h.heif_image_handle_get_height(handle);

var imagePtr = arena.allocate(C_POINTER);
checkError(heif_h.heif_decode_image(arena, handle, imagePtr, heif_colorspace_RGB(), heif_chroma_interleaved_RGBA(), MemorySegment.NULL));
checkError(
heif_h.heif_decode_image(arena, handle, imagePtr, HeifColorSpace.HEIF_COLOR_SPACE_RGB.intValue(), HeifChroma.HEIF_CHROMA_INTERLEAVED_RGBA.intValue(),
MemorySegment.NULL));
var image = imagePtr.get(C_POINTER, 0);

var pixels = heif_h.heif_image_get_plane_readonly(image, heif_channel_interleaved(), MemorySegment.NULL);
var stridePtr = arena.allocate(C_INT);
var pixels = heif_h.heif_image_get_plane_readonly(image, heif_channel_interleaved(), stridePtr);
var stride = stridePtr.get(C_INT, 0);
var pixelsRaster = new int[Math.min(width, raster.getWidth()) * Math.min(height, raster.getHeight())];

var sourceRegion = param != null ? param.getSourceRegion() : null;
Expand All @@ -147,7 +151,7 @@ public static void decode(final ImageInputStream stream, BasicInfo info, final W
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 = pixels.get(pixelLayout, (((long) row * width) + col) * pixelLayout.byteSize());
int pixel = pixels.get(pixelLayout, (long) row * stride + (col * pixelLayout.byteSize()));
pixelsRaster[offset++] = pixel;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.gotson.nightmonkeys.heif.lib.enums;

import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h;

public enum HeifChannel {
HEIF_CHANNEL_Y(heif_h.heif_channel_Y()),
HEIF_CHANNEL_CB(heif_h.heif_channel_Cb()),
HEIF_CHANNEL_CR(heif_h.heif_channel_Cr()),
HEIF_CHANNEL_R(heif_h.heif_channel_R()),
HEIF_CHANNEL_G(heif_h.heif_channel_G()),
HEIF_CHANNEL_B(heif_h.heif_channel_B()),
HEIF_CHANNEL_ALPHA(heif_h.heif_channel_Alpha()),
HEIF_CHANNEL_INTERLEAVED(heif_h.heif_channel_interleaved()),
;

private final int val;

HeifChannel(int val) {
this.val = val;
}

public int intValue() {
return val;
}

public static HeifChannel fromId(int id) {
for (HeifChannel type : values()) {
if (type.intValue() == id) {
return type;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.github.gotson.nightmonkeys.heif.lib.enums;

import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h;

public enum HeifChroma {
HEIF_CHROMA_UNDEFINED(heif_h.heif_chroma_undefined()),
HEIF_CHROMA_MONOCHROME(heif_h.heif_chroma_monochrome()),
HEIF_CHROMA_420(heif_h.heif_chroma_420()),
HEIF_CHROMA_422(heif_h.heif_chroma_422()),
HEIF_CHROMA_444(heif_h.heif_chroma_444()),
HEIF_CHROMA_INTERLEAVED_RGB(heif_h.heif_chroma_interleaved_RGB()),
HEIF_CHROMA_INTERLEAVED_RGBA(heif_h.heif_chroma_interleaved_RGBA()),
HEIF_CHROMA_INTERLEAVED_RRGGBB_BE(heif_h.heif_chroma_interleaved_RRGGBB_BE()),
HEIF_CHROMA_INTERLEAVED_RRGGBBAA_BE(heif_h.heif_chroma_interleaved_RRGGBBAA_BE()),
HEIF_CHROMA_INTERLEAVED_RRGGBB_LE(heif_h.heif_chroma_interleaved_RRGGBB_LE()),
HEIF_CHROMA_INTERLEAVED_RRGGBBAA_LE(heif_h.heif_chroma_interleaved_RRGGBBAA_LE());

private final int val;

HeifChroma(int val) {
this.val = val;
}

public int intValue() {
return val;
}

public static HeifChroma fromId(int id) {
for (HeifChroma type : values()) {
if (type.intValue() == id) {
return type;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.github.gotson.nightmonkeys.heif.lib.enums;

import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h;

public enum HeifColorSpace {
HEIF_COLOR_SPACE_UNDEFINED(heif_h.heif_colorspace_undefined()),
HEIF_COLOR_SPACE_YCBCR(heif_h.heif_colorspace_YCbCr()),
HEIF_COLOR_SPACE_RGB(heif_h.heif_colorspace_RGB()),
HEIF_COLOR_SPACE_MONOCHROME(heif_h.heif_colorspace_monochrome());

private final int val;

HeifColorSpace(int val) {
this.val = val;
}

public int intValue() {
return val;
}

public static HeifColorSpace fromId(int id) {
for (HeifColorSpace type : values()) {
if (type.intValue() == id) {
return type;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
package com.github.gotson.nightmonkeys.heif.imageio.plugins;

import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import javax.imageio.spi.ImageReaderSpi;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -59,7 +54,11 @@ protected List<TestData> getTestData() {

// AVIF Animation (from http://188.121.162.14/avif/)
// Status: not supported by libheif, only 1 image will be available
new TestData(getClassLoaderResource("/avif/animation2.avif"), new Dimension(640, 640))
new TestData(getClassLoaderResource("/avif/animation2.avif"), new Dimension(640, 640)),

// AVIF with stride != from width
new TestData(getClassLoaderResource("/avif/kk.avif"), new Dimension(2535, 4167)),
new TestData(getClassLoaderResource("/avif/monster.avif"), new Dimension(846, 1200))
);
}

Expand Down
Binary file added imageio-heif/src/test/resources/avif/kk.avif
Binary file not shown.
Binary file added imageio-heif/src/test/resources/avif/monster.avif
Binary file not shown.

0 comments on commit dffc40b

Please sign in to comment.