@@ -44,61 +44,53 @@ std::unique_ptr<const unc_encoder> unc_encoder_factory_bytealign_component_inter
4444}
4545
4646
47- void unc_encoder_bytealign_component_interleave::add_channel_if_exists (const std::shared_ptr<const HeifPixelImage>& image, heif_channel channel)
48- {
49- if (image->has_channel (channel)) {
50- m_components.push_back ({channel, heif_channel_to_component_type (channel)});
51- }
52- }
53-
54-
5547unc_encoder_bytealign_component_interleave::unc_encoder_bytealign_component_interleave (const std::shared_ptr<const HeifPixelImage>& image,
5648 const heif_encoding_options& options)
5749{
58- // Special case for heif_channel_Y:
59- // - if this an YCbCr image, use component_type_Y,
60- // - otherwise, use component_type_monochrome
50+ bool is_nonvisual = (image->get_colorspace () == heif_colorspace_nonvisual);
51+ uint32_t num_components = image->get_number_of_components ();
52+
53+ for (uint32_t idx = 0 ; idx < num_components; idx++) {
54+ heif_uncompressed_component_type comp_type;
6155
62- if (image->has_channel (heif_channel_Y)) {
63- if (image->has_channel (heif_channel_Cb) && image->has_channel (heif_channel_Cr)) {
64- m_components.push_back ({heif_channel_Y, heif_uncompressed_component_type::component_type_Y});
56+ if (is_nonvisual) {
57+ comp_type = static_cast <heif_uncompressed_component_type>(image->get_component_type (idx));
6558 }
6659 else {
67- m_components.push_back ({heif_channel_Y, heif_uncompressed_component_type::component_type_monochrome});
60+ heif_channel ch = image->get_component_channel (idx);
61+ if (ch == heif_channel_Y && !image->has_channel (heif_channel_Cb)) {
62+ comp_type = component_type_monochrome;
63+ }
64+ else {
65+ comp_type = heif_channel_to_component_type (ch);
66+ }
6867 }
69- }
7068
71- add_channel_if_exists (image, heif_channel_Cb);
72- add_channel_if_exists (image, heif_channel_Cr);
73- add_channel_if_exists (image, heif_channel_R);
74- add_channel_if_exists (image, heif_channel_G);
75- add_channel_if_exists (image, heif_channel_B);
76- add_channel_if_exists (image, heif_channel_Alpha);
77- add_channel_if_exists (image, heif_channel_filter_array);
78- add_channel_if_exists (image, heif_channel_depth);
79- add_channel_if_exists (image, heif_channel_disparity);
69+ uint8_t bpp = image->get_component_bits_per_pixel (idx);
70+ auto datatype = image->get_component_datatype (idx);
71+ auto comp_format = to_unc_component_format (datatype);
8072
73+ m_components.push_back ({idx, comp_type, comp_format, bpp});
74+ }
8175
82- // if we have any component > 8 bits, we enable this
76+ // Build cmpd/uncC boxes
8377 bool little_endian = false ;
8478
85- uint16_t index = 0 ;
86- for (channel_component channelcomponent : m_components) {
87- m_cmpd->add_component ({channelcomponent.component_type });
88-
89- uint8_t bpp = image->get_bits_per_pixel (channelcomponent.channel );
90- uint8_t component_align_size = static_cast <uint8_t >((bpp + 7 ) / 8 );
79+ uint16_t box_index = 0 ;
80+ for (const auto & comp : m_components) {
81+ m_cmpd->add_component ({comp.component_type });
9182
92- if (bpp % 8 == 0 ) {
83+ uint8_t component_align_size = static_cast <uint8_t >((comp.bpp + 7 ) / 8 );
84+ if (comp.bpp % 8 == 0 ) {
9385 component_align_size = 0 ;
9486 }
9587
96- if (bpp > 8 ) {
97- little_endian = true ; // TODO: depending on the host endianness
88+ if (comp. bpp > 8 ) {
89+ little_endian = true ;
9890 }
9991
100- m_uncC->add_component ({index, bpp, component_format_unsigned , component_align_size});
101- index ++;
92+ m_uncC->add_component ({box_index, comp. bpp , comp. component_format , component_align_size});
93+ box_index ++;
10294 }
10395
10496 m_uncC->set_interleave_type (interleave_mode_component);
@@ -114,19 +106,20 @@ unc_encoder_bytealign_component_interleave::unc_encoder_bytealign_component_inte
114106 m_uncC->set_sampling_type (sampling_mode_no_subsampling);
115107 }
116108
117-
118109 // --- compute bytes per pixel
119110
120111 m_bytes_per_pixel_x4 = 0 ;
121112
122- for (channel_component channelcomponent : m_components) {
123- int bpp = image->get_bits_per_pixel (channelcomponent.channel );
124- int bytes_per_pixel = 4 * (bpp + 7 ) / 8 ;
113+ for (const auto & comp : m_components) {
114+ int bytes_per_pixel = 4 * (comp.bpp + 7 ) / 8 ;
125115
126- if (channelcomponent.channel == heif_channel_Cb ||
127- channelcomponent.channel == heif_channel_Cr) {
128- int downsampling = chroma_h_subsampling (image->get_chroma_format ()) * chroma_v_subsampling (image->get_chroma_format ());
129- bytes_per_pixel /= downsampling;
116+ if (!is_nonvisual) {
117+ heif_channel ch = image->get_component_channel (comp.component_idx );
118+ if (ch == heif_channel_Cb || ch == heif_channel_Cr) {
119+ int downsampling = chroma_h_subsampling (image->get_chroma_format ())
120+ * chroma_v_subsampling (image->get_chroma_format ());
121+ bytes_per_pixel /= downsampling;
122+ }
130123 }
131124
132125 m_bytes_per_pixel_x4 += bytes_per_pixel;
@@ -142,36 +135,37 @@ uint64_t unc_encoder_bytealign_component_interleave::compute_tile_data_size_byte
142135
143136std::vector<uint8_t > unc_encoder_bytealign_component_interleave::encode_tile (const std::shared_ptr<const HeifPixelImage>& src_image) const
144137{
145- std::vector<uint8_t > data;
146-
147138 // compute total size of all components
148139
149140 uint64_t total_size = 0 ;
150141
151- for (channel_component channelcomponent : m_components) {
152- int bpp = src_image-> get_bits_per_pixel (channelcomponent. channel ) ;
153- int bytes_per_pixel = (bpp + 7 ) / 8 ;
154-
155- total_size += static_cast <uint64_t >(src_image-> get_height (channelcomponent. channel )) * src_image-> get_width (channelcomponent. channel ) * bytes_per_pixel;
142+ for (const auto & comp : m_components) {
143+ int bytes_per_pixel = (comp. bpp + 7 ) / 8 ;
144+ uint32_t w = src_image-> get_component_width (comp. component_idx ) ;
145+ uint32_t h = src_image-> get_component_height (comp. component_idx );
146+ total_size += static_cast <uint64_t >(h) * w * bytes_per_pixel;
156147 }
157148
149+ std::vector<uint8_t > data;
158150 data.resize (total_size);
159151
160152 // output all component planes
161153
162154 uint64_t out_data_start_pos = 0 ;
163155
164- for (channel_component channelcomponent : m_components) {
165- int bpp = src_image->get_bits_per_pixel (channelcomponent.channel );
166- int bytes_per_pixel = (bpp + 7 ) / 8 ;
156+ for (const auto & comp : m_components) {
157+ int bytes_per_pixel = (comp.bpp + 7 ) / 8 ;
158+ uint32_t w = src_image->get_component_width (comp.component_idx );
159+ uint32_t h = src_image->get_component_height (comp.component_idx );
167160
168161 size_t src_stride;
169- const uint8_t * src_data = src_image->get_plane (channelcomponent. channel , &src_stride);
162+ const uint8_t * src_data = src_image->get_component (comp. component_idx , &src_stride);
170163
171- for (uint32_t y = 0 ; y < src_image->get_height (channelcomponent.channel ); y++) {
172- uint32_t width = src_image->get_width (channelcomponent.channel );
173- memcpy (data.data () + out_data_start_pos, src_data + src_stride * y, width * bytes_per_pixel);
174- out_data_start_pos += width * bytes_per_pixel;
164+ for (uint32_t y = 0 ; y < h; y++) {
165+ memcpy (data.data () + out_data_start_pos,
166+ src_data + src_stride * y,
167+ w * bytes_per_pixel);
168+ out_data_start_pos += w * bytes_per_pixel;
175169 }
176170 }
177171
0 commit comments