@@ -92,8 +92,20 @@ static void decompress_image(BCdecFormat format, const void *src, void *dst, con
9292void image_decompress_bcdec (Image *p_image) {
9393 uint64_t start_time = OS::get_singleton ()->get_ticks_msec ();
9494
95- int w = p_image->get_width ();
96- int h = p_image->get_height ();
95+ int width = p_image->get_width ();
96+ int height = p_image->get_height ();
97+
98+ // Compressed images' dimensions should be padded to the upper multiple of 4.
99+ // If they aren't, they need to be realigned (the actual data is correctly padded though).
100+ if (width % 4 != 0 || height % 4 != 0 ) {
101+ int new_width = width + (4 - (width % 4 ));
102+ int new_height = height + (4 - (height % 4 ));
103+
104+ print_verbose (vformat (" Compressed image's dimensions are not multiples of 4 (%dx%d), aligning to (%dx%d)" , width, height, new_width, new_height));
105+
106+ width = new_width;
107+ height = new_height;
108+ }
97109
98110 Image::Format source_format = p_image->get_format ();
99111 Image::Format target_format = Image::FORMAT_MAX;
@@ -148,30 +160,27 @@ void image_decompress_bcdec(Image *p_image) {
148160 }
149161
150162 int mm_count = p_image->get_mipmap_count ();
151- int64_t target_size = Image::get_image_data_size (w, h , target_format, p_image->has_mipmaps ());
163+ int64_t target_size = Image::get_image_data_size (width, height , target_format, p_image->has_mipmaps ());
152164
165+ // Decompressed data.
153166 Vector<uint8_t > data;
154167 data.resize (target_size);
168+ uint8_t *wb = data.ptrw ();
155169
170+ // Source data.
156171 const uint8_t *rb = p_image->get_data ().ptr ();
157- uint8_t *wb = data.ptrw ();
158172
159173 // Decompress mipmaps.
160174 for (int i = 0 ; i <= mm_count; i++) {
161- int64_t src_ofs = 0 , mipmap_size = 0 ;
162175 int mipmap_w = 0 , mipmap_h = 0 ;
163- p_image->get_mipmap_offset_size_and_dimensions (i, src_ofs, mipmap_size, mipmap_w, mipmap_h);
164-
165- int64_t dst_ofs = Image::get_image_mipmap_offset (p_image->get_width (), p_image->get_height (), target_format, i);
176+ int64_t src_ofs = Image::get_image_mipmap_offset_and_dimensions (width, height, source_format, i, mipmap_w, mipmap_h);
177+ int64_t dst_ofs = Image::get_image_mipmap_offset (width, height, target_format, i);
166178 decompress_image (bcdec_format, rb + src_ofs, wb + dst_ofs, mipmap_w, mipmap_h);
167-
168- w >>= 1 ;
169- h >>= 1 ;
170179 }
171180
172- p_image->set_data (p_image-> get_width (), p_image-> get_height () , p_image->has_mipmaps (), target_format, data);
181+ p_image->set_data (width, height , p_image->has_mipmaps (), target_format, data);
173182
174- // Swap channels if necessary .
183+ // Swap channels if the format is using a channel swizzle .
175184 if (source_format == Image::FORMAT_DXT5_RA_AS_RG) {
176185 p_image->convert_ra_rgba8_to_rg ();
177186 }
0 commit comments