Skip to content

Commit 52f9efa

Browse files
authored
call heif_init on heif startup (libvips#3651)
a little safer, and makes libvips work with the libheif on ubuntu 23.04
1 parent a25782d commit 52f9efa

File tree

4 files changed

+103
-68
lines changed

4 files changed

+103
-68
lines changed

libvips/foreign/heifload.c

Lines changed: 91 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,32 @@ typedef struct _VipsForeignLoadHeif {
211211

212212
} VipsForeignLoadHeif;
213213

214+
#ifdef HAVE_HEIF_INIT
215+
static void *
216+
vips__heif_init_once(void *client)
217+
{
218+
struct heif_error error;
219+
220+
error = heif_init(NULL);
221+
if (error.code)
222+
g_warning("heif_init: %s (%d.%d)\n",
223+
error.message ? error.message : "(null)",
224+
error.code, error.subcode);
225+
226+
return NULL;
227+
}
228+
#endif /*HAVE_HEIF_INIT*/
229+
230+
void
231+
vips__heif_init(void)
232+
{
233+
#ifdef HAVE_HEIF_INIT
234+
static GOnce once = G_ONCE_INIT;
235+
236+
VIPS_ONCE(&once, vips__heif_init_once, NULL);
237+
#endif /*HAVE_HEIF_INIT*/
238+
}
239+
214240
void
215241
vips__heif_error(struct heif_error *error)
216242
{
@@ -220,6 +246,69 @@ vips__heif_error(struct heif_error *error)
220246
error->code, error->subcode);
221247
}
222248

249+
#ifdef DEBUG
250+
void
251+
vips__heif_image_print(struct heif_image *img)
252+
{
253+
const static enum heif_channel channel[] = {
254+
heif_channel_Y,
255+
heif_channel_Cb,
256+
heif_channel_Cr,
257+
heif_channel_R,
258+
heif_channel_G,
259+
heif_channel_B,
260+
heif_channel_Alpha,
261+
heif_channel_interleaved
262+
};
263+
264+
const static char *channel_name[] = {
265+
"heif_channel_Y",
266+
"heif_channel_Cb",
267+
"heif_channel_Cr",
268+
"heif_channel_R",
269+
"heif_channel_G",
270+
"heif_channel_B",
271+
"heif_channel_Alpha",
272+
"heif_channel_interleaved"
273+
};
274+
275+
int i;
276+
277+
printf("vips__heif_image_print:\n");
278+
for (i = 0; i < VIPS_NUMBER(channel); i++) {
279+
if (!heif_image_has_channel(img, channel[i]))
280+
continue;
281+
282+
printf("\t%s:\n", channel_name[i]);
283+
printf("\t\twidth = %d\n",
284+
heif_image_get_width(img, channel[i]));
285+
printf("\t\theight = %d\n",
286+
heif_image_get_height(img, channel[i]));
287+
printf("\t\tbits = %d\n",
288+
heif_image_get_bits_per_pixel(img, channel[i]));
289+
}
290+
}
291+
#endif /*DEBUG*/
292+
293+
/* Pick a chroma format. Shared with heifsave.
294+
*/
295+
int
296+
vips__heif_chroma(int bits_per_pixel, gboolean has_alpha)
297+
{
298+
if (bits_per_pixel == 8) {
299+
if (has_alpha)
300+
return heif_chroma_interleaved_RGBA;
301+
else
302+
return heif_chroma_interleaved_RGB;
303+
}
304+
else {
305+
if (has_alpha)
306+
return heif_chroma_interleaved_RRGGBBAA_BE;
307+
else
308+
return heif_chroma_interleaved_RRGGBB_BE;
309+
}
310+
}
311+
223312
typedef struct _VipsForeignLoadHeifClass {
224313
VipsForeignLoadClass parent_class;
225314

@@ -847,69 +936,6 @@ vips_foreign_load_heif_header(VipsForeignLoad *load)
847936
return 0;
848937
}
849938

850-
#ifdef DEBUG
851-
void
852-
vips__heif_image_print(struct heif_image *img)
853-
{
854-
const static enum heif_channel channel[] = {
855-
heif_channel_Y,
856-
heif_channel_Cb,
857-
heif_channel_Cr,
858-
heif_channel_R,
859-
heif_channel_G,
860-
heif_channel_B,
861-
heif_channel_Alpha,
862-
heif_channel_interleaved
863-
};
864-
865-
const static char *channel_name[] = {
866-
"heif_channel_Y",
867-
"heif_channel_Cb",
868-
"heif_channel_Cr",
869-
"heif_channel_R",
870-
"heif_channel_G",
871-
"heif_channel_B",
872-
"heif_channel_Alpha",
873-
"heif_channel_interleaved"
874-
};
875-
876-
int i;
877-
878-
printf("vips__heif_image_print:\n");
879-
for (i = 0; i < VIPS_NUMBER(channel); i++) {
880-
if (!heif_image_has_channel(img, channel[i]))
881-
continue;
882-
883-
printf("\t%s:\n", channel_name[i]);
884-
printf("\t\twidth = %d\n",
885-
heif_image_get_width(img, channel[i]));
886-
printf("\t\theight = %d\n",
887-
heif_image_get_height(img, channel[i]));
888-
printf("\t\tbits = %d\n",
889-
heif_image_get_bits_per_pixel(img, channel[i]));
890-
}
891-
}
892-
#endif /*DEBUG*/
893-
894-
/* Pick a chroma format. Shared with heifsave.
895-
*/
896-
int
897-
vips__heif_chroma(int bits_per_pixel, gboolean has_alpha)
898-
{
899-
if (bits_per_pixel == 8) {
900-
if (has_alpha)
901-
return heif_chroma_interleaved_RGBA;
902-
else
903-
return heif_chroma_interleaved_RGB;
904-
}
905-
else {
906-
if (has_alpha)
907-
return heif_chroma_interleaved_RRGGBBAA_BE;
908-
else
909-
return heif_chroma_interleaved_RRGGBB_BE;
910-
}
911-
}
912-
913939
static int
914940
vips_foreign_load_heif_generate(VipsRegion *out_region,
915941
void *seq, void *a, void *b, gboolean *stop)
@@ -1051,6 +1077,8 @@ vips_foreign_load_heif_class_init(VipsForeignLoadHeifClass *class)
10511077
VipsObjectClass *object_class = (VipsObjectClass *) class;
10521078
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
10531079

1080+
vips__heif_init();
1081+
10541082
gobject_class->dispose = vips_foreign_load_heif_dispose;
10551083
gobject_class->set_property = vips_object_set_property;
10561084
gobject_class->get_property = vips_object_get_property;

libvips/foreign/heifsave.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,6 @@ typedef struct _VipsForeignSaveHeif {
139139

140140
typedef VipsForeignSaveClass VipsForeignSaveHeifClass;
141141

142-
/* Defined in heifload.c
143-
*/
144-
void vips__heif_image_print(struct heif_image *img);
145-
void vips__heif_error(struct heif_error *error);
146-
147142
G_DEFINE_ABSTRACT_TYPE(VipsForeignSaveHeif, vips_foreign_save_heif,
148143
VIPS_TYPE_FOREIGN_SAVE);
149144

@@ -630,6 +625,8 @@ vips_foreign_save_heif_class_init(VipsForeignSaveHeifClass *class)
630625
VipsObjectClass *object_class = (VipsObjectClass *) class;
631626
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
632627

628+
vips__heif_init();
629+
633630
gobject_class->dispose = vips_foreign_save_heif_dispose;
634631
gobject_class->set_property = vips_object_set_property;
635632
gobject_class->get_property = vips_object_get_property;

libvips/foreign/pforeign.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,12 @@ void *vips__foreign_nifti_map(VipsNiftiMapFn fn, void *a, void *b);
201201
extern const char *vips__heic_suffs[];
202202
extern const char *vips__avif_suffs[];
203203
extern const char *vips__heif_suffs[];
204+
struct heif_image;
205+
struct heif_error;
206+
void vips__heif_init(void);
204207
int vips__heif_chroma(int bits_per_pixel, gboolean has_alpha);
208+
void vips__heif_image_print(struct heif_image *img);
209+
void vips__heif_error(struct heif_error *error);
205210

206211
extern const char *vips__jp2k_suffs[];
207212
int vips__foreign_load_jp2k_decompress(VipsImage *out,

meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,11 @@ if libheif_dep.found()
485485
if libheif_dep.version().version_compare('>=1.7.0')
486486
cfg_var.set('HAVE_HEIF_AVIF', '1')
487487
endif
488+
489+
# heif_init in 1.13
490+
if libheif_dep.version().version_compare('>=1.13.0')
491+
cfg_var.set('HAVE_HEIF_INIT', '1')
492+
endif
488493
endif
489494

490495
libjxl_dep = dependency('libjxl', version: '>=0.6', required: get_option('jpeg-xl'))

0 commit comments

Comments
 (0)