Different version of Fog in documentation and in reality... Or Image::WriteToFile() don't work

13 views
Skip to first unread message

Aleus Essentia

unread,
Oct 7, 2011, 8:31:51 PM10/7/11
to fog-dev
Hello! I am newbie in Fog and want get some example for undestanding
API. Fog have documentation for Start in Fog but it's for previous
version... Good. This no problem for me. I simple math API in doxygen
and example and I recieve next code:

#include <Fog/Core.h>
#include <Fog/G2d.h>

using namespace Fog;

int main(int argc, char* argv[])
{
Image image( SizeI(320, 320), IMAGE_FORMAT_XRGB32 );

Painter painter( image );

painter.setSource( Argb32(0xFFFFFFFF) );
painter.fillAll();

double x = 10.5;
double y = 10.5;
double w = 300.0;
double h = 300.0;

PathD path;
path.round( RoundD(RectD(x,y,w,h), PointD( 50.0, 50.0)) );

GradientD gradient( GRADIENT_TYPE_LINEAR );
gradient._pts[0] = PointD(x,y);
gradient._pts[1] = PointD(50.0, 50.0);

List<ColorStop> colorstops;
colorstops += ColorStop(0.0f, Argb32(0xFFFFFF00));
colorstops += ColorStop(1.0f, Argb32(0xFFFF0000));
gradient.setStops( colorstops );

Pattern pattern( gradient );

painter.setSource( pattern );
painter.fillPath( path );

painter.setSource( Argb32(0xFF000000) );
painter.drawPath( path );

painter.end();

StringW filename( Ascii8("Introduction.bmp") ); // "Introduction.png"
image.writeToFile( filename );
return 0;
}

But this code throw exception at prelast line -
image.writeToFile( filename). I debug it... And found that reason of
this exception was been null pointer in _d->blitFn() in function
ImageConverter::blitSpan().
How I can solve this exception?

Petr Kobalíček

unread,
Oct 8, 2011, 9:49:18 AM10/8/11
to fog...@googlegroups.com
Hello,

Thank you for trying Fog-Framework and welcome to the mailing list.

I can confirm that your code produces the assertion. It was a bug and
it was fixed. I found another bug related to the GradientD, so
updating to trunk is really necessary.

Now I'd like to do small correction to your code:

This:

       GradientD gradient( GRADIENT_TYPE_LINEAR );
       gradient._pts[0] = PointD(x,y);
       gradient._pts[1] = PointD(50.0, 50.0);

       List<ColorStop> colorstops;
       colorstops += ColorStop(0.0f, Argb32(0xFFFFFF00));
       colorstops += ColorStop(1.0f, Argb32(0xFFFF0000));
       gradient.setStops( colorstops );

       Pattern pattern( gradient );

       painter.setSource( pattern );

could be replaced by:

       LinearGradientD gradient(PointD(x, y), PointD(50.0, 50.0));
gradient.addStop(0.0f, Argb32(0xFFFFFF00));
gradient.addStop(1.0f, Argb32(0xFFFF0000));
       painter.setSource( gradient );

Using underscores in Fog-Framework in production code should be
minimized, with underscore are usually decorated private members and
functions.

Thank you for the report!

Best regards
Petr Kobalicek

Aleus Essentia

unread,
Oct 9, 2011, 8:02:05 AM10/9/11
to fog-dev
Thank you for fixing bug. But I have new runtime error. It's
initialization of object of Image class at first line -
Image image( SizeI(320, 320), IMAGE_FORMAT_XRGB32 );
Another problem which I miss in previos time is that Fog can't
deterimine locale in my comp (cp1251, windows 7).

Petr Kobalíček

unread,
Oct 9, 2011, 1:04:49 PM10/9/11
to fog...@googlegroups.com
Hi Aleus,

please try to rebuild project completely to avoid the crash; I
experienced that visual studio creates wrong build when changed core
files (I'm not sure about other compilers).

If the problem remains I will check it.

I noticed the locale problem too, this will be fixed soon. But this
should affect nothing, because Fog is using unicode versions of
WinAPI.

Thanks
Petr

Aleus Essentia

unread,
Oct 10, 2011, 10:53:27 AM10/10/11
to fog-dev
Hello, Petr! :^)

I update Fog's svn, fix some syntax error in using scalePixel()
function and rebuild library and my code... Ehm... Now program fault
at image.writeToFile() again. :^)
P.S.: I use MS VS2010 x86.

Aleus Essentia

unread,
Oct 10, 2011, 11:02:45 AM10/10/11
to fog-dev
I avoid my problem by replacing PNG image format to BMP. It's enough
for my education of Fog at this moment. Thanks. :^)

Petr Kobalíček

unread,
Oct 10, 2011, 11:08:46 AM10/10/11
to fog...@googlegroups.com
Hi Aleus,

I updated the compiler error issue and I can reproduce the png saving
bug (using GDI+). I'm going to fix it,

Thank you!
Petr

Petr Kobalíček

unread,
Oct 10, 2011, 12:08:18 PM10/10/11
to fog...@googlegroups.com
Hi,

GDI+ codec is now fixed;)

Best regards
Petr

Jacques Leroy

unread,
Nov 27, 2011, 7:06:00 AM11/27/11
to Petr Kobalicek

Hi Petr,

Doing some code review in Fog...

In Point.h, looking at

 FOG_INLINE bool operator< (const PointI& other) { return (y < other.y) | ((y <= other.y) & (x <  other.x)); }
 FOG_INLINE bool operator> (const PointI& other) { return (y > other.y) | ((y <= other.y) & (x >  other.x)); }
 FOG_INLINE bool operator<=(const PointI& other) { return (y < other.y) | ((y == other.y) & (x <= other.x)); }
 FOG_INLINE bool operator>=(const PointI& other) { return (y > other.y) | ((y == other.y) & (x >= other.x)); }

is there a good reason for using bitwise operators & and | and not logical operators && and || , and therefore:

 FOG_INLINE bool operator< (const PointI& other) { return (y < other.y) || ((y <= other.y) && (x <  other.x)); }
 FOG_INLINE bool operator> (const PointI& other) { return (y > other.y) || ((y <= other.y) && (x >  other.x)); }
 FOG_INLINE bool operator<=(const PointI& other) { return (y < other.y) || ((y == other.y) && (x <= other.x)); }
 FOG_INLINE bool operator>=(const PointI& other) { return (y > other.y) || ((y == other.y) && (x >= other.x)); }

Friendly yours,
 Jacques Leroy

Jacques Leroy

unread,
Nov 27, 2011, 7:15:36 AM11/27/11
to Petr Kobalicek
Hi Petr,

Doing some code review in Fog...

In Point.h, looking at

 FOG_INLINE bool operator< (const PointI& other) { return (y < other.y) | ((y <= other.y) & (x <  other.x)); }
 FOG_INLINE bool operator> (const PointI& other) { return (y > other.y) | ((y <= other.y) & (x >  other.x)); }
 FOG_INLINE bool operator<=(const PointI& other) { return (y < other.y) | ((y == other.y) & (x <= other.x)); }
 FOG_INLINE bool operator>=(const PointI& other) { return (y > other.y) | ((y == other.y) & (x >= other.x)); }

is there a good reason for using bitwise operators & and | instead of logical operators && and || , driving to:


 FOG_INLINE bool operator< (const PointI& other) { return (y < other.y) || ((y <= other.y) && (x <  other.x)); }
 FOG_INLINE bool operator> (const PointI& other) { return (y > other.y) || ((y <= other.y) && (x >  other.x)); }
 FOG_INLINE bool operator<=(const PointI& other) { return (y < other.y) || ((y == other.y) && (x <= other.x)); }
 FOG_INLINE bool operator>=(const PointI& other) { return (y > other.y) || ((y == other.y) && (x >= other.x)); }


WARNING: Same glitch for PointF and PointD.


Friendly yours,
 Jacques Leroy

Petr Kobalíček

unread,
Dec 13, 2011, 4:44:58 PM12/13/11
to fog...@googlegroups.com
Hi,

the code is right :) There are binary ops, but it's only here to make
sure that compiler will emit only one condition per function. The &&
and || will of course work too.

Thanks for review;)

Best regards
Petr Kobalicek

Jacques Leroy

unread,
Dec 13, 2011, 4:52:00 PM12/13/11
to Petr Kobalicek
I keep finding it strange...

generally:

((2) && (1)) is 3 , so true

((2) & (1)) is zero == false

and I can't see optimized code using bitwise operators ...

Friendly yours,
 Jacques Leroy

> Date: Tue, 13 Dec 2011 23:44:58 +0200
> Subject: Re: [fog-dev] Some code review... (Point.h)
> From: kobalic...@gmail.com
> To: fog...@googlegroups.com

Petr Kobalíček

unread,
Dec 14, 2011, 2:59:07 AM12/14/11
to fog...@googlegroups.com
Hi,

On Tue, Dec 13, 2011 at 11:52 PM, Jacques Leroy <blake...@hotmail.com> wrote:
> I keep finding it strange...
>
> generally:
>
> ((2) && (1)) is 3 , so true
>
> ((2) & (1)) is zero == false
>

Actually this is not the case, because result of comparison (a op b)
should be always 0 or 1, so bitwise ops should do the right job. I
need more testing whether this way has benefit or not, but generally
I'd like to tell compiler that one cmp/branch is okay for the whole
comparison.

> and I can't see optimized code using bitwise operators ...

It probably depends on the compiler/arch, I think that there should be
benefit at least for ARM, we will see in the future;)

Best regards
Petr

Jacques Leroy

unread,
Dec 14, 2011, 4:49:09 AM12/14/11
to Petr Kobalicek
Hi Petr !

I'd like to show you the following reference:

http://www.programmersheaven.com/mb/CandCPP/337795/337795/whats-the-difference-between-bitwise-and-logical-operators/

I understand your need for speed (I have the same), and this article gives you a clear answer:

If you're looking for fast boolean expression evaluation: always go with logical operators,
because evaluation stops as soon as possible, while bitwise operators always go
for full expression evaluation... Benefits won't rely upon CPU architecture...
Things are always faster when there's nothing to do !

Example:

if (condition1 || condition2)

if condition1 evaluates to 'true' (aka a non zero value), condition2 won't be evaluated

if (condition1 | condition2)

both conditions will ALWAYS be evaluated

More:

if (condition1  && condition2)

imagine condition1 evaluates to 1, and condition2 evaluates to 2, result is (1 && 2) = (true && true) = true

While:

if (condition1 & condition2) evaluates to (1 & 2) = (01 & 10) /* binary */ = 0 = false !!!!

So you can see both poor performance and hidden dangers in using bitwise operators
instead of logical operators for pure boolean arithmetic...

Hope this helps,
 Jacques Leroy

> Date: Wed, 14 Dec 2011 09:59:07 +0200

Jacques Leroy

unread,
Dec 14, 2011, 6:35:43 AM12/14/11
to Petr Kobalicek
Hi Petr !

I'd like to show you the following reference:

http://www.programmersheaven.com/mb/CandCPP/337795/337795/whats-the-difference-between-bitwise-and-logical-operators/

I understand your need for speed (I have the same), and this article gives you a clear answer:

If you're looking for fast boolean expression evaluation: always go with logical operators,
because evaluation stops as soon as possible, while bitwise operators always go
for full expression evaluation... Benefits won't rely upon CPU architecture...
Things are always faster when there's nothing to do !

Example:

if (condition1 || condition2)

if condition1 evaluates to 'true' (aka a non zero value), condition2 won't be evaluated

if (condition1 | condition2)

both conditions will ALWAYS be evaluated

More:

if (condition1  && condition2)

imagine condition1 evaluates to 1, and condition2 evaluates to 2, result is (1 && 2) = (true && true) = true

While:

if (condition1 & condition2) evaluates to (1 & 2) = (01 & 10) /* binary */ = 0 = false !!!!

So you can see both poor performance and hidden dangers in using bitwise operators
instead of logical operators for pure boolean arithmetic...

Hope this helps,
 Jacques Leroy

> Date: Wed, 14 Dec 2011 09:59:07 +0200

Petr Kobalíček

unread,
Dec 16, 2011, 7:38:51 AM12/16/11
to fog...@googlegroups.com
Hi Jacques,

I understand the differences between & and &&, and I currently want to
evaluate both conditions. The reason is that some processors, for
example ARM, have many conditional instructions, and such code can
execute using only one conditional branch, which is the most costly
instruction, if mispredicted.

But what I don't understand is your example, mainly "if (condition1 &
condition2) evaluates to (1 & 2) = (01 & 10)". I don't know whether
the condition can evaluate to a different value than 0 or 1, so this
shouldn't never be an issue. If you know about compiler / architecture
where the expression like a > b, or a == b, or a < b, etc can evaluate
to a different value than 0, 1, and to be more precise, where
expressions like (a > b) and (a < b) can evaluate to a different
non-zero values on 'true', then post me a link so I can read about the
possible issues.

I'm currently making port for ARM devices, so I will be able to test
(a > b) & (c > d) against (a > b) && (c > d). I use & mainly when it
comes into floating point, because I'm sure that compiler is unable to
optimize && to & when working with float/double types.

Hope that my explanation is clear ;)

Best regards
Petr Kobalicek

Jacques Leroy

unread,
Jan 1, 2012, 7:23:14 AM1/1/12
to Petr Kobalicek
Hi Petr !

First... Happy New Year !  ;)

I clearly see now what you're trying to achieve.

The way you're using bitwise operators is unusual,
but could be rewarding...

As far as you're dealing with bitwise operators and boolean
expressions ONLY, your system is valid.

My mathematical side said 'hulk' just because your system is not
fully general: (2 & 1) == 0, so 'false', but (2 && 1) is 'true'
(but 2 is not boolean)

I'll try to give an eye on ARM architecture...

Friendly yours,
 Jacques


> Date: Fri, 16 Dec 2011 14:38:51 +0200

Jacques Leroy

unread,
Jan 3, 2012, 7:36:53 AM1/3/12
to Petr Kobalicek
Hi Petr !

Two more cents about this problem:

// Using: && - it will work ...

char *s = getName();

if ((NULL != s) && (0 != s[0]))
{
 // ...
}


// Using: & - you're doomed !

char *s = getName();

if ((NULL != s) & (0 != s[0]))  // if s is NULL, s[0] will crash !
{
 // ...
}

All that to say that trying to force full evaluation of boolean expressions
is dangerous - it may be done, provided you do it with EXTREME caution,
to prevent EXTREME prejudice...

Friendly yours,
 Jacques

> Date: Fri, 16 Dec 2011 14:38:51 +0200

Jacques Leroy

unread,
Jan 3, 2012, 7:41:52 AM1/3/12
to Petr Kobalicek
I recommend you the following article:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

It could be interesting to investigate about:

provided f1 and f2 are floats, and one of them is strictly positive,
expressions like:

if (*(int*)&f1 < *(int*)&f2)


works perfectly !


(but don't know if it brings any benefit with ARM architecture...)


Friendly yours,

 Jacques Leroy



> Date: Fri, 16 Dec 2011 14:38:51 +0200

Petr Kobalíček

unread,
Jan 9, 2012, 9:06:31 PM1/9/12
to fog...@googlegroups.com
Hi Jacques,

I know that article, I read it more times, because I wanted to have
float comparison done right in Fog. But there are always limitations
when making comparison using integers, as you said, they must be
strictly positive, for example. So currently I'm not using such tricks
to compare floats (only Hash<float, X> can compare floats using binary
representation).

But back to your question about using & and | in conditions. There is
no much code where this technique is used and this technique is only
used in very strict way. I said that the idea behind it is strictly an
optimization, telling compiler that I'd like to compare more
variables, but I'd like to use only one branch.

for example, if I have two integers, and I need to do some comparison,
then there is no much difference between using & vs &&. I think that
compiler can emit & instead of && automatically - and I'm sure that
Intel compiler does it.
Example:
int a, b;
int x, y;

1) if ((a == x) && (b == y)

vs

2) if ((a == x) & (b == y)

For me 1) is more readable, 2) should be faster in the most
architectures, but I hope that C++ compilers do the right job, so
personally I don't care about this scenario.

But if we substitute int using float, for example:
float a, b;
float x, y;

1) if ((a == x) && (b == y))

vs

2) if ((a == x) & (b == y))

Then compiler can't simply use & instead of && if not mentioned,
because there can be signaling nan in 'b' or 'y' and in such case 1)
would be okay, but in 2) an exception should be thrown. This is the
main reason why & is sometimes used when working with floating point.
If you browse the whole Fog code then you shouldn't find that using
single & is only in some places and there is reason for it. There is
no dangerous code such ((a != NULL) & (a[0] != 0)) as you wrote in the
previous post.

I'd like also to mention that bit masking is used extensively in
SSE/SSE2 code, so using & is basically the same, but done in C - and
used carefully;)

Best regards
Petr Kobalicek

Reply all
Reply to author
Forward
0 new messages