ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Loading 32 bit BI_BITFIELDS bitmap having non-8-bit channels

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Harald Lampke Posted - Sep 15 2022 : 07:43:52
When loading a 32 bit bitmap with "biCompression = BI_BITFIELDS", and when the bitmask of a channel (including the alpha channel) has more or less than 8 bits set, the resulting colors respectively alpha values are wrong.

To fix this, in module bmpfilt.pas, procedure BMPReadStream, the lines

  rshift := IEGetFirstSetBit(BitFields[0]) - 1;
  gshift := IEGetFirstSetBit(BitFields[1]) - 1;
  bshift := IEGetFirstSetBit(BitFields[2]) - 1;
  ashift := IEGetFirstSetBit(BitFields[3]) - 1;


must be supplemented to

  rshift := IEGetFirstSetBit(BitFields[0]) - 1 + (_GetBitCount(BitFields[0]) - 8);
  gshift := IEGetFirstSetBit(BitFields[1]) - 1 + (_GetBitCount(BitFields[1]) - 8);
  bshift := IEGetFirstSetBit(BitFields[2]) - 1 + (_GetBitCount(BitFields[2]) - 8);
  ashift := IEGetFirstSetBit(BitFields[3]) - 1 + (_GetBitCount(BitFields[3]) - 8);


in order to scale the resulting channel values to the range of [0..255].

Additional, a 32 bit bitmap with "biCompression = BI_BITFIELDS" and a header of type BITMAPINFOHEADER only has three DWORD bitmasks (red, green and blue) and no alpha mask, not four bitmasks (see https://docs.microsoft.com/de-de/previous-versions//dd183376%28v=vs.85%29 ). So the code loading the bitmasks should be

  if xCompression = BI_BITFIELDS then
  begin
    case xBitCount of
      ...
      32: begin
        // red, green and blue masks
        fs.Read(BitFields[0], sizeof(dword) * 3);
        // no alpha mask 
        BitFields[3] := 0;
        IgnoreAlpha := true;
        end; // 32
    end; // case
  end; // if


and in line 1079

  if BitFields[3] = 0 then
    ashift := 0
  else
    ashift := IEGetFirstSetBit(BitFields[3]) - 1 + (_GetBitCount(BitFields[3]) - 8);
3   L A T E S T    R E P L I E S    (Newest First)
xequte Posted - Sep 20 2022 : 21:30:50
Thank you for your code suggestions.

This will be implemented in the next update.

Nigel
Xequte Software
www.imageen.com
Harald Lampke Posted - Sep 16 2022 : 01:52:02
Attached you'll find five 32 bit images: Genuine is 32 bit BI_RGB, and four BI_BITFIELDS encoded images in 7-7-7, 8-8-8, 9-9-9 and 12-11-9, all showing the same subject.

attach/Harald Lampke/202291614916_32 Bit BI_BITFIELDS.zip
985.15 KB
xequte Posted - Sep 15 2022 : 18:09:20
Thanks, I'll have my partner take a look at this. Can you upload/forward your test images?

Nigel
Xequte Software
www.imageen.com