libheif/pixelimage.h (134 lines of code) (raw):

/* * HEIF codec. * Copyright (c) 2017 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_IMAGE_H #define LIBHEIF_IMAGE_H //#include "heif.h" #include "error.h" #include "nclx.h" #include <vector> #include <memory> #include <map> #include <set> #include <utility> heif_chroma chroma_from_subsampling(int h, int v); bool is_chroma_with_alpha(heif_chroma chroma); int num_interleaved_pixels_per_plane(heif_chroma chroma); bool is_integer_multiple_of_chroma_size(int width, int height, heif_chroma chroma); // Returns the list of valid heif_chroma values for a given colorspace. std::vector<heif_chroma> get_valid_chroma_values_for_colorspace(heif_colorspace colorspace); class HeifPixelImage : public std::enable_shared_from_this<HeifPixelImage>, public ErrorBuffer { public: explicit HeifPixelImage() = default; ~HeifPixelImage(); void create(int width, int height, heif_colorspace colorspace, heif_chroma chroma); bool add_plane(heif_channel channel, int width, int height, int bit_depth); bool add_shared_rgba_plane(heif_channel channel, int width, int height, uint8_t bit_depth); bool has_channel(heif_channel channel) const; // Has alpha information either as a separate channel or in the interleaved format. bool has_alpha() const; bool is_premultiplied_alpha() const { return m_premultiplied_alpha; } void set_premultiplied_alpha(bool flag) { m_premultiplied_alpha = flag; } int get_width() const { return m_width; } int get_height() const { return m_height; } int get_width(enum heif_channel channel) const; int get_height(enum heif_channel channel) const; bool get_image_use_external_buf() const { return image_use_external_buf; } uint8_t * get_image_external_buf_base() const { return image_external_buf_base; } uint32_t get_image_external_buf_len() const { return image_external_buf_len; } uint32_t get_image_external_buf_stride() const { return image_external_buf_stride; } heif_chroma get_chroma_format() const { return m_chroma; } heif_colorspace get_colorspace() const { return m_colorspace; } std::set<enum heif_channel> get_channel_set() const; uint8_t get_storage_bits_per_pixel(enum heif_channel channel) const; uint8_t get_bits_per_pixel(enum heif_channel channel) const; uint8_t* get_plane(enum heif_channel channel, int* out_stride); const uint8_t* get_plane(enum heif_channel channel, int* out_stride) const; void copy_new_plane_from(const std::shared_ptr<const HeifPixelImage>& src_image, heif_channel src_channel, heif_channel dst_channel); void fill_new_plane(heif_channel dst_channel, uint16_t value, int width, int height, int bpp); void transfer_plane_from_image_as(const std::shared_ptr<HeifPixelImage>& source, heif_channel src_channel, heif_channel dst_channel); Error rotate_ccw(int angle_degrees, std::shared_ptr<HeifPixelImage>& out_img); Error mirror_inplace(heif_transform_mirror_direction); Error crop(int left, int right, int top, int bottom, std::shared_ptr<HeifPixelImage>& out_img) const; Error rgba_premultiply_alpha( void ) ; Error fill_RGB_16bit(uint16_t r, uint16_t g, uint16_t b, uint16_t a); Error overlay(std::shared_ptr<HeifPixelImage>& overlay, int32_t dx, int32_t dy); Error scale_nearest_neighbor(std::shared_ptr<HeifPixelImage>& output, int width, int height) const; void set_image_resolution(int width, int height) { m_width = width; m_height = height; } void set_color_profile_nclx(const std::shared_ptr<const color_profile_nclx>& profile) { m_color_profile_nclx = profile; } const std::shared_ptr<const color_profile_nclx>& get_color_profile_nclx() const { return m_color_profile_nclx; } void set_color_profile_icc(const std::shared_ptr<const color_profile_raw>& profile) { m_color_profile_icc = profile; } void set_image_external_info(bool use_buf, void* buf_base, uint32_t buf_len, uint32_t buf_stride) { image_use_external_buf = use_buf ; image_external_buf_base= (uint8_t *)buf_base ; image_external_buf_len = buf_len ; image_external_buf_stride = buf_stride ; } const std::shared_ptr<const color_profile_raw>& get_color_profile_icc() const { return m_color_profile_icc; } void debug_dump() const; bool extend_padding_to_size(int width, int height); // --- pixel aspect ratio bool has_nonsquare_pixel_ratio() const { return m_PixelAspectRatio_h != m_PixelAspectRatio_v; } void get_pixel_ratio(uint32_t* h, uint32_t* v) const { *h = m_PixelAspectRatio_h; *v = m_PixelAspectRatio_v; } void set_pixel_ratio(uint32_t h, uint32_t v) { m_PixelAspectRatio_h = h; m_PixelAspectRatio_v = v; } // --- clli bool has_clli() const { return m_clli.max_content_light_level != 0 || m_clli.max_pic_average_light_level != 0; } heif_content_light_level get_clli() const { return m_clli; } void set_clli(const heif_content_light_level& clli) { m_clli = clli; } // --- mdcv bool has_mdcv() const { return m_mdcv_set; } heif_mastering_display_colour_volume get_mdcv() const { return m_mdcv; } void set_mdcv(const heif_mastering_display_colour_volume& mdcv) { m_mdcv = mdcv; m_mdcv_set = true; } void unset_mdcv() { m_mdcv_set = false; } // --- warnings void add_warning(Error warning) { m_warnings.emplace_back(std::move(warning)); } const std::vector<Error>& get_warnings() const { return m_warnings; } void set_duration_in_Timescales(uint64_t duration) {durationInTimescales = duration;} uint64_t get_duration_in_Timescales() const {return durationInTimescales;} private: struct ImagePlane { bool alloc(int width, int height, int bit_depth, heif_chroma chroma); uint8_t m_bit_depth = 0; // the "visible" area of the plane int m_width = 0; int m_height = 0; // the allocated memory size int m_mem_width = 0; int m_mem_height = 0; uint8_t* mem = nullptr; // aligned memory start uint8_t* allocated_mem = nullptr; // unaligned memory we allocated uint32_t stride = 0; // bytes per line bool plane_use_external_buf = false; }; uint64_t durationInTimescales = 0; int m_width = 0; int m_height = 0; heif_colorspace m_colorspace = heif_colorspace_undefined; heif_chroma m_chroma = heif_chroma_undefined; bool m_premultiplied_alpha = false; std::shared_ptr<const color_profile_nclx> m_color_profile_nclx; std::shared_ptr<const color_profile_raw> m_color_profile_icc; std::map<heif_channel, ImagePlane> m_planes; uint32_t m_PixelAspectRatio_h = 1; uint32_t m_PixelAspectRatio_v = 1; heif_content_light_level m_clli{}; heif_mastering_display_colour_volume m_mdcv{}; bool m_mdcv_set = false; // replace with std::optional<> when we are on C*+17 std::vector<Error> m_warnings; bool image_use_external_buf = false ; // if image_use_external_buf =true, need to free, if image_use_external_buf =false, uint8_t* image_external_buf_base = NULL;// if image_use_external_buf = true, the buf pointed by ext_image_plane keep pixel data; uint32_t image_external_buf_len = 0 ; // if image_use_external_buf = true, the length is the buf memory length uint32_t image_external_buf_stride=0 ; // if image_use_external_buf = true, the stride is the buf memory stride }; #endif