[gimp] plug-ins: metadata import/export for JPEG XL format



commit eac694905fc8144389faab23f945738031b82331
Author: Daniel Novomeský <dnovomesky gmail com>
Date:   Tue Oct 4 17:02:08 2022 +0200

    plug-ins: metadata import/export for JPEG XL format
    
    Changes require libjxl 0.7.0

 configure.ac                   |   2 +-
 meson.build                    |   2 +-
 plug-ins/common/Makefile.am    |   1 +
 plug-ins/common/file-jpegxl.c  | 441 ++++++++++++++++++++++++++++++++++++-----
 plug-ins/common/meson.build    |   2 +-
 plug-ins/common/plugin-defs.pl |   2 +-
 6 files changed, 397 insertions(+), 53 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b7f1a78a09..713feb0b0b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,7 +77,7 @@ m4_define([json_glib_required_version], [1.2.6])
 m4_define([lcms_required_version], [2.8])
 m4_define([libgudev_required_version], [167])
 m4_define([libheif_required_version], [1.3.2])
-m4_define([libjxl_required_version], [0.6.1])
+m4_define([libjxl_required_version], [0.7.0])
 m4_define([liblzma_required_version], [5.0.0])
 m4_define([libmypaint_required_version], [1.3.0])
 m4_define([libpng_required_version], [1.6.25])
diff --git a/meson.build b/meson.build
index 6f5a504344..149065b6d9 100644
--- a/meson.build
+++ b/meson.build
@@ -834,7 +834,7 @@ if openjpeg.found()
   MIMEtypes += [ 'image/jp2', 'image/jpeg2000', 'image/jpx', ]
 endif
 
-jpegxl_minver  = '0.6.1'
+jpegxl_minver  = '0.7.0'
 libjxl         = dependency('libjxl',
                             version: '>='+jpegxl_minver,
                             required: get_option('jpeg-xl')
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index 85ae6be80a..095a489677 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -844,6 +844,7 @@ file_jpegxl_LDADD = \
        $(GEGL_LIBS)            \
        $(JXL_THREADS_LIBS)             \
        $(JXL_LIBS)             \
+       $(GEXIV2_LIBS)          \
        $(RT_LIBS)              \
        $(INTLLIBS)             \
        $(file_jpegxl_RC)
diff --git a/plug-ins/common/file-jpegxl.c b/plug-ins/common/file-jpegxl.c
index 8dcd013c46..7b40523a74 100644
--- a/plug-ins/common/file-jpegxl.c
+++ b/plug-ins/common/file-jpegxl.c
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include <gexiv2/gexiv2.h>
 #include <glib/gstdio.h>
 
 #include <jxl/decode.h>
@@ -191,6 +192,18 @@ jpegxl_create_procedure (GimpPlugIn  *plug_in,
                              _("Store ICC profile to exported JXL file"),
                              FALSE,
                              G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_BOOLEAN (procedure, "save-exif",
+                             _("Save Exi_f"),
+                             _("Toggle saving Exif data"),
+                             gimp_export_exif (),
+                             G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_BOOLEAN (procedure, "save-xmp",
+                             _("Save _XMP"),
+                             _("Toggle saving XMP data"),
+                             gimp_export_xmp (),
+                             G_PARAM_READWRITE);
     }
 
   return procedure;
@@ -300,6 +313,8 @@ load_image (GFile        *file,
       return NULL;
     }
 
+  JxlDecoderCloseInput (decoder);
+
   if (JxlDecoderSubscribeEvents (decoder, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE) 
!= JXL_DEC_SUCCESS)
     {
       g_set_error (error, G_FILE_ERROR, 0,
@@ -627,6 +642,208 @@ load_image (GFile        *file,
     {
       g_object_unref (profile);
     }
+
+  if (basicinfo.have_container)
+    {
+      JxlDecoderReleaseInput (decoder);
+      JxlDecoderRewind (decoder);
+
+      if (JxlDecoderSetInput (decoder, memory, inputFileSize) != JXL_DEC_SUCCESS)
+        {
+          g_printerr ("%s: JxlDecoderSetInput failed after JxlDecoderRewind\n", G_STRFUNC);
+        }
+      else
+        {
+          JxlDecoderCloseInput (decoder);
+          if (JxlDecoderSubscribeEvents (decoder, JXL_DEC_BOX) != JXL_DEC_SUCCESS)
+            {
+              g_printerr ("%s: JxlDecoderSubscribeEvents for JXL_DEC_BOX failed\n", G_STRFUNC);
+            }
+          else
+            {
+              gboolean    search_exif  = TRUE;
+              gboolean    search_xmp   = TRUE;
+              gboolean    success_exif = FALSE;
+              gboolean    success_xmp  = FALSE;
+              JxlBoxType  box_type     = { 0, 0, 0, 0 };
+              GByteArray *exif_box     = NULL;
+              GByteArray *xml_box      = NULL;
+              size_t      exif_remains = 0;
+              size_t      xml_remains  = 0;
+
+              while (search_exif || search_xmp)
+                {
+                  status = JxlDecoderProcessInput (decoder);
+                  switch (status)
+                    {
+                    case JXL_DEC_SUCCESS:
+                      if (box_type[0] == 'E' && box_type[1] == 'x' && box_type[2] == 'i' && box_type[3] == 
'f' && search_exif)
+                        {
+                          exif_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (exif_box, exif_box->len - exif_remains);
+                          success_exif = TRUE;
+                        }
+                      else if (box_type[0] == 'x' && box_type[1] == 'm' && box_type[2] == 'l' && box_type[3] 
== ' ' && search_xmp)
+                        {
+                          xml_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (xml_box, xml_box->len - xml_remains);
+                          success_xmp = TRUE;
+                        }
+
+                      search_exif = FALSE;
+                      search_xmp  = FALSE;
+                      break;
+                    case JXL_DEC_ERROR:
+                      search_exif = FALSE;
+                      search_xmp  = FALSE;
+                      g_printerr ("%s: Metadata decoding error\n", G_STRFUNC);
+                      break;
+                    case JXL_DEC_NEED_MORE_INPUT:
+                      search_exif = FALSE;
+                      search_xmp  = FALSE;
+                      g_printerr ("%s: JXL metadata are probably incomplete\n", G_STRFUNC);
+                      break;
+                    case JXL_DEC_BOX:
+                      JxlDecoderSetDecompressBoxes (decoder, JXL_TRUE);
+
+                      if (box_type[0] == 'E' && box_type[1] == 'x' && box_type[2] == 'i' && box_type[3] == 
'f' && search_exif && exif_box)
+                        {
+                          exif_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (exif_box, exif_box->len - exif_remains);
+
+                          search_exif  = FALSE;
+                          success_exif = TRUE;
+                        }
+                      else if (box_type[0] == 'x' && box_type[1] == 'm' && box_type[2] == 'l' && box_type[3] 
== ' ' && search_xmp && xml_box)
+                        {
+                          xml_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (xml_box, xml_box->len - xml_remains);
+
+                          search_xmp  = FALSE;
+                          success_xmp = TRUE;
+                        }
+
+                      if (JxlDecoderGetBoxType (decoder, box_type, JXL_TRUE) == JXL_DEC_SUCCESS)
+                        {
+                          if (box_type[0] == 'E' && box_type[1] == 'x' && box_type[2] == 'i' && box_type[3] 
== 'f' && search_exif)
+                            {
+                              exif_box = g_byte_array_sized_new (4096);
+                              g_byte_array_set_size (exif_box, 4096);
+
+                              JxlDecoderSetBoxBuffer (decoder, exif_box->data, exif_box->len);
+                            }
+                          else if (box_type[0] == 'x' && box_type[1] == 'm' && box_type[2] == 'l' && 
box_type[3] == ' ' && search_xmp)
+                            {
+                              xml_box = g_byte_array_sized_new (4096);
+                              g_byte_array_set_size (xml_box, 4096);
+
+                              JxlDecoderSetBoxBuffer (decoder, xml_box->data, xml_box->len);
+                            }
+                        }
+                      else
+                        {
+                          search_exif = FALSE;
+                          search_xmp  = FALSE;
+                          g_printerr ("%s: Error in JxlDecoderGetBoxType\n", G_STRFUNC);
+                        }
+                      break;
+                    case JXL_DEC_BOX_NEED_MORE_OUTPUT:
+                      if (box_type[0] == 'E' && box_type[1] == 'x' && box_type[2] == 'i' && box_type[3] == 
'f' && search_exif)
+                        {
+                          exif_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (exif_box, exif_box->len + 4096);
+                          JxlDecoderSetBoxBuffer (decoder, exif_box->data + exif_box->len - (4096 + 
exif_remains), 4096 + exif_remains);
+                        }
+                      else if (box_type[0] == 'x' && box_type[1] == 'm' && box_type[2] == 'l' && box_type[3] 
== ' ' && search_xmp)
+                        {
+                          xml_remains = JxlDecoderReleaseBoxBuffer (decoder);
+                          g_byte_array_set_size (xml_box, xml_box->len + 4096);
+                          JxlDecoderSetBoxBuffer (decoder, xml_box->data + xml_box->len - (4096 + 
xml_remains), 4096 + xml_remains);
+                        }
+                      else
+                        {
+                          search_exif = FALSE;
+                          search_xmp  = FALSE;
+                        }
+                      break;
+                    default:
+                      break;
+                    }
+                }
+
+              if (success_exif || success_xmp)
+                {
+                  GimpMetadata *metadata = gimp_metadata_new ();
+
+                  if (success_exif && exif_box)
+                    {
+                      const guint8  tiffHeaderBE[4] = { 'M', 'M', 0, 42 };
+                      const guint8  tiffHeaderLE[4] = { 'I', 'I', 42, 0 };
+                      const guint8 *tiffheader      = exif_box->data;
+                      glong         new_exif_size   = exif_box->len;
+
+                      while (new_exif_size >= 4) /*Searching for TIFF Header*/
+                        {
+                          if (tiffheader[0] == tiffHeaderBE[0] && tiffheader[1] == tiffHeaderBE[1] &&
+                              tiffheader[2] == tiffHeaderBE[2] && tiffheader[3] == tiffHeaderBE[3])
+                            {
+                              break;
+                            }
+                          if (tiffheader[0] == tiffHeaderLE[0] && tiffheader[1] == tiffHeaderLE[1] &&
+                              tiffheader[2] == tiffHeaderLE[2] && tiffheader[3] == tiffHeaderLE[3])
+                            {
+                              break;
+                            }
+                          new_exif_size--;
+                          tiffheader++;
+                        }
+
+                      if (new_exif_size > 4) /* TIFF header + some data found*/
+                        {
+                          if (! gexiv2_metadata_open_buf (GEXIV2_METADATA (metadata), tiffheader, 
new_exif_size, error))
+                            {
+                              g_printerr ("%s: Failed to set EXIF metadata: %s\n", G_STRFUNC, 
(*error)->message);
+                              g_clear_error (error);
+                            }
+                        }
+                      else
+                        {
+                          g_printerr ("%s: EXIF metadata not set\n", G_STRFUNC);
+                        }
+                    }
+
+                  if (success_xmp && xml_box)
+                    {
+                      if (! gimp_metadata_set_from_xmp (metadata, xml_box->data, xml_box->len, error))
+                        {
+                          g_printerr ("%s: Failed to set XMP metadata: %s\n", G_STRFUNC, (*error)->message);
+                          g_clear_error (error);
+                        }
+                    }
+
+                  gexiv2_metadata_try_set_orientation (GEXIV2_METADATA (metadata),
+                                                       GEXIV2_ORIENTATION_NORMAL, NULL);
+                  gexiv2_metadata_try_set_metadata_pixel_width (GEXIV2_METADATA (metadata),
+                                                                basicinfo.xsize, NULL);
+                  gexiv2_metadata_try_set_metadata_pixel_height (GEXIV2_METADATA (metadata),
+                                                                 basicinfo.ysize, NULL);
+                  gimp_image_metadata_load_finish (image, "image/jxl", metadata,
+                                                   GIMP_METADATA_LOAD_COMMENT | 
GIMP_METADATA_LOAD_RESOLUTION);
+                }
+
+              if (exif_box)
+                {
+                  g_byte_array_free (exif_box, TRUE);
+                }
+
+              if (xml_box)
+                {
+                  g_byte_array_free (xml_box, TRUE);
+                }
+            }
+        }
+    }
+
   JxlThreadParallelRunnerDestroy (runner);
   JxlDecoderDestroy (decoder);
   g_free (memory);
@@ -674,47 +891,49 @@ jpegxl_load (GimpProcedure        *procedure,
   return return_vals;
 }
 
-
 static gboolean
-save_image (GFile                *file,
-            GimpProcedureConfig  *config,
-            GimpImage            *image,
-            GimpDrawable         *drawable,
-            GError              **error)
+save_image (GFile               *file,
+            GimpProcedureConfig *config,
+            GimpImage           *image,
+            GimpDrawable        *drawable,
+            GimpMetadata        *metadata,
+            GError             **error)
 {
-  JxlEncoder        *encoder;
-  void              *runner;
-  JxlEncoderOptions *encoder_options;
-  JxlPixelFormat     pixel_format;
-  JxlBasicInfo       output_info;
-  JxlColorEncoding   color_profile;
-  JxlEncoderStatus   status;
-  size_t             buffer_size;
-
-  GByteArray        *compressed;
-
-  FILE              *outfile;
-  GeglBuffer        *buffer;
-  GimpImageType      drawable_type;
-
-  gint               drawable_width;
-  gint               drawable_height;
-  gpointer           picture_buffer;
-
-  GimpColorProfile  *profile = NULL;
-  const Babl        *file_format = NULL;
-  const Babl        *space = NULL;
-  gboolean           out_linear = FALSE;
-
-  size_t             offset = 0;
-  uint8_t           *next_out;
-  size_t             avail_out;
-
-  gdouble            compression = 1.0;
-  gboolean           lossless = FALSE;
-  gint               speed = 7;
-  gint               bit_depth = 8;
-  gboolean           uses_original_profile = FALSE;
+  JxlEncoder              *encoder;
+  void                    *runner;
+  JxlEncoderFrameSettings *encoder_options;
+  JxlPixelFormat           pixel_format;
+  JxlBasicInfo             output_info;
+  JxlColorEncoding         color_profile;
+  JxlEncoderStatus         status;
+  size_t                   buffer_size;
+
+  GByteArray              *compressed;
+
+  FILE                    *outfile;
+  GeglBuffer              *buffer;
+  GimpImageType            drawable_type;
+
+  gint                     drawable_width;
+  gint                     drawable_height;
+  gpointer                 picture_buffer;
+
+  GimpColorProfile        *profile = NULL;
+  const Babl              *file_format = NULL;
+  const Babl              *space = NULL;
+  gboolean                 out_linear = FALSE;
+
+  size_t                   offset = 0;
+  uint8_t                 *next_out;
+  size_t                   avail_out;
+
+  gdouble                  compression = 1.0;
+  gboolean                 lossless = FALSE;
+  gint                     speed = 7;
+  gint                     bit_depth = 8;
+  gboolean                 uses_original_profile = FALSE;
+  gboolean                 save_exif = FALSE;
+  gboolean                 save_xmp = FALSE;
 
   gimp_progress_init_printf (_("Exporting '%s'"),
                              gimp_file_get_utf8_name (file));
@@ -725,6 +944,8 @@ save_image (GFile                *file,
                 "speed",                 &speed,
                 "save-bit-depth",        &bit_depth,
                 "uses-original-profile", &uses_original_profile,
+                "save-exif",             &save_exif,
+                "save-xmp",              &save_xmp,
                 NULL);
 
   if (lossless)
@@ -792,7 +1013,6 @@ save_image (GFile                *file,
   output_info.xsize = drawable_width;
   output_info.ysize = drawable_height;
   output_info.exponent_bits_per_sample = 0;
-  output_info.intensity_target = 255.0f;
   output_info.orientation = JXL_ORIENT_IDENTITY;
   output_info.animation.tps_numerator = 10;
   output_info.animation.tps_denominator = 1;
@@ -911,6 +1131,22 @@ save_image (GFile                *file,
       return FALSE;
     }
 
+  if ( (output_info.bits_per_sample > 12 && (output_info.uses_original_profile || output_info.alpha_bits > 
12)) || (metadata && (save_exif || save_xmp)))
+    {
+      output_info.have_container = JXL_TRUE;
+      JxlEncoderUseContainer (encoder, JXL_TRUE);
+
+      if (output_info.bits_per_sample > 12 && (output_info.uses_original_profile || output_info.alpha_bits > 
12))
+        {
+          JxlEncoderSetCodestreamLevel (encoder, 10);
+        }
+
+      if (metadata && (save_exif || save_xmp))
+        {
+          JxlEncoderUseBoxes (encoder);
+        }
+    }
+
   runner = JxlThreadParallelRunnerCreate (NULL, gimp_get_num_processors ());
   if (JxlEncoderSetParallelRunner (encoder, JxlThreadParallelRunner, runner) != JXL_ENC_SUCCESS)
     {
@@ -981,23 +1217,23 @@ save_image (GFile                *file,
         }
     }
 
-  encoder_options = JxlEncoderOptionsCreate (encoder, NULL);
+  encoder_options = JxlEncoderFrameSettingsCreate (encoder, NULL);
 
   if (lossless)
     {
-      JxlEncoderOptionsSetDistance (encoder_options, 0);
-      JxlEncoderOptionsSetLossless (encoder_options, JXL_TRUE);
+      JxlEncoderSetFrameDistance (encoder_options, 0);
+      JxlEncoderSetFrameLossless (encoder_options, JXL_TRUE);
     }
   else
     {
-      JxlEncoderOptionsSetDistance (encoder_options, compression);
-      JxlEncoderOptionsSetLossless (encoder_options, JXL_FALSE);
+      JxlEncoderSetFrameDistance (encoder_options, compression);
+      JxlEncoderSetFrameLossless (encoder_options, JXL_FALSE);
     }
 
-  status = JxlEncoderOptionsSetEffort (encoder_options, speed);
+  status = JxlEncoderFrameSettingsSetOption (encoder_options, JXL_ENC_FRAME_SETTING_EFFORT, speed);
   if (status != JXL_ENC_SUCCESS)
     {
-      g_printerr ("JxlEncoderOptionsSetEffort failed to set effort %d", speed);
+      g_printerr ("JxlEncoderFrameSettingsSetOption failed to set effort %d", speed);
     }
 
   gimp_progress_update (0.5);
@@ -1013,6 +1249,104 @@ save_image (GFile                *file,
       return FALSE;
     }
 
+  gimp_progress_update (0.65);
+
+  if (metadata && (save_exif || save_xmp))
+    {
+      GimpMetadata         *filtered_metadata;
+      GimpMetadataSaveFlags metadata_flags = 0;
+
+      if (save_exif)
+        {
+          metadata_flags |= GIMP_METADATA_SAVE_EXIF;
+        }
+
+      if (save_xmp)
+        {
+          metadata_flags |= GIMP_METADATA_SAVE_XMP;
+        }
+
+      filtered_metadata = gimp_image_metadata_save_filter (image, "image/jxl", metadata, metadata_flags, 
NULL, error);
+      if (! filtered_metadata)
+        {
+          if (error && *error)
+            {
+              g_printerr ("%s: error filtering metadata: %s",
+                          G_STRFUNC, (*error)->message);
+              g_clear_error (error);
+            }
+        }
+      else
+        {
+          GExiv2Metadata *filtered_g2metadata = GEXIV2_METADATA (filtered_metadata);
+
+          /*  EXIF metadata  */
+          if (save_exif && gexiv2_metadata_has_exif (filtered_g2metadata))
+            {
+              GBytes *raw_exif_data;
+
+              raw_exif_data = gexiv2_metadata_get_exif_data (filtered_g2metadata, GEXIV2_BYTE_ORDER_LITTLE, 
error);
+              if (raw_exif_data)
+                {
+                  gsize exif_size = 0;
+                  gconstpointer exif_buffer = g_bytes_get_data (raw_exif_data, &exif_size);
+
+                  if (exif_size >= 4)
+                    {
+                      const JxlBoxType exif_box_type = { 'E', 'x', 'i', 'f' };
+                      uint8_t         *content = g_new (uint8_t, exif_size + 4);
+
+                      content[0] = 0;
+                      content[1] = 0;
+                      content[2] = 0;
+                      content[3] = 0;
+                      memcpy (content + 4, exif_buffer, exif_size);
+
+                      if (JxlEncoderAddBox (encoder, exif_box_type, content, exif_size + 4, JXL_FALSE) != 
JXL_ENC_SUCCESS)
+                        {
+                          g_printerr ("%s: Failed to save EXIF metadata.\n", G_STRFUNC);
+                        }
+
+                      g_free (content);
+                    }
+                  g_bytes_unref (raw_exif_data);
+                }
+              else
+                {
+                  if (error && *error)
+                    {
+                      g_printerr ("%s: error preparing EXIF metadata: %s",
+                                  G_STRFUNC, (*error)->message);
+                      g_clear_error (error);
+                    }
+                }
+            }
+
+          /*  XMP metadata  */
+          if (save_xmp && gexiv2_metadata_has_xmp (filtered_g2metadata))
+            {
+              gchar *xmp_packet;
+
+              xmp_packet = gexiv2_metadata_try_generate_xmp_packet (filtered_g2metadata, 
GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0, NULL);
+              if (xmp_packet)
+                {
+                  int xmp_size = strlen (xmp_packet);
+                  if (xmp_size > 0)
+                    {
+                      const JxlBoxType xml_box_type = { 'x', 'm', 'l', ' ' };
+                      if (JxlEncoderAddBox (encoder, xml_box_type, (const uint8_t *) xmp_packet, xmp_size, 
JXL_FALSE) != JXL_ENC_SUCCESS)
+                        {
+                          g_printerr ("%s: Failed to save XMP metadata.\n", G_STRFUNC);
+                        }
+                    }
+                  g_free (xmp_packet);
+                }
+            }
+
+          g_object_unref (filtered_metadata);
+        }
+    }
+
   JxlEncoderCloseInput (encoder);
 
   gimp_progress_update (0.7);
@@ -1139,6 +1473,7 @@ save_dialog (GimpImage     *image,
                               "lossless", "compression",
                               "speed", "save-bit-depth",
                               "uses-original-profile",
+                              "save-exif", "save-xmp",
                               NULL);
 
   run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
@@ -1212,11 +1547,19 @@ jpegxl_save (GimpProcedure        *procedure,
 
   if (status == GIMP_PDB_SUCCESS)
     {
-      if (! save_image (file, config,
-                        image, drawables[0], &error))
+      GimpMetadataSaveFlags metadata_flags;
+
+      GimpMetadata *metadata = gimp_image_metadata_save_prepare (image, "image/jxl", &metadata_flags);
+
+      if (! save_image (file, config, image, drawables[0], metadata, &error))
         {
           status = GIMP_PDB_EXECUTION_ERROR;
         }
+
+      if (metadata)
+        {
+          g_object_unref (metadata);
+        }
     }
 
 
diff --git a/plug-ins/common/meson.build b/plug-ins/common/meson.build
index 07a9e25899..c01ff92f88 100644
--- a/plug-ins/common/meson.build
+++ b/plug-ins/common/meson.build
@@ -107,7 +107,7 @@ endif
 if libjxl.found() and libjxl_threads.found()
   common_plugins_list += {
     'name': 'file-jpegxl',
-    'deps': [ gtk3, gegl, libjxl, libjxl_threads, ],
+    'deps': [ gtk3, gegl, gexiv2, libjxl, libjxl_threads, ],
   }
 endif
 
diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl
index 140fba934c..2d0aaf2f03 100644
--- a/plug-ins/common/plugin-defs.pl
+++ b/plug-ins/common/plugin-defs.pl
@@ -32,7 +32,7 @@
     'file-heif' => { ui => 1, optional => 1, gegl => 1, libdep => 'GEXIV2:LCMS', libs => 'LIBHEIF_LIBS', 
cflags => 'LIBHEIF_CFLAGS' },
     'file-html-table' => { ui => 1, gegl => 1 },
     'file-jp2-load' => { ui => 1, optional => 1, gegl => 1, libs => 'OPENJPEG_LIBS', cflags => 
'OPENJPEG_CFLAGS' },
-    'file-jpegxl' => { ui => 1, optional => 1, gegl => 1, libdep => 'JXL:JXL_THREADS', cflags => 
'JXL_CFLAGS' },
+    'file-jpegxl' => { ui => 1, optional => 1, gegl => 1, libdep => 'GEXIV2:JXL:JXL_THREADS', cflags => 
'JXL_CFLAGS' },
     'file-mng' => { ui => 1, gegl => 1, optional => 1, libs => 'MNG_LIBS', cflags => 'MNG_CFLAGS' },
     'file-pat' => { ui => 1, gegl => 1 },
     'file-pcx' => { ui => 1, gegl => 1 },


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]