| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362 |
- /*
- * C++ interface to libheif
- * Copyright (c) 2018 Dirk Farin <dirk.farin@gmail.com>
- *
- * This file is part of libheif.
- *
- * libheif is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * libheif is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with libheif. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef LIBHEIF_HEIF_CXX_H
- #define LIBHEIF_HEIF_CXX_H
- #include <memory>
- #include <string>
- #include <vector>
- #include <cassert>
- extern "C" {
- #include <libheif/heif.h>
- }
- namespace heif {
- class Error
- {
- public:
- Error()
- {
- m_code = heif_error_Ok;
- m_subcode = heif_suberror_Unspecified;
- m_message = "Ok";
- }
- Error(const heif_error& err)
- {
- assert(err.message);
- m_code = err.code;
- m_subcode = err.subcode;
- m_message = err.message;
- }
- Error(heif_error_code code, heif_suberror_code subcode, const std::string& msg)
- {
- m_code = code;
- m_subcode = subcode;
- m_message = msg;
- }
- const std::string& get_message() const
- { return m_message; }
- heif_error_code get_code() const
- { return m_code; }
- heif_suberror_code get_subcode() const
- { return m_subcode; }
- operator bool() const
- { return m_code != heif_error_Ok; }
- private:
- heif_error_code m_code;
- heif_suberror_code m_subcode;
- std::string m_message;
- };
- class ImageHandle;
- class Image;
- class Encoder;
- class EncoderParameter;
- class EncoderDescriptor;
- class Context
- {
- public:
- Context();
- class ReadingOptions
- {
- };
- // throws Error
- void read_from_file(const std::string& filename, const ReadingOptions& opts = ReadingOptions());
- // DEPRECATED. Use read_from_memory_without_copy() instead.
- // throws Error
- void read_from_memory(const void* mem, size_t size, const ReadingOptions& opts = ReadingOptions());
- // throws Error
- void read_from_memory_without_copy(const void* mem, size_t size, const ReadingOptions& opts = ReadingOptions());
- class Reader
- {
- public:
- virtual ~Reader() = default;
- virtual int64_t get_position() const = 0;
- virtual int read(void* data, size_t size) = 0;
- virtual int seek(int64_t position) = 0;
- virtual heif_reader_grow_status wait_for_file_size(int64_t target_size) = 0;
- };
- // throws Error
- void read_from_reader(Reader&, const ReadingOptions& opts = ReadingOptions());
- int get_number_of_top_level_images() const noexcept;
- bool is_top_level_image_ID(heif_item_id id) const noexcept;
- std::vector<heif_item_id> get_list_of_top_level_image_IDs() const noexcept;
- // throws Error
- heif_item_id get_primary_image_ID() const;
- // throws Error
- ImageHandle get_primary_image_handle() const;
- ImageHandle get_image_handle(heif_item_id id) const;
- class EncodingOptions : public heif_encoding_options
- {
- public:
- EncodingOptions();
- };
- // throws Error
- ImageHandle encode_image(const Image& img, Encoder& encoder,
- const EncodingOptions& options = EncodingOptions());
- // throws Error
- void set_primary_image(ImageHandle& new_primary_image_handle);
- // throws Error
- ImageHandle encode_thumbnail(const Image& image,
- const ImageHandle& master_image,
- Encoder& encoder,
- const EncodingOptions&,
- int bbox_size);
- // throws Error
- void assign_thumbnail(const ImageHandle& thumbnail_image,
- const ImageHandle& master_image);
- // throws Error
- void add_exif_metadata(const ImageHandle& master_image,
- const void* data, int size);
- // throws Error
- void add_XMP_metadata(const ImageHandle& master_image,
- const void* data, int size);
- class Writer
- {
- public:
- virtual ~Writer() = default;
- virtual heif_error write(const void* data, size_t size) = 0;
- };
- // throws Error
- void write(Writer&);
- // throws Error
- void write_to_file(const std::string& filename) const;
- private:
- std::shared_ptr<heif_context> m_context;
- friend struct ::heif_error heif_writer_trampoline_write(struct heif_context* ctx,
- const void* data,
- size_t size,
- void* userdata);
- //static Context wrap_without_releasing(heif_context*); // internal use in friend function only
- };
- class ImageHandle
- {
- public:
- ImageHandle() = default;
- ImageHandle(heif_image_handle* handle);
- bool empty() const noexcept
- { return !m_image_handle; }
- bool is_primary_image() const noexcept;
- int get_width() const noexcept;
- int get_height() const noexcept;
- bool has_alpha_channel() const noexcept;
- bool is_premultiplied_alpha() const noexcept;
- int get_luma_bits_per_pixel() const noexcept;
- int get_chroma_bits_per_pixel() const noexcept;
- int get_ispe_width() const noexcept;
- int get_ispe_height() const noexcept;
- // ------------------------- depth images -------------------------
- // TODO
- // ------------------------- thumbnails -------------------------
- int get_number_of_thumbnails() const noexcept;
- std::vector<heif_item_id> get_list_of_thumbnail_IDs() const noexcept;
- // throws Error
- ImageHandle get_thumbnail(heif_item_id id);
- // ------------------------- metadata (Exif / XMP) -------------------------
- // Can optionally be filtered by type ("Exif" / "XMP")
- std::vector<heif_item_id> get_list_of_metadata_block_IDs(const char* type_filter = nullptr) const noexcept;
- std::string get_metadata_type(heif_item_id metadata_id) const noexcept;
- std::string get_metadata_content_type(heif_item_id metadata_id) const noexcept;
- // throws error
- std::vector<uint8_t> get_metadata(heif_item_id) const;
- class DecodingOptions
- {
- };
- // throws Error
- Image decode_image(heif_colorspace colorspace, heif_chroma chroma,
- const DecodingOptions& options = DecodingOptions());
- heif_image_handle* get_raw_image_handle() noexcept
- { return m_image_handle.get(); }
- const heif_image_handle* get_raw_image_handle() const noexcept
- { return m_image_handle.get(); }
- private:
- std::shared_ptr<heif_image_handle> m_image_handle;
- };
- class ColorProfile_nclx
- {
- public:
- ColorProfile_nclx();
- ~ColorProfile_nclx();
- heif_color_primaries get_color_primaries() const;
- heif_transfer_characteristics get_transfer_characteristics() const;
- heif_matrix_coefficients get_matrix_coefficients() const;
- bool is_full_range() const;
- void set_color_primaries(heif_color_primaries cp);
- // DEPRECATED: typo in function name. Use set_color_primaries() instead.
- void set_color_primaties(heif_color_primaries cp);
- void set_transfer_characteristics(heif_transfer_characteristics tc);
- void set_matrix_coefficients(heif_matrix_coefficients mc);
- void set_full_range_flag(bool is_full_range);
- private:
- ColorProfile_nclx(heif_color_profile_nclx* nclx)
- { mProfile = nclx; }
- heif_color_profile_nclx* mProfile;
- friend class Image;
- };
- class Image
- {
- public:
- Image() = default;
- Image(heif_image* image);
- // throws Error
- void create(int width, int height,
- enum heif_colorspace colorspace,
- enum heif_chroma chroma);
- // throws Error
- void add_plane(enum heif_channel channel,
- int width, int height, int bit_depth);
- heif_colorspace get_colorspace() const noexcept;
- heif_chroma get_chroma_format() const noexcept;
- int get_width(enum heif_channel channel) const noexcept;
- int get_height(enum heif_channel channel) const noexcept;
- int get_bits_per_pixel(enum heif_channel channel) const noexcept;
- int get_bits_per_pixel_range(enum heif_channel channel) const noexcept;
- bool has_channel(enum heif_channel channel) const noexcept;
- const uint8_t* get_plane(enum heif_channel channel, int* out_stride) const noexcept;
- uint8_t* get_plane(enum heif_channel channel, int* out_stride) noexcept;
- // throws Error
- void set_nclx_color_profile(const ColorProfile_nclx&);
- // throws Error
- ColorProfile_nclx get_nclx_color_profile() const;
- heif_color_profile_type get_color_profile_type() const;
- // throws Error
- std::vector<uint8_t> get_raw_color_profile() const;
- void set_raw_color_profile(heif_color_profile_type type,
- const std::vector<uint8_t>& data);
- bool is_premultiplied_alpha() const noexcept;
- void set_premultiplied_alpha(bool is_premultiplied_alpha) noexcept;
- class ScalingOptions
- {
- };
- // throws Error
- Image scale_image(int width, int height,
- const ScalingOptions& options = ScalingOptions()) const;
- private:
- std::shared_ptr<heif_image> m_image;
- friend class Context;
- };
- class EncoderDescriptor
- {
- public:
- static std::vector<EncoderDescriptor>
- get_encoder_descriptors(enum heif_compression_format format_filter,
- const char* name_filter) noexcept;
- std::string get_name() const noexcept;
- std::string get_id_name() const noexcept;
- enum heif_compression_format get_compression_format() const noexcept;
- // DEPRECATED: typo in function name
- bool supportes_lossy_compression() const noexcept;
- // DEPRECATED: typo in function name
- bool supportes_lossless_compression() const noexcept;
- // throws Error
- Encoder get_encoder() const;
- bool supports_lossy_compression() const noexcept;
- bool supports_lossless_compression() const noexcept;
- private:
- EncoderDescriptor(const struct heif_encoder_descriptor* descr) : m_descriptor(descr)
- {}
- const struct heif_encoder_descriptor* m_descriptor = nullptr;
- };
- class EncoderParameter
- {
- public:
- std::string get_name() const noexcept;
- enum heif_encoder_parameter_type get_type() const noexcept;
- bool is_integer() const noexcept;
- // Returns 'true' if the integer range is limited.
- bool get_valid_integer_range(int& out_minimum, int& out_maximum);
- bool is_boolean() const noexcept;
- bool is_string() const noexcept;
- std::vector<std::string> get_valid_string_values() const;
- private:
- EncoderParameter(const heif_encoder_parameter*);
- const struct heif_encoder_parameter* m_parameter;
- friend class Encoder;
- };
- class Encoder
- {
- public:
- // throws Error
- Encoder(enum heif_compression_format format);
- // throws Error
- void set_lossy_quality(int quality);
- // throws Error
- void set_lossless(bool enable_lossless);
- std::vector<EncoderParameter> list_parameters() const noexcept;
- void set_integer_parameter(const std::string& parameter_name, int value);
- int get_integer_parameter(const std::string& parameter_name) const;
- void set_boolean_parameter(const std::string& parameter_name, bool value);
- bool get_boolean_parameter(const std::string& parameter_name) const;
- void set_string_parameter(const std::string& parameter_name, const std::string& value);
- std::string get_string_parameter(const std::string& parameter_name) const;
- void set_parameter(const std::string& parameter_name, const std::string& parameter_value);
- std::string get_parameter(const std::string& parameter_name) const;
- private:
- Encoder(struct heif_encoder*) noexcept;
- std::shared_ptr<heif_encoder> m_encoder;
- friend class EncoderDescriptor;
- friend class Context;
- };
- // ==========================================================================================
- // IMPLEMENTATION
- // ==========================================================================================
- inline Context::Context()
- {
- heif_context* ctx = heif_context_alloc();
- m_context = std::shared_ptr<heif_context>(ctx,
- [](heif_context* c) { heif_context_free(c); });
- }
- inline void Context::read_from_file(const std::string& filename, const ReadingOptions& /*opts*/)
- {
- Error err = Error(heif_context_read_from_file(m_context.get(), filename.c_str(), NULL));
- if (err) {
- throw err;
- }
- }
- inline void Context::read_from_memory(const void* mem, size_t size, const ReadingOptions& /*opts*/)
- {
- Error err = Error(heif_context_read_from_memory(m_context.get(), mem, size, NULL));
- if (err) {
- throw err;
- }
- }
- inline void Context::read_from_memory_without_copy(const void* mem, size_t size, const ReadingOptions& /*opts*/)
- {
- Error err = Error(heif_context_read_from_memory_without_copy(m_context.get(), mem, size, NULL));
- if (err) {
- throw err;
- }
- }
- inline int64_t heif_reader_trampoline_get_position(void* userdata)
- {
- Context::Reader* reader = (Context::Reader*) userdata;
- return reader->get_position();
- }
- inline int heif_reader_trampoline_read(void* data, size_t size, void* userdata)
- {
- Context::Reader* reader = (Context::Reader*) userdata;
- return reader->read(data, size);
- }
- inline int heif_reader_trampoline_seek(int64_t position, void* userdata)
- {
- Context::Reader* reader = (Context::Reader*) userdata;
- return reader->seek(position);
- }
- inline heif_reader_grow_status heif_reader_trampoline_wait_for_file_size(int64_t target_size, void* userdata)
- {
- Context::Reader* reader = (Context::Reader*) userdata;
- return reader->wait_for_file_size(target_size);
- }
- static struct heif_reader heif_reader_trampoline =
- {
- 1,
- heif_reader_trampoline_get_position,
- heif_reader_trampoline_read,
- heif_reader_trampoline_seek,
- heif_reader_trampoline_wait_for_file_size
- };
- inline void Context::read_from_reader(Reader& reader, const ReadingOptions& /*opts*/)
- {
- Error err = Error(heif_context_read_from_reader(m_context.get(), &heif_reader_trampoline,
- &reader, NULL));
- if (err) {
- throw err;
- }
- }
- inline int Context::get_number_of_top_level_images() const noexcept
- {
- return heif_context_get_number_of_top_level_images(m_context.get());
- }
- inline bool Context::is_top_level_image_ID(heif_item_id id) const noexcept
- {
- return heif_context_is_top_level_image_ID(m_context.get(), id);
- }
- inline std::vector<heif_item_id> Context::get_list_of_top_level_image_IDs() const noexcept
- {
- int num = get_number_of_top_level_images();
- std::vector<heif_item_id> IDs(num);
- heif_context_get_list_of_top_level_image_IDs(m_context.get(), IDs.data(), num);
- return IDs;
- }
- inline heif_item_id Context::get_primary_image_ID() const
- {
- heif_item_id id;
- Error err = Error(heif_context_get_primary_image_ID(m_context.get(), &id));
- if (err) {
- throw err;
- }
- return id;
- }
- inline ImageHandle Context::get_primary_image_handle() const
- {
- heif_image_handle* handle;
- Error err = Error(heif_context_get_primary_image_handle(m_context.get(), &handle));
- if (err) {
- throw err;
- }
- return ImageHandle(handle);
- }
- inline ImageHandle Context::get_image_handle(heif_item_id id) const
- {
- struct heif_image_handle* handle;
- Error err = Error(heif_context_get_image_handle(m_context.get(), id, &handle));
- if (err) {
- throw err;
- }
- return ImageHandle(handle);
- }
- #if 0
- inline Context Context::wrap_without_releasing(heif_context* ctx) {
- Context context;
- context.m_context = std::shared_ptr<heif_context>(ctx,
- [] (heif_context*) { /* NOP */ });
- return context;
- }
- #endif
- inline struct ::heif_error heif_writer_trampoline_write(struct heif_context* ctx,
- const void* data,
- size_t size,
- void* userdata)
- {
- Context::Writer* writer = (Context::Writer*) userdata;
- (void) ctx;
- //Context context = Context::wrap_without_releasing(ctx);
- //return writer->write(context, data, size);
- return writer->write(data, size);
- }
- static struct heif_writer heif_writer_trampoline =
- {
- 1,
- &heif_writer_trampoline_write
- };
- inline void Context::write(Writer& writer)
- {
- Error err = Error(heif_context_write(m_context.get(), &heif_writer_trampoline, &writer));
- if (err) {
- throw err;
- }
- }
- inline void Context::write_to_file(const std::string& filename) const
- {
- Error err = Error(heif_context_write_to_file(m_context.get(), filename.c_str()));
- if (err) {
- throw err;
- }
- }
- inline ImageHandle::ImageHandle(heif_image_handle* handle)
- {
- if (handle != nullptr) {
- m_image_handle = std::shared_ptr<heif_image_handle>(handle,
- [](heif_image_handle* h) { heif_image_handle_release(h); });
- }
- }
- inline bool ImageHandle::is_primary_image() const noexcept
- {
- return heif_image_handle_is_primary_image(m_image_handle.get()) != 0;
- }
- inline int ImageHandle::get_width() const noexcept
- {
- return heif_image_handle_get_width(m_image_handle.get());
- }
- inline int ImageHandle::get_height() const noexcept
- {
- return heif_image_handle_get_height(m_image_handle.get());
- }
- inline bool ImageHandle::has_alpha_channel() const noexcept
- {
- return heif_image_handle_has_alpha_channel(m_image_handle.get()) != 0;
- }
- inline bool ImageHandle::is_premultiplied_alpha() const noexcept
- {
- return heif_image_handle_is_premultiplied_alpha(m_image_handle.get()) != 0;
- }
- inline int ImageHandle::get_luma_bits_per_pixel() const noexcept
- {
- return heif_image_handle_get_luma_bits_per_pixel(m_image_handle.get());
- }
- inline int ImageHandle::get_chroma_bits_per_pixel() const noexcept
- {
- return heif_image_handle_get_chroma_bits_per_pixel(m_image_handle.get());
- }
- inline int ImageHandle::get_ispe_width() const noexcept
- {
- return heif_image_handle_get_ispe_width(m_image_handle.get());
- }
- inline int ImageHandle::get_ispe_height() const noexcept
- {
- return heif_image_handle_get_ispe_height(m_image_handle.get());
- }
- // ------------------------- depth images -------------------------
- // TODO
- // ------------------------- thumbnails -------------------------
- inline int ImageHandle::get_number_of_thumbnails() const noexcept
- {
- return heif_image_handle_get_number_of_thumbnails(m_image_handle.get());
- }
- inline std::vector<heif_item_id> ImageHandle::get_list_of_thumbnail_IDs() const noexcept
- {
- int num = get_number_of_thumbnails();
- std::vector<heif_item_id> IDs(num);
- heif_image_handle_get_list_of_thumbnail_IDs(m_image_handle.get(), IDs.data(), num);
- return IDs;
- }
- inline ImageHandle ImageHandle::get_thumbnail(heif_item_id id)
- {
- heif_image_handle* handle;
- Error err = Error(heif_image_handle_get_thumbnail(m_image_handle.get(), id, &handle));
- if (err) {
- throw err;
- }
- return ImageHandle(handle);
- }
- inline Image ImageHandle::decode_image(heif_colorspace colorspace, heif_chroma chroma,
- const DecodingOptions& /*options*/)
- {
- heif_image* out_img;
- Error err = Error(heif_decode_image(m_image_handle.get(),
- &out_img,
- colorspace,
- chroma,
- nullptr)); //const struct heif_decoding_options* options);
- if (err) {
- throw err;
- }
- return Image(out_img);
- }
- inline std::vector<heif_item_id> ImageHandle::get_list_of_metadata_block_IDs(const char* type_filter) const noexcept
- {
- int nBlocks = heif_image_handle_get_number_of_metadata_blocks(m_image_handle.get(),
- type_filter);
- std::vector<heif_item_id> ids(nBlocks);
- int n = heif_image_handle_get_list_of_metadata_block_IDs(m_image_handle.get(),
- type_filter,
- ids.data(), nBlocks);
- (void) n;
- //assert(n==nBlocks);
- return ids;
- }
- inline std::string ImageHandle::get_metadata_type(heif_item_id metadata_id) const noexcept
- {
- return heif_image_handle_get_metadata_type(m_image_handle.get(), metadata_id);
- }
- inline std::string ImageHandle::get_metadata_content_type(heif_item_id metadata_id) const noexcept
- {
- return heif_image_handle_get_metadata_content_type(m_image_handle.get(), metadata_id);
- }
- inline std::vector<uint8_t> ImageHandle::get_metadata(heif_item_id metadata_id) const
- {
- size_t data_size = heif_image_handle_get_metadata_size(m_image_handle.get(),
- metadata_id);
- std::vector<uint8_t> data(data_size);
- Error err = Error(heif_image_handle_get_metadata(m_image_handle.get(),
- metadata_id,
- data.data()));
- if (err) {
- throw err;
- }
- return data;
- }
- inline ColorProfile_nclx::ColorProfile_nclx()
- {
- mProfile = heif_nclx_color_profile_alloc();
- }
- inline ColorProfile_nclx::~ColorProfile_nclx()
- {
- heif_nclx_color_profile_free(mProfile);
- }
- inline heif_color_primaries ColorProfile_nclx::get_color_primaries() const
- { return mProfile->color_primaries; }
- inline heif_transfer_characteristics ColorProfile_nclx::get_transfer_characteristics() const
- { return mProfile->transfer_characteristics; }
- inline heif_matrix_coefficients ColorProfile_nclx::get_matrix_coefficients() const
- { return mProfile->matrix_coefficients; }
- inline bool ColorProfile_nclx::is_full_range() const
- { return mProfile->full_range_flag; }
- inline void ColorProfile_nclx::set_color_primaries(heif_color_primaries cp)
- { mProfile->color_primaries = cp; }
- inline void ColorProfile_nclx::set_color_primaties(heif_color_primaries cp)
- { set_color_primaries(cp); }
- inline void ColorProfile_nclx::set_transfer_characteristics(heif_transfer_characteristics tc)
- { mProfile->transfer_characteristics = tc; }
- inline void ColorProfile_nclx::set_matrix_coefficients(heif_matrix_coefficients mc)
- { mProfile->matrix_coefficients = mc; }
- inline void ColorProfile_nclx::set_full_range_flag(bool is_full_range)
- { mProfile->full_range_flag = is_full_range; }
- inline Image::Image(heif_image* image)
- {
- m_image = std::shared_ptr<heif_image>(image,
- [](heif_image* h) { heif_image_release(h); });
- }
- inline void Image::create(int width, int height,
- enum heif_colorspace colorspace,
- enum heif_chroma chroma)
- {
- heif_image* image;
- Error err = Error(heif_image_create(width, height, colorspace, chroma, &image));
- if (err) {
- m_image.reset();
- throw err;
- }
- else {
- m_image = std::shared_ptr<heif_image>(image,
- [](heif_image* h) { heif_image_release(h); });
- }
- }
- inline void Image::add_plane(enum heif_channel channel,
- int width, int height, int bit_depth)
- {
- Error err = Error(heif_image_add_plane(m_image.get(), channel, width, height, bit_depth));
- if (err) {
- throw err;
- }
- }
- inline heif_colorspace Image::get_colorspace() const noexcept
- {
- return heif_image_get_colorspace(m_image.get());
- }
- inline heif_chroma Image::get_chroma_format() const noexcept
- {
- return heif_image_get_chroma_format(m_image.get());
- }
- inline int Image::get_width(enum heif_channel channel) const noexcept
- {
- return heif_image_get_width(m_image.get(), channel);
- }
- inline int Image::get_height(enum heif_channel channel) const noexcept
- {
- return heif_image_get_height(m_image.get(), channel);
- }
- inline int Image::get_bits_per_pixel(enum heif_channel channel) const noexcept
- {
- return heif_image_get_bits_per_pixel(m_image.get(), channel);
- }
- inline int Image::get_bits_per_pixel_range(enum heif_channel channel) const noexcept
- {
- return heif_image_get_bits_per_pixel_range(m_image.get(), channel);
- }
- inline bool Image::has_channel(enum heif_channel channel) const noexcept
- {
- return heif_image_has_channel(m_image.get(), channel);
- }
- inline const uint8_t* Image::get_plane(enum heif_channel channel, int* out_stride) const noexcept
- {
- return heif_image_get_plane_readonly(m_image.get(), channel, out_stride);
- }
- inline uint8_t* Image::get_plane(enum heif_channel channel, int* out_stride) noexcept
- {
- return heif_image_get_plane(m_image.get(), channel, out_stride);
- }
- inline void Image::set_nclx_color_profile(const ColorProfile_nclx& nclx)
- {
- Error err = Error(heif_image_set_nclx_color_profile(m_image.get(), nclx.mProfile));
- if (err) {
- throw err;
- }
- }
- // throws Error
- inline ColorProfile_nclx Image::get_nclx_color_profile() const
- {
- heif_color_profile_nclx* nclx = nullptr;
- Error err = Error(heif_image_get_nclx_color_profile(m_image.get(), &nclx));
- if (err) {
- throw err;
- }
- return ColorProfile_nclx(nclx);
- }
- inline heif_color_profile_type Image::get_color_profile_type() const
- {
- return heif_image_get_color_profile_type(m_image.get());
- }
- // throws Error
- inline std::vector<uint8_t> Image::get_raw_color_profile() const
- {
- auto size = heif_image_get_raw_color_profile_size(m_image.get());
- std::vector<uint8_t> profile(size);
- heif_image_get_raw_color_profile(m_image.get(), profile.data());
- return profile;
- }
- inline void Image::set_raw_color_profile(heif_color_profile_type type,
- const std::vector<uint8_t>& data)
- {
- const char* profile_type = nullptr;
- switch (type) {
- case heif_color_profile_type_prof:
- profile_type = "prof";
- break;
- case heif_color_profile_type_rICC:
- profile_type = "rICC";
- break;
- default:
- throw Error(heif_error_code::heif_error_Usage_error,
- heif_suberror_Unspecified,
- "invalid raw color profile type");
- break;
- }
- Error err = Error(heif_image_set_raw_color_profile(m_image.get(), profile_type,
- data.data(), data.size()));
- if (err) {
- throw err;
- }
- }
- inline bool Image::is_premultiplied_alpha() const noexcept
- {
- return heif_image_is_premultiplied_alpha(m_image.get()) != 0;
- }
- inline void Image::set_premultiplied_alpha(bool is_premultiplied_alpha) noexcept
- {
- heif_image_set_premultiplied_alpha(m_image.get(), is_premultiplied_alpha);
- }
- inline Image Image::scale_image(int width, int height,
- const ScalingOptions&) const
- {
- heif_image* img;
- Error err = Error(heif_image_scale_image(m_image.get(), &img, width, height,
- nullptr)); // TODO: scaling options not defined yet
- if (err) {
- throw err;
- }
- return Image(img);
- }
- inline std::vector<EncoderDescriptor>
- EncoderDescriptor::get_encoder_descriptors(enum heif_compression_format format_filter,
- const char* name_filter) noexcept
- {
- int maxDescriptors = 10;
- int nDescriptors;
- for (;;) {
- const struct heif_encoder_descriptor** descriptors;
- descriptors = new const heif_encoder_descriptor* [maxDescriptors];
- nDescriptors = heif_context_get_encoder_descriptors(nullptr,
- format_filter,
- name_filter,
- descriptors,
- maxDescriptors);
- if (nDescriptors < maxDescriptors) {
- std::vector<EncoderDescriptor> outDescriptors;
- outDescriptors.reserve(nDescriptors);
- for (int i = 0; i < nDescriptors; i++) {
- outDescriptors.push_back(EncoderDescriptor(descriptors[i]));
- }
- delete[] descriptors;
- return outDescriptors;
- }
- else {
- delete[] descriptors;
- maxDescriptors *= 2;
- }
- }
- }
- inline std::string EncoderDescriptor::get_name() const noexcept
- {
- return heif_encoder_descriptor_get_name(m_descriptor);
- }
- inline std::string EncoderDescriptor::get_id_name() const noexcept
- {
- return heif_encoder_descriptor_get_id_name(m_descriptor);
- }
- inline enum heif_compression_format EncoderDescriptor::get_compression_format() const noexcept
- {
- return heif_encoder_descriptor_get_compression_format(m_descriptor);
- }
- inline bool EncoderDescriptor::supportes_lossy_compression() const noexcept
- {
- return heif_encoder_descriptor_supports_lossy_compression(m_descriptor);
- }
- inline bool EncoderDescriptor::supports_lossy_compression() const noexcept
- {
- return heif_encoder_descriptor_supports_lossy_compression(m_descriptor);
- }
- inline bool EncoderDescriptor::supportes_lossless_compression() const noexcept
- {
- return heif_encoder_descriptor_supports_lossless_compression(m_descriptor);
- }
- inline bool EncoderDescriptor::supports_lossless_compression() const noexcept
- {
- return heif_encoder_descriptor_supports_lossless_compression(m_descriptor);
- }
- inline Encoder EncoderDescriptor::get_encoder() const
- {
- heif_encoder* encoder;
- Error err = Error(heif_context_get_encoder(nullptr, m_descriptor, &encoder));
- if (err) {
- throw err;
- }
- return Encoder(encoder);
- }
- inline Encoder::Encoder(enum heif_compression_format format)
- {
- heif_encoder* encoder;
- Error err = Error(heif_context_get_encoder_for_format(nullptr, format, &encoder));
- if (err) {
- throw err;
- }
- m_encoder = std::shared_ptr<heif_encoder>(encoder,
- [](heif_encoder* e) { heif_encoder_release(e); });
- }
- inline Encoder::Encoder(struct heif_encoder* encoder) noexcept
- {
- m_encoder = std::shared_ptr<heif_encoder>(encoder,
- [](heif_encoder* e) { heif_encoder_release(e); });
- }
- inline EncoderParameter::EncoderParameter(const heif_encoder_parameter* param)
- : m_parameter(param)
- {
- }
- inline std::string EncoderParameter::get_name() const noexcept
- {
- return heif_encoder_parameter_get_name(m_parameter);
- }
- inline enum heif_encoder_parameter_type EncoderParameter::get_type() const noexcept
- {
- return heif_encoder_parameter_get_type(m_parameter);
- }
- inline bool EncoderParameter::is_integer() const noexcept
- {
- return get_type() == heif_encoder_parameter_type_integer;
- }
- inline bool EncoderParameter::get_valid_integer_range(int& out_minimum, int& out_maximum)
- {
- int have_minimum_maximum;
- Error err = Error(heif_encoder_parameter_get_valid_integer_range(m_parameter,
- &have_minimum_maximum,
- &out_minimum, &out_maximum));
- if (err) {
- throw err;
- }
- return have_minimum_maximum;
- }
- inline bool EncoderParameter::is_boolean() const noexcept
- {
- return get_type() == heif_encoder_parameter_type_boolean;
- }
- inline bool EncoderParameter::is_string() const noexcept
- {
- return get_type() == heif_encoder_parameter_type_string;
- }
- inline std::vector<std::string> EncoderParameter::get_valid_string_values() const
- {
- const char* const* stringarray;
- Error err = Error(heif_encoder_parameter_get_valid_string_values(m_parameter,
- &stringarray));
- if (err) {
- throw err;
- }
- std::vector<std::string> values;
- for (int i = 0; stringarray[i]; i++) {
- values.push_back(stringarray[i]);
- }
- return values;
- }
- inline std::vector<EncoderParameter> Encoder::list_parameters() const noexcept
- {
- std::vector<EncoderParameter> parameters;
- for (const struct heif_encoder_parameter* const* params = heif_encoder_list_parameters(m_encoder.get());
- *params;
- params++) {
- parameters.push_back(EncoderParameter(*params));
- }
- return parameters;
- }
- inline void Encoder::set_lossy_quality(int quality)
- {
- Error err = Error(heif_encoder_set_lossy_quality(m_encoder.get(), quality));
- if (err) {
- throw err;
- }
- }
- inline void Encoder::set_lossless(bool enable_lossless)
- {
- Error err = Error(heif_encoder_set_lossless(m_encoder.get(), enable_lossless));
- if (err) {
- throw err;
- }
- }
- inline void Encoder::set_integer_parameter(const std::string& parameter_name, int value)
- {
- Error err = Error(heif_encoder_set_parameter_integer(m_encoder.get(), parameter_name.c_str(), value));
- if (err) {
- throw err;
- }
- }
- inline int Encoder::get_integer_parameter(const std::string& parameter_name) const
- {
- int value;
- Error err = Error(heif_encoder_get_parameter_integer(m_encoder.get(), parameter_name.c_str(), &value));
- if (err) {
- throw err;
- }
- return value;
- }
- inline void Encoder::set_boolean_parameter(const std::string& parameter_name, bool value)
- {
- Error err = Error(heif_encoder_set_parameter_boolean(m_encoder.get(), parameter_name.c_str(), value));
- if (err) {
- throw err;
- }
- }
- inline bool Encoder::get_boolean_parameter(const std::string& parameter_name) const
- {
- int value;
- Error err = Error(heif_encoder_get_parameter_boolean(m_encoder.get(), parameter_name.c_str(), &value));
- if (err) {
- throw err;
- }
- return value;
- }
- inline void Encoder::set_string_parameter(const std::string& parameter_name, const std::string& value)
- {
- Error err = Error(heif_encoder_set_parameter_string(m_encoder.get(), parameter_name.c_str(), value.c_str()));
- if (err) {
- throw err;
- }
- }
- inline std::string Encoder::get_string_parameter(const std::string& parameter_name) const
- {
- const int max_size = 250;
- char value[max_size];
- Error err = Error(heif_encoder_get_parameter_string(m_encoder.get(), parameter_name.c_str(),
- value, max_size));
- if (err) {
- throw err;
- }
- return value;
- }
- inline void Encoder::set_parameter(const std::string& parameter_name, const std::string& parameter_value)
- {
- Error err = Error(heif_encoder_set_parameter(m_encoder.get(), parameter_name.c_str(),
- parameter_value.c_str()));
- if (err) {
- throw err;
- }
- }
- inline std::string Encoder::get_parameter(const std::string& parameter_name) const
- {
- const int max_size = 250;
- char value[max_size];
- Error err = Error(heif_encoder_get_parameter(m_encoder.get(), parameter_name.c_str(),
- value, max_size));
- if (err) {
- throw err;
- }
- return value;
- }
- inline void Context::set_primary_image(ImageHandle& new_primary_image_handle)
- {
- Error err = Error(heif_context_set_primary_image(m_context.get(),
- new_primary_image_handle.get_raw_image_handle()));
- if (err) {
- throw err;
- }
- }
- inline Context::EncodingOptions::EncodingOptions()
- {
- // TODO: this is a bit hacky. It would be better to have an API function to set
- // the options to default values. But I do not see any reason for that apart from
- // this use-case.
- struct heif_encoding_options* default_options = heif_encoding_options_alloc();
- *static_cast<heif_encoding_options*>(this) = *default_options; // copy over all options
- heif_encoding_options_free(default_options);
- }
- inline ImageHandle Context::encode_image(const Image& img, Encoder& encoder,
- const EncodingOptions& options)
- {
- struct heif_image_handle* image_handle;
- Error err = Error(heif_context_encode_image(m_context.get(),
- img.m_image.get(),
- encoder.m_encoder.get(),
- &options,
- &image_handle));
- if (err) {
- throw err;
- }
- return ImageHandle(image_handle);
- }
- inline ImageHandle Context::encode_thumbnail(const Image& image,
- const ImageHandle& master_image_handle,
- Encoder& encoder,
- const EncodingOptions& options,
- int bbox_size)
- {
- struct heif_image_handle* thumb_image_handle;
- Error err = Error(heif_context_encode_thumbnail(m_context.get(),
- image.m_image.get(),
- master_image_handle.get_raw_image_handle(),
- encoder.m_encoder.get(),
- &options,
- bbox_size,
- &thumb_image_handle));
- if (err) {
- throw err;
- }
- return ImageHandle(thumb_image_handle);
- }
- inline void Context::assign_thumbnail(const ImageHandle& thumbnail_image,
- const ImageHandle& master_image)
- {
- Error err = Error(heif_context_assign_thumbnail(m_context.get(),
- thumbnail_image.get_raw_image_handle(),
- master_image.get_raw_image_handle()));
- if (err) {
- throw err;
- }
- }
- inline void Context::add_exif_metadata(const ImageHandle& master_image,
- const void* data, int size)
- {
- Error err = Error(heif_context_add_exif_metadata(m_context.get(),
- master_image.get_raw_image_handle(),
- data, size));
- if (err) {
- throw err;
- }
- }
- inline void Context::add_XMP_metadata(const ImageHandle& master_image,
- const void* data, int size)
- {
- Error err = Error(heif_context_add_XMP_metadata(m_context.get(),
- master_image.get_raw_image_handle(),
- data, size));
- if (err) {
- throw err;
- }
- }
- }
- #endif
|