@@ -228,12 +228,36 @@ namespace IMCodec
228228 // Normal color
229229 case 16 :
230230 case 24 :
231+ {
232+ if (VerifyFileSize (reinterpret_cast <const uint8_t *>(buffer), baseSourceAddress, size
233+ , sourceRowPitch * imageItem->descriptor .height ))
234+ {
235+ for (size_t line = 0 ; line < imageItem->descriptor .height ; line++)
236+ {
237+ auto sourceLineOffset = (imageItem->descriptor .height - line - 1 ) * imageItem->descriptor .rowPitchInBytes ;
238+ auto destLineOffset = line * imageItem->descriptor .rowPitchInBytes ;
239+ const auto sourceLineAddress = baseSourceAddress + sourceLineOffset;
240+ auto destLineAddress = reinterpret_cast <uint8_t *>(imageItem->data .data ()) + destLineOffset;
241+ memcpy (destLineAddress, sourceLineAddress, imageItem->descriptor .rowPitchInBytes );
242+ }
243+
244+ out_image = std::make_shared<Image>(imageItem, ImageItemType::Unknown);
245+ result = ImageResult::Success;
246+ }
247+ else
248+ {
249+ result = ImageResult::FileIsCorrupted;
250+ }
251+
252+ break ;
253+ }
231254 case 32 :
232255 {
233256
234257 if (VerifyFileSize (reinterpret_cast <const uint8_t *>(buffer), baseSourceAddress, size
235258 , sourceRowPitch * imageItem->descriptor .height ))
236259 {
260+ uint8_t transparencyOr = 0 ;
237261
238262 for (size_t line = 0 ; line < imageItem->descriptor .height ; line++)
239263 {
@@ -242,23 +266,29 @@ namespace IMCodec
242266 const auto sourceLineAddress = baseSourceAddress + sourceLineOffset;
243267 auto destLineAddress = reinterpret_cast <uint8_t *>(imageItem->data .data ()) + destLineOffset;
244268
245- if (bmpInfo. biBitCount == 32 )
269+ for ( size_t x = 0 ; x < imageItem-> descriptor . width ; x += 1 )
246270 {
247- // If it's a 32 bit bitmap, override alpha channel with full opacity.
248- // some application write just zeros to the alpha channel of 32 bit bitmaps.
271+ using color32 = std::array<uint8_t , 4 >;
272+ reinterpret_cast <color32*>(destLineAddress)[x] = reinterpret_cast <const color32*>(sourceLineAddress)[x];
273+ transparencyOr |= reinterpret_cast <color32*>(destLineAddress)[x][3 ];
274+ }
275+ }
276+
277+ // If it's a 32 bit bitmap and all alpha values are '0' , inject alpha 255
278+ // Since some application write just zeros to the alpha channel of 32 bit bitmaps.
279+ if (transparencyOr == 0 )
280+ {
281+ for (size_t line = 0 ; line < imageItem->descriptor .height ; line++)
282+ {
283+ const auto destLineOffset = line * imageItem->descriptor .rowPitchInBytes ;
284+ const auto destLineAddress = reinterpret_cast <uint8_t *>(imageItem->data .data ()) + destLineOffset;
249285
250286 for (size_t x = 0 ; x < imageItem->descriptor .width ; x += 1 )
251287 {
252288 using color32 = std::array<uint8_t , 4 >;
253- reinterpret_cast <color32*>(destLineAddress)[x] = reinterpret_cast <const color32*>(sourceLineAddress)[x];
254289 reinterpret_cast <color32*>(destLineAddress)[x][3 ] = 255 ;
255290 }
256291 }
257- else
258- {
259- memcpy (destLineAddress, sourceLineAddress, imageItem->descriptor .rowPitchInBytes );
260- }
261-
262292 }
263293 out_image = std::make_shared<Image>(imageItem, ImageItemType::Unknown);
264294 result = ImageResult::Success;
0 commit comments