diff --git a/src/imageformats/heif.cpp b/src/imageformats/heif.cpp index fc80ab3..4b3c8c0 100644 --- a/src/imageformats/heif.cpp +++ b/src/imageformats/heif.cpp @@ -31,6 +31,7 @@ bool HEIFHandler::m_plugins_queried = false; bool HEIFHandler::m_heif_decoder_available = false; bool HEIFHandler::m_heif_encoder_available = false; bool HEIFHandler::m_hej2_decoder_available = false; +bool HEIFHandler::m_hej2_encoder_available = false; bool HEIFHandler::m_avci_decoder_available = false; extern "C" { @@ -154,6 +155,14 @@ bool HEIFHandler::write_helper(const QImage &image) break; } + heif_compression_format encoder_codec = heif_compression_HEVC; +#if LIBHEIF_HAVE_VERSION(1, 13, 0) + if (format() == "hej2") { + encoder_codec = heif_compression_JPEG2000; + save_depth = 8; // for compatibility reasons + } +#endif + heif_chroma chroma; if (save_depth > 8) { if (save_alpha) { @@ -286,7 +295,7 @@ bool HEIFHandler::write_helper(const QImage &image) } struct heif_encoder *encoder = nullptr; - err = heif_context_get_encoder_for_format(context, heif_compression_HEVC, &encoder); + err = heif_context_get_encoder_for_format(context, encoder_codec, &encoder); if (err.code) { qWarning() << "Unable to get an encoder instance:" << err.message; heif_image_release(h_image); @@ -1019,6 +1028,13 @@ bool HEIFHandler::isHej2DecoderAvailable() return m_hej2_decoder_available; } +bool HEIFHandler::isHej2EncoderAvailable() +{ + HEIFHandler::queryHeifLib(); + + return m_hej2_encoder_available; +} + bool HEIFHandler::isAVCIDecoderAvailable() { HEIFHandler::queryHeifLib(); @@ -1041,6 +1057,7 @@ void HEIFHandler::queryHeifLib() m_heif_decoder_available = heif_have_decoder_for_format(heif_compression_HEVC); #if LIBHEIF_HAVE_VERSION(1, 13, 0) m_hej2_decoder_available = heif_have_decoder_for_format(heif_compression_JPEG2000); + m_hej2_encoder_available = heif_have_encoder_for_format(heif_compression_JPEG2000); #endif #if LIBHEIF_HAVE_VERSION(1, 19, 6) m_avci_decoder_available = heif_have_decoder_for_format(heif_compression_AVC); @@ -1109,6 +1126,9 @@ QImageIOPlugin::Capabilities HEIFPlugin::capabilities(QIODevice *device, const Q if (HEIFHandler::isHej2DecoderAvailable()) { format_cap |= CanRead; } + if (HEIFHandler::isHej2EncoderAvailable()) { + format_cap |= CanWrite; + } return format_cap; } @@ -1138,7 +1158,7 @@ QImageIOPlugin::Capabilities HEIFPlugin::capabilities(QIODevice *device, const Q } } - if (device->isWritable() && HEIFHandler::isHeifEncoderAvailable()) { + if (device->isWritable() && (HEIFHandler::isHeifEncoderAvailable() || HEIFHandler::isHej2EncoderAvailable())) { cap |= CanWrite; } return cap; diff --git a/src/imageformats/heif_p.h b/src/imageformats/heif_p.h index 7da12c6..daf41e0 100644 --- a/src/imageformats/heif_p.h +++ b/src/imageformats/heif_p.h @@ -31,6 +31,7 @@ public: static bool isHeifDecoderAvailable(); static bool isHeifEncoderAvailable(); static bool isHej2DecoderAvailable(); + static bool isHej2EncoderAvailable(); static bool isAVCIDecoderAvailable(); static bool isSupportedBMFFType(const QByteArray &header); @@ -62,6 +63,7 @@ private: static bool m_heif_decoder_available; static bool m_heif_encoder_available; static bool m_hej2_decoder_available; + static bool m_hej2_encoder_available; static bool m_avci_decoder_available; static QMutex &getHEIFHandlerMutex();