fix bug #788 in HEIF usage, stride is requiremaster
parent
0f9dd9627a
commit
f1a53c0821
|
@ -1,9 +1,9 @@
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.7 FATAL_ERROR)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.7 FATAL_ERROR)
|
||||||
|
project(GD)
|
||||||
SET(PACKAGE GD)
|
SET(PACKAGE GD)
|
||||||
SET(PACKAGE_NAME GD)
|
SET(PACKAGE_NAME GD)
|
||||||
|
|
||||||
PROJECT(GD)
|
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH "${GD_SOURCE_DIR}/cmake/modules")
|
SET(CMAKE_MODULE_PATH "${GD_SOURCE_DIR}/cmake/modules")
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,8 @@ static gdImagePtr _gdImageCreateFromHeifCtx(gdIOCtx *infile, gd_heif_brand expec
|
||||||
size_t size = 0, n = GD_HEIF_ALLOC_STEP;
|
size_t size = 0, n = GD_HEIF_ALLOC_STEP;
|
||||||
gdImagePtr im;
|
gdImagePtr im;
|
||||||
int x, y;
|
int x, y;
|
||||||
uint8_t *p;
|
uint8_t *p, *row_start;
|
||||||
|
int stride;
|
||||||
|
|
||||||
magic_len = gdGetBuf(magic, GD_HEIF_HEADER, infile);
|
magic_len = gdGetBuf(magic, GD_HEIF_HEADER, infile);
|
||||||
if (magic_len != GD_HEIF_HEADER || !_gdHeifCheckBrand(magic, expected_brand)) {
|
if (magic_len != GD_HEIF_HEADER || !_gdHeifCheckBrand(magic, expected_brand)) {
|
||||||
|
@ -207,7 +208,7 @@ static gdImagePtr _gdImageCreateFromHeifCtx(gdIOCtx *infile, gd_heif_brand expec
|
||||||
heif_context_free(heif_ctx);
|
heif_context_free(heif_ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, NULL);
|
rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, &stride);
|
||||||
if (!rgba) {
|
if (!rgba) {
|
||||||
gd_error("gd-heif cannot get image plane\n");
|
gd_error("gd-heif cannot get image plane\n");
|
||||||
gdFree(filedata);
|
gdFree(filedata);
|
||||||
|
@ -217,7 +218,9 @@ static gdImagePtr _gdImageCreateFromHeifCtx(gdIOCtx *infile, gd_heif_brand expec
|
||||||
gdImageDestroy(im);
|
gdImageDestroy(im);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
row_start = rgba;
|
||||||
for (y = 0, p = rgba; y < height; y++) {
|
for (y = 0, p = rgba; y < height; y++) {
|
||||||
|
p = row_start;
|
||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
uint8_t r = *(p++);
|
uint8_t r = *(p++);
|
||||||
uint8_t g = *(p++);
|
uint8_t g = *(p++);
|
||||||
|
@ -225,6 +228,7 @@ static gdImagePtr _gdImageCreateFromHeifCtx(gdIOCtx *infile, gd_heif_brand expec
|
||||||
uint8_t a = gdAlphaMax - (*(p++) >> 1);
|
uint8_t a = gdAlphaMax - (*(p++) >> 1);
|
||||||
im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a);
|
im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
row_start += stride;
|
||||||
}
|
}
|
||||||
gdFree(filedata);
|
gdFree(filedata);
|
||||||
heif_image_release(heif_im);
|
heif_image_release(heif_im);
|
||||||
|
@ -273,7 +277,8 @@ static int _gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifC
|
||||||
uint8_t *rgba;
|
uint8_t *rgba;
|
||||||
int x, y;
|
int x, y;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
uint8_t *row_start;
|
||||||
|
int stride;
|
||||||
if (im == NULL) {
|
if (im == NULL) {
|
||||||
return GD_FALSE;
|
return GD_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +354,7 @@ static int _gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifC
|
||||||
return GD_FALSE;
|
return GD_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, NULL);
|
rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, &stride);
|
||||||
if (!rgba) {
|
if (!rgba) {
|
||||||
gd_error("gd-heif cannot get image plane\n");
|
gd_error("gd-heif cannot get image plane\n");
|
||||||
heif_image_release(heif_im);
|
heif_image_release(heif_im);
|
||||||
|
@ -357,8 +362,9 @@ static int _gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifC
|
||||||
heif_context_free(heif_ctx);
|
heif_context_free(heif_ctx);
|
||||||
return GD_FALSE;
|
return GD_FALSE;
|
||||||
}
|
}
|
||||||
p = rgba;
|
row_start = rgba;
|
||||||
for (y = 0; y < gdImageSY(im); y++) {
|
for (y = 0; y < gdImageSY(im); y++) {
|
||||||
|
p = row_start;
|
||||||
for (x = 0; x < gdImageSX(im); x++) {
|
for (x = 0; x < gdImageSX(im); x++) {
|
||||||
int c;
|
int c;
|
||||||
char a;
|
char a;
|
||||||
|
@ -374,6 +380,7 @@ static int _gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifC
|
||||||
*(p++) = gdTrueColorGetBlue(c);
|
*(p++) = gdTrueColorGetBlue(c);
|
||||||
*(p++) = a;
|
*(p++) = a;
|
||||||
}
|
}
|
||||||
|
row_start += stride;
|
||||||
}
|
}
|
||||||
err = heif_context_encode_image(heif_ctx, heif_im, heif_enc, NULL, NULL);
|
err = heif_context_encode_image(heif_ctx, heif_im, heif_enc, NULL, NULL);
|
||||||
heif_encoder_release(heif_enc);
|
heif_encoder_release(heif_enc);
|
||||||
|
|
|
@ -5,6 +5,7 @@ LIST(APPEND TESTS_FILES
|
||||||
heif_null
|
heif_null
|
||||||
heif_ptr_double_free
|
heif_ptr_double_free
|
||||||
heif_read
|
heif_read
|
||||||
|
bug788
|
||||||
)
|
)
|
||||||
ENDIF(HEIF_FOUND)
|
ENDIF(HEIF_FOUND)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Bug 788 stride not implemented.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gd.h"
|
||||||
|
#include "gdtest.h"
|
||||||
|
|
||||||
|
#include <libheif/heif.h>
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
FILE *fp;
|
||||||
|
gdImagePtr in;
|
||||||
|
gdImagePtr dst;
|
||||||
|
gdImagePtr diff;
|
||||||
|
int size;
|
||||||
|
void *data;
|
||||||
|
CuTestImageResult result = {0, 0};
|
||||||
|
fp = gdTestFileOpen2("heif", "bug788.png");
|
||||||
|
in = gdImageCreateFromPng(fp);
|
||||||
|
fclose(fp);
|
||||||
|
fp = fopen("1.png", "wb");
|
||||||
|
gdImagePng(in, fp);
|
||||||
|
fclose(fp);
|
||||||
|
data = gdImageHeifPtrEx(in, &size, 200, GD_HEIF_CODEC_HEVC, GD_HEIF_CHROMA_444);
|
||||||
|
|
||||||
|
dst = gdImageCreateFromHeifPtr(size, data);
|
||||||
|
diff = gdImageCreateTrueColor(gdImageSX(dst), gdImageSY(dst));
|
||||||
|
if (gdTestAssertMsg(dst != NULL, "cannot compare with NULL buffer")) {
|
||||||
|
gdTestImageDiff(in, dst, diff, &result);
|
||||||
|
}
|
||||||
|
fp = fopen("2.png", "wb");
|
||||||
|
gdImageHeif(dst, fp);
|
||||||
|
fclose(fp);
|
||||||
|
fp = fopen("3.png", "wb");
|
||||||
|
gdImagePng(diff, fp);
|
||||||
|
fclose(fp);
|
||||||
|
/* colorspace conversion cannot avoid colors differences, even if we use the same format/colorspace for in and out */
|
||||||
|
gdTestAssertMsg(result.pixels_changed > 30, "pixels changed: %d\n", result.pixels_changed);
|
||||||
|
gdImageDestroy(dst);
|
||||||
|
gdImageDestroy(in);
|
||||||
|
gdImageDestroy(diff);
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
Loading…
Reference in New Issue