🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.delphi.graphics
14 messages
14 total messages Started by Ian Boyd Thu, 24 Jul 2008 21:18
CreateDIBSection fails with EDivideZero exception
#160
Author: Ian Boyd
Date: Thu, 24 Jul 2008 21:18
63 lines
2690 bytes
function CreateDIBSection_V5(DC: HDC;
  p2: PBitmapV5Header;
  p3: UINT;
  var p4: Pointer;
  p5: THandle; p6: DWORD): HBITMAP; stdcall; external GDI32 name 
'CreateDIBSection';


procedure TForm1.Button1Click(Sender: TObject);
var
     bm: HBITMAP;
     dc: HDC;
     BitmapHeader: TBitmapV5Header;
     pBits: Pointer;
begin
     ZeroMemory(@BitmapHeader, SizeOf(BITMAPV5HEADER));
     BitmapHeader.bV5Size := SizeOf(BITMAPV5HEADER);
     BitmapHeader.bV5Width := 32;
     BitmapHeader.bV5Height := 32;
     BitmapHeader.bV5Planes := 1;
     BitmapHeader.bV5BitCount := 32;
     BitmapHeader.bV5Compression := BI_BITFIELDS;
     BitmapHeader.bV5RedMask   :=  $00FF0000;
     BitmapHeader.bV5GreenMask :=  $0000FF00;
     BitmapHeader.bV5BlueMask  :=  $000000FF;
     BitmapHeader.bV5AlphaMask :=  $FF000000;

     dc := GetDC(0);

     bm := CreateDIBSection_V5(
            dc,
            @BitmapHeader,
            DIB_RGB_COLORS,
            pBits,
            0, 0);
end;


The call to CreateDIBSection throws an EDivideZero exception.

It doesn't fail for others:
  How To Create an Alpha Blended Cursor or Icon in Windows XP
  http://support.microsoft.com/kb/318876

http://www.delphipraxis.net/topic125964.html
http://www.delphipraxis.net/post539759.html

i step into it in the CPU windows, i get into GDI32.CreateDIBSection, i keep 
tracing it down, and i eventually see yes - it's dividing by zero:

gdi32.CreateDIBSection

mscms.CreateProfileFromLogColorSpaceW
73b36089 call -$00000495

ICM32.CMCreateProfileW
55e9433e    fdivr qword ptr [eax]


Which doesn't really help me. Plus i'm sure it's not a bug in 
CreateDIBSection.

But i can't figure it out. 
Re: CreateDIBSection fails with EDivideZero exception
#161
Author: David Ninnes
Date: Thu, 24 Jul 2008 23:34
12 lines
1283 bytes
Works for me,

Vista /D2007

if you've got a bigger sample it would be good, I don't know if the bitmap 
created is valid.

cheers,
Dave

 
Re: CreateDIBSection fails with EDivideZero exception
#162
Author: Ian Boyd
Date: Fri, 25 Jul 2008 02:47
12 lines
1362 bytes
> Works for me,
>
> Vista /D2007
>
> if you've got a bigger sample it would be good, I don't know if the bitmap 
> created is valid.

That's the exact code i can run that fails.

XP/D5

Grrrr. 
Re: CreateDIBSection fails with EDivideZero exception
#164
Author: David Ninnes
Date: Fri, 25 Jul 2008 04:16
21 lines
1591 bytes

"Ian Boyd" <ian.borlandnews008@zunblvlda1.dyndns.org.spamsucks> wrote in 
message news:48893ebb@newsgroups.borland.com...
>> Works for me,
>>
>> Vista /D2007
>>
>> if you've got a bigger sample it would be good, I don't know if the 
>> bitmap created is valid.
>
> That's the exact code i can run that fails.
>
> XP/D5
>
> Grrrr.
maybe the D5 data structure definitions aren't quite right? V5 bitmaps were 
fairly new then I think.

cheers,
Dave 
Re: CreateDIBSection fails with EDivideZero exception
#163
Author: David Ninnes
Date: Fri, 25 Jul 2008 04:34
17 lines
1501 bytes

"Ian Boyd" <ian.borlandnews008@zunblvlda1.dyndns.org.spamsucks> wrote in 
message news:48893ebb@newsgroups.borland.com...
>> Works for me,
>>
>> Vista /D2007
>>
>> if you've got a bigger sample it would be good, I don't know if the 
>> bitmap created is valid.
>
> That's the exact code i can run that fails.
>
> XP/D5
>
> Grrrr.
Nope, fails for me on XP/2007 
Re: CreateDIBSection fails with EDivideZero exception
#165
Author: David Ninnes
Date: Fri, 25 Jul 2008 09:25
105 lines
4222 bytes
"Ian Boyd" <ian.borlandnews008@zunblvlda1.dyndns.org.spamsucks> wrote in 
message news:48893ebb@newsgroups.borland.com...
>> Works for me,
>>
>> Vista /D2007
>>
>> if you've got a bigger sample it would be good, I don't know if the 
>> bitmap created is valid.
>
> That's the exact code i can run that fails.
>
> XP/D5
>
> Grrrr.

It's because you followed the MS docs and did a ZeroMemory, if you'd ignored 
that like everyone else did it would work :-). It set bV5CSType to 0 which 
means it uses the bV5Endpoints fields, now they're all zero as well and so 
it tries to divide by zero somewhere and throws an exception.

It's a bug in the MS docs, the other delphi examples omit the ZeroMemory and 
so it will usually work unless all those fields are set to 0 when the memory 
is malloced, the bug is probably everywhere in applications, but you'd 
seldom hit it.

(I changed a couple of other non crtical bits below (at least I think they 
are))

cheers,
Dave


function CreateDIBSection_V5(DC: HDC; const p2: TBitmapV5Header; p3: UINT;
  var p4: Pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall;external GDI32 
name
'CreateDIBSection';



procedure TForm12.Button1Click(Sender: TObject);
var
     bm: HBITMAP;
     dc: HDC;
     BitmapHeader: TBitmapV5Header;
     pBits: Pointer;
begin
     FillMemory(@BitmapHeader, SizeOf(BITMAPV5HEADER), 0);

     with BitmapHeader do
     begin
{        bV5Size := 0;
        bV5Width := 0;
        bV5Height := 0;
        bV5Planes := 0;
        bV5BitCount := 0;
        bV5Compression := 0;
        bV5SizeImage := 0;
        bV5XPelsPerMeter := 0;
        bV5YPelsPerMeter := 0;
        bV5ClrUsed := 0;
        bV5ClrImportant := 0;
        bV5RedMask := 0;
        bV5GreenMask := 0;
        bV5BlueMask := 0;
        bV5AlphaMask := 0; }
        bV5CSType := 1; <-------------- This flag here
        bV5Endpoints.ciexyzRed.ciexyzX := 0;
        bV5Endpoints.ciexyzRed.ciexyzY := 0;
        bV5Endpoints.ciexyzRed.ciexyzZ := 0;
        bV5Endpoints.ciexyzGreen.ciexyzX := 0;
        bV5Endpoints.ciexyzGreen.ciexyzY := 0;
        bV5Endpoints.ciexyzGreen.ciexyzZ := 0;
        bV5Endpoints.ciexyzBlue.ciexyzX := 0;
        bV5Endpoints.ciexyzBlue.ciexyzY := 0;
        bV5Endpoints.ciexyzBlue.ciexyzZ := 0;
{        bV5GammaRed := 0;
        bV5GammaGreen := 0;
        bV5GammaBlue := 0;
        bV5Intent := 0;
        bV5ProfileData := 0;
        bV5ProfileSize := 0;
        bV5Reserved := 0;    }
     end;
     BitmapHeader.bV5Size := SizeOf(BITMAPV5HEADER);
     BitmapHeader.bV5Width := 32;
     BitmapHeader.bV5Height := 32;
     BitmapHeader.bV5Planes := 1;
     BitmapHeader.bV5BitCount := 32;
     BitmapHeader.bV5Compression := BI_BITFIELDS;
     BitmapHeader.bv5clrused := 1;
     BitmapHeader.bV5RedMask   :=  $00FF0000;
     BitmapHeader.bV5GreenMask :=  $0000FF00;
     BitmapHeader.bV5BlueMask  :=  $000000FF;
     BitmapHeader.bV5AlphaMask :=  $FF000000;

     dc := GetDC(0);

     bm := CreateDIBSection_V5(
            dc,
            BitmapHeader,
            DIB_RGB_COLORS,
            pBits,
            0, 0);
end; 
Re: CreateDIBSection fails with EDivideZero exception
#166
Author: Ian Boyd
Date: Fri, 25 Jul 2008 13:26
12 lines
1616 bytes
> It's because you did a ZeroMemory
> It set bV5CSType to 0 which means it uses the bV5Endpoints fields, now 
> they're all zero as well

> It's a bug in the MS docs, the other delphi examples omit the ZeroMemory 
> and so it will usually work unless all those fields are set to 0 when the 
> memory is malloced, the bug is probably everywhere in applications, but 
> you'd seldom hit it.

Oh...my...god.

That is truely terrifying. 
Re: CreateDIBSection fails with EDivideZero exception
#174
Author: Ian Boyd
Date: Fri, 25 Jul 2008 19:11
70 lines
3477 bytes
Here's the working call.

People should note the bug in the MS KB article leaves bV5CSType as zero 
(LCS_CALIBRATED_RGB), which then means you have to specify 3 xyz coordinates 
of red, green and blue in bV5Endpoints, and the three red, green and blue 
gamma values in bV5GammaRed, bV5GammaGreen, bV5GammaBlue. If you don't you 
(might) get a division by zero.  (who knows if SP2 added more security 
checks to CreateDIBSection to catch the missing values)



function CreateDIBSection_V5(
      DC: HDC;      // handle to DC
      pbmi: PBitmapV5Header; // bitmap data
      iUsage: UINT;    // data type indicator
      var pBits: Pointer;  // bit values
      hSection: THandle;  // handle to file mapping object
      dwOffset: DWORD   // offset to bitmap bit values
): HBITMAP; stdcall; external GDI32 name 'CreateDIBSection';

var
     bm: HBITMAP;
     dc: HDC;
     BitmapHeader: TBitmapV5Header;
     Bits: Pointer;
const
     LCS_CALIBRATED_RGB =   $00000000;
     LCS_sRGB =       $73524742; //ASCII encoding of "sRGB"
     LCS_WINDOWS_COLOR_SPACE =  $57696E20; //ASCII encoding of "Win "

     LCS_GM_BUSINESS =    $00000001; //Saturation
     LCS_GM_GRAPHICS =    $00000002; //Relative Colorimetric
     LCS_GM_IMAGES =     $00000004; //Perceptual
     LCS_GM_ABS_COLORIMETRIC =  $00000008; //Absolute Colorimetric
begin
     ZeroMemory(@BitmapHeader, SizeOf(TBitmapV5Header));
     BitmapHeader.bV5Size := SizeOf(TBitmapV5Header);
     BitmapHeader.bV5Width := 32;
     BitmapHeader.bV5Height := 32;
     BitmapHeader.bV5Planes := 1; //must be 1
     BitmapHeader.bV5BitCount := 32;
     BitmapHeader.bV5Compression := BI_BITFIELDS;
     BitmapHeader.bV5RedMask   :=  $00FF0000;
     BitmapHeader.bV5GreenMask :=  $0000FF00;
     BitmapHeader.bV5BlueMask  :=  $000000FF;
     BitmapHeader.bV5AlphaMask :=  $FF000000;
     BitmapHeader.bV5CSType := LCS_sRGB;
     BitmapHeader.bV5Intent := LCS_GM_ABS_COLORIMETRIC;
     BitmapHeader.bV5Reserved := 0; //should be zero

     dc := GetDC(0);
     if dc = 0 then
          RaiseLastWin32Error;
     try
          bm := CreateDIBSection_V5(
                dc,
                @BitmapHeader,
                DIB_RGB_COLORS,
                Bits,
                0, 0);
     finally
          ReleaseDC(0, dc);
     end;
end;



Note: Just because you can create a 32bpp bitmap, doesn't mean you'll ever 
be able to figure out how to use the alpha values to achive actual 
transparency. 
Re: CreateDIBSection fails with EDivideZero exception
#179
Author: GrandmasterB
Date: Fri, 25 Jul 2008 21:48
8 lines
1428 bytes
"Ian Boyd" <ian.borlandnews010@avatopia.com> wrote in message 
news:488a2574$1@newsgroups.borland.com...
> Here's the working call.

Thanks for posting this.  Figuring out how to do this in Delphi was on my 
'long term' things to-do list because I think it may help me speed up 
certain operations that I'm doing in straight gdi+ right now (which can be 
very slow due to the way it locks/unlocks pixel data).
Re: CreateDIBSection fails with EDivideZero exception
#181
Author: David Ninnes
Date: Fri, 25 Jul 2008 23:40
18 lines
1814 bytes

"GrandmasterB" <Fizzle@shizzle.com> wrote in message 
news:488a3c82$1@newsgroups.borland.com...
> "Ian Boyd" <ian.borlandnews010@avatopia.com> wrote in message 
> news:488a2574$1@newsgroups.borland.com...
>> Here's the working call.
>
> Thanks for posting this.  Figuring out how to do this in Delphi was on my 
> 'long term' things to-do list because I think it may help me speed up 
> certain operations that I'm doing in straight gdi+ right now (which can be 
> very slow due to the way it locks/unlocks pixel data).
>
>
>

ditto, I was hoping V5 bitmaps will be in the next version of delphi, 
particularly in the clipboard for copying and pasting alpha channel images. 
Re: CreateDIBSection fails with EDivideZero exception
#182
Author: David Ninnes
Date: Fri, 25 Jul 2008 23:47
21 lines
1926 bytes

"Ian Boyd" <ian.borlandnews010@avatopia.com> wrote in message 
news:4889d47b$1@newsgroups.borland.com...
>> It's because you did a ZeroMemory
>> It set bV5CSType to 0 which means it uses the bV5Endpoints fields, now 
>> they're all zero as well
>
>> It's a bug in the MS docs, the other delphi examples omit the ZeroMemory 
>> and so it will usually work unless all those fields are set to 0 when the 
>> memory is malloced, the bug is probably everywhere in applications, but 
>> you'd seldom hit it.
>
> Oh...my...god.
>
> That is truely terrifying.
>
Don't know if I'd go that far :-). Thanks for formalizing it.

cheers,
Dave 
Re: CreateDIBSection fails with EDivideZero exception
#195
Author: Ian Boyd
Date: Mon, 28 Jul 2008 15:03
13 lines
1649 bytes
>> That is truely terrifying.
>>
> Don't know if I'd go that far :-). Thanks for formalizing it.

It's terrifying because everyone follows code the find. And when the actual 
MS KB article has a crash in it, everyone's code can potentially crash 
depending on how the random gamma rays from M31 flipped the bits in a 
person's RAM.


i can't blame them though; people don't realize that a KB article isn't a 
formal piece of documentation from Microsoft - it's just something that a 
guy at MS figured out and can share with the world. 
Re: CreateDIBSection fails with EDivideZero exception
#196
Author: David Ninnes
Date: Mon, 28 Jul 2008 17:54
25 lines
2159 bytes

"Ian Boyd" <ian.borlandnews010@avatopia.com> wrote in message 
news:488ddfcb@newsgroups.borland.com...
>>> That is truely terrifying.
>>>
>> Don't know if I'd go that far :-). Thanks for formalizing it.
>
> It's terrifying because everyone follows code the find. And when the 
> actual MS KB article has a crash in it, everyone's code can potentially 
> crash depending on how the random gamma rays from M31 flipped the bits in 
> a person's RAM.
>
>
> i can't blame them though; people don't realize that a KB article isn't a 
> formal piece of documentation from Microsoft - it's just something that a 
> guy at MS figured out and can share with the world.
>

There's a feedback down the bottom of the MS article, I made a comment, 
we'll see what happens. It may be worthwhile if you make an entry too? not 
sure if more complaints gets things changed :-).

cheers,
Dave 
Re: CreateDIBSection fails with EDivideZero exception
#197
Author: Ian Boyd
Date: Mon, 28 Jul 2008 18:06
12 lines
1836 bytes
> There's a feedback down the bottom of the MS article, I made a comment, 
> we'll see what happens. It may be worthwhile if you make an entry too? not 
> sure if more complaints gets things changed :-).

Reading Raymond Chen's blog, it's apparent that even the formal documention 
is incomplete or sometimes in error.

One story was how a guy at MS discovered that something worked, and had to 
docs team change it.

Turns out the guy was relying on 'undocumented' behaviour, which then broke 
in the next version of Windows.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads