/* * Copyright (C) 2005-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #pragma once #include "../AddonBase.h" #include "../c-api/addon-instance/image_decoder.h" #ifdef __cplusplus namespace kodi { namespace addon { //############################################################################## /// @defgroup cpp_kodi_addon_imagedecoder_Defs Definitions, structures and enumerators /// @ingroup cpp_kodi_addon_imagedecoder /// @brief **Image decoder add-on general variables** /// /// Used to exchange the available options between Kodi and addon. /// /// //============================================================================== /// /// @addtogroup cpp_kodi_addon_imagedecoder /// @brief @cpp_class{ kodi::addon::CInstanceImageDecoder } /// **Image decoder add-on instance**\n /// This instance type is used to allow Kodi various additional image format /// types. /// /// This usage can be requested under various conditions, by a Mimetype protocol /// defined in `addon.xml` or supported file extensions. /// /// Include the header @ref ImageDecoder.h "#include " /// to use this class. /// /// ---------------------------------------------------------------------------- /// /// Here is an example of what the `addon.xml.in` would look like for an /// image decoder addon: /// /// ~~~~~~~~~~~~~{.xml} /// /// /// @ADDON_DEPENDS@ /// /// /// My image decoder addon summary /// My image decoder description /// @PLATFORM@ /// /// /// ~~~~~~~~~~~~~ /// /// ### Standard values that can be declared for processing in `addon.xml`. /// /// These values are used by Kodi to identify associated images and file /// extensions and then to select the associated addon. /// /// \table_start /// \table_h3{ Labels, Type, Description } /// \table_row3{ `point`, /// @anchor cpp_kodi_addon_imagedecoder_point /// string, /// The identification of the addon instance to image decoder is mandatory /// `kodi.imagedecoder`. In addition\, the instance declared in the /// first `` is also the main type of addon. /// } /// \table_row3{ `extension`, /// @anchor cpp_kodi_addon_imagedecoder_defaultPort /// string, /// The from addon operated and supported image file endings.\n /// Use a `|` to separate between different ones. /// } /// \table_row3{ `defaultPort`, /// @anchor cpp_kodi_addon_imagedecoder_defaultPort /// string, /// The from addon operated image [mimetypes](https://en.wikipedia.org/wiki/Media_type).\n /// Use a `|` to separate between different ones. /// } /// \table_row3{ `library_@PLATFORM@`, /// @anchor cpp_kodi_addon_imagedecoder_library /// string, /// The runtime library used for the addon. This is usually declared by `cmake` and correctly displayed in the translated `addon.xml`. /// } /// \table_end /// /// @remark For more detailed description of the `addon.xml`, see also https://kodi.wiki/view/Addon.xml. /// /// /// -------------------------------------------------------------------------- /// /// /// **Example:** /// /// ~~~~~~~~~~~~~{.cpp} /// #include /// /// class ATTRIBUTE_HIDDEN CMyImageDecoder : public kodi::addon::CInstanceImageDecoder /// { /// public: /// CMyImageDecoder(KODI_HANDLE instance, const std::string& kodiVersion); /// /// bool LoadImageFromMemory(unsigned char* buffer, /// unsigned int bufSize, /// unsigned int& width, /// unsigned int& height) override; /// /// bool Decode(unsigned char* pixels, /// unsigned int width, /// unsigned int height, /// unsigned int pitch, /// ImageFormat format) override; /// /// ... /// }; /// /// CMyImageDecoder::CMyImageDecoder(KODI_HANDLE instance, const std::string& kodiVersion) /// : CInstanceImageDecoder(instance, kodiVersion) /// { /// ... /// } /// /// bool CMyImageDecoder::LoadImageFromMemory(unsigned char* buffer, /// unsigned int bufSize, /// unsigned int& width, /// unsigned int& height) /// { /// ... /// return true; /// } /// /// bool CMyImageDecoder::Decode(unsigned char* pixels, /// unsigned int width, /// unsigned int height, /// unsigned int pitch, /// ImageFormat format) override; /// { /// ... /// return true; /// } /// /// //---------------------------------------------------------------------- /// /// class ATTRIBUTE_HIDDEN CMyAddon : public kodi::addon::CAddonBase /// { /// public: /// CMyAddon() = default; /// ADDON_STATUS CreateInstance(int instanceType, /// const std::string& instanceID, /// KODI_HANDLE instance, /// const std::string& version, /// KODI_HANDLE& addonInstance) override; /// }; /// /// // If you use only one instance in your add-on, can be instanceType and /// // instanceID ignored /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType, /// const std::string& instanceID, /// KODI_HANDLE instance, /// const std::string& version, /// KODI_HANDLE& addonInstance) /// { /// if (instanceType == ADDON_INSTANCE_IMAGEDECODER) /// { /// kodi::Log(ADDON_LOG_INFO, "Creating my image decoder instance"); /// addonInstance = new CMyImageDecoder(instance, version); /// return ADDON_STATUS_OK; /// } /// else if (...) /// { /// ... /// } /// return ADDON_STATUS_UNKNOWN; /// } /// /// ADDONCREATOR(CMyAddon) /// ~~~~~~~~~~~~~ /// /// The destruction of the example class `CMyImageDecoder` is called from /// Kodi's header. Manually deleting the add-on instance is not required. /// //------------------------------------------------------------------------------ class ATTRIBUTE_HIDDEN CInstanceImageDecoder : public IAddonInstance { public: //============================================================================ /// @ingroup cpp_kodi_addon_imagedecoder /// @brief Class constructor. /// /// @param[in] instance The from Kodi given instance given be add-on /// CreateInstance call with instance id /// @ref ADDON_INSTANCE_IMAGEDECODER. /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to /// allow compatibility to older Kodi versions. /// /// @note Recommended to set `kodiVersion`. /// explicit CInstanceImageDecoder(KODI_HANDLE instance, const std::string& kodiVersion = "") : IAddonInstance(ADDON_INSTANCE_IMAGEDECODER, !kodiVersion.empty() ? kodiVersion : GetKodiTypeVersion(ADDON_INSTANCE_IMAGEDECODER)) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) throw std::logic_error("kodi::addon::CInstanceImageDecoder: Creation of multiple together " "with single instance way is not allowed!"); SetAddonStruct(instance); } //---------------------------------------------------------------------------- ~CInstanceImageDecoder() override = default; //============================================================================ /// @ingroup cpp_kodi_addon_imagedecoder /// @brief Initialize an encoder. /// /// @param[in] buffer The data to read from memory /// @param[in] bufSize The buffer size /// @param[in,out] width The optimal width of image on entry, obtained width /// on return /// @param[in,out] height The optimal height of image, actual obtained height /// on return /// @return true if successful done, false on error /// virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int& width, unsigned int& height) = 0; //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_imagedecoder /// @brief Decode previously loaded image. /// /// @param[in] pixels Output buffer /// @param[in] width Width of output image /// @param[in] height Height of output image /// @param[in] pitch Pitch of output image /// @param[in] format Format of output image /// @return true if successful done, false on error /// virtual bool Decode(unsigned char* pixels, unsigned int width, unsigned int height, unsigned int pitch, ImageFormat format) = 0; //---------------------------------------------------------------------------- //============================================================================ /// @ingroup cpp_kodi_addon_imagedecoder /// @brief **Callback to Kodi Function**\n /// Get the wanted mime type from Kodi. /// /// @return the mimetype wanted from Kodi /// /// @remarks Only called from addon itself. /// inline std::string MimeType() { return m_instanceData->props->mimetype; } //---------------------------------------------------------------------------- private: void SetAddonStruct(KODI_HANDLE instance) { if (instance == nullptr) throw std::logic_error("kodi::addon::CInstanceImageDecoder: Creation with empty addon " "structure not allowed, table must be given from Kodi!"); m_instanceData = static_cast(instance); m_instanceData->toAddon->addonInstance = this; m_instanceData->toAddon->load_image_from_memory = ADDON_LoadImageFromMemory; m_instanceData->toAddon->decode = ADDON_Decode; } inline static bool ADDON_LoadImageFromMemory(const AddonInstance_ImageDecoder* instance, unsigned char* buffer, unsigned int bufSize, unsigned int* width, unsigned int* height) { return static_cast(instance->toAddon->addonInstance) ->LoadImageFromMemory(buffer, bufSize, *width, *height); } inline static bool ADDON_Decode(const AddonInstance_ImageDecoder* instance, unsigned char* pixels, unsigned int width, unsigned int height, unsigned int pitch, enum ImageFormat format) { return static_cast(instance->toAddon->addonInstance) ->Decode(pixels, width, height, pitch, format); } AddonInstance_ImageDecoder* m_instanceData; }; } /* namespace addon */ } /* namespace kodi */ #endif /* __cplusplus */