Bug in Form>>#asFormOfDepth:?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug in Form>>#asFormOfDepth:?

Christoph Thiede

Hi all,


consider the following example (print it):


"Example 1"

f := Form extent: 1 asPoint depth: 1.
f colorAt: 0 @ 0 put: Color red.
g := f asFormOfDepth: 2.
g colorAt: 0 @ 0


Expected output: Color red.

Actual output: Color black!


Other examples:


"Example 2"

f := Form extent: 1 asPoint depth: 1.
f colorAt: 0 @ 0 put: Color red.
g := f asFormOfDepth: 32.
g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"


"Example 3"

f := Form extent: 1 asPoint depth: 16.
f colorAt: 0 @ 0 put: Color red.
g := f asFormOfDepth: 32.
g colorAt: 0 @ 0 "--> (Color r: 0.973 g: 0.0 b: 0.0)"

I am not familiar with color depths, but afaik Color red could be stored exactly using only 1 bit? Do I misunderstand the concept or is this really a bad output?

(I came across to this when performing #collectColors: on an 8 bit ColorForm loaded from disk, which did not work as expected.)

Best,
Christoph


Reply | Threaded
Open this post in threaded view
|

Re: Bug in Form>>#asFormOfDepth:?

Tobias Pape
Hi Christoph,

> On 09.09.2019, at 13:25, Thiede, Christoph <[hidden email]> wrote:
>
> Hi all,
>
> consider the following example (print it):
>
> "Example 1"
> f := Form extent: 1 asPoint depth: 1.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 2.
> g colorAt: 0 @ 0
>
> Expected output: Color red.
> Actual output: Color black!

No, Forms of depth 1 are black and white, and of depth2 are gray.

>
> Other examples:
>
> "Example 2"
> f := Form extent: 1 asPoint depth: 1.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 32.
> g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"

yes, because you go from black/white to 32bit. I would have expected r0g0b0, but there might some rounding go on.

>
> "Example 3"
> f := Form extent: 1 asPoint depth: 16.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 32.
> g colorAt: 0 @ 0 "--> (Color r: 0.973 g: 0.0 b: 0.0)"



Something's wonky here!
If we do

        (((Form extent: 1 asPoint depth: 16)
                colorAt: 0 @ 0 put: Color red)
                asFormOfDepth: 32)
        pixelValueAt: 0@0

we get
        4294443008 (aka 0xFFF80000)  which is a 32bit value.
But the meaning is

        11111111 11111000 00000000 00000000
        ^ alpha  ^ r      ^ g      ^ b

which means that the r component is not  "upscaled" during the #asFormOfDepth: process o.O (see PS)




>
> I am not familiar with color depths, but afaik Color red could be stored exactly using only 1 bit? Do I misunderstand the concept or is this really a bad output?

No, the first bit depth to support red is 4 bit.

Have a look at Color class>>colorFromPixelValue: p depth: d

BTW: You can use a ColorForm to work with your own palette, so that you can have for example a 1-bit form with 1=yellow & 0=red…


Best regards
        -Tobias

>
> (I came across to this when performing #collectColors: on an 8 bit ColorForm loaded from disk, which did not work as expected.)
>
> Best,
> Christoph

PS: PS:
Color red is r:1.0 g:0.0 b:0.0 but stored in a different fashion:

Color comment:
"
Think of Color's instance variables as:
        r amount of red, a Float between 0.0 and 1.0.
        g amount of green, a Float between 0.0 and 1.0.
        b amount of blue, a Float between 0.0 and 1.0.
(But, in fact, the three are encoded as values from 0 to 1023 and combined in a single integer, rgb.  The user does not need to know this.)
"
that means "Color red" is stored as 0x3FF00000 or,

1111111111 0000000000 0000000000
^ red      ^ green    ^ blue

that makes 10 bit per component.

However, in the 16 bit form we have only 5 bit per component, so,

        f := Form extent: 1 asPoint depth: 16.
        f colorAt: 0 @ 0 put: Color red.
        f pixelValueAt: 0@0.

yields 0x7C00 aka

11111 00000 00000
^ r   ^ g   ^ b


Reply | Threaded
Open this post in threaded view
|

Re: Bug in Form>>#asFormOfDepth:?

Christoph Thiede

Hi Tobias,


oops, I mistook the depth with the number of bits per channel. Sorry and many thanks for your explanations!


How would one fix the upscaling issue? Form>>#colormapIfNeededFor: returns nil in example 3, the comment in Color>>#colorMapIfNeededFrom:to: states this task is delegated to BitBlt. Is this comment wrong or is the defect in the primitive called that is in BitBlt>>#copyBits?


Best,

Christoph



Von: Squeak-dev <[hidden email]> im Auftrag von Tobias Pape <[hidden email]>
Gesendet: Montag, 9. September 2019 14:56 Uhr
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Bug in Form>>#asFormOfDepth:?
 
Hi Christoph,

> On 09.09.2019, at 13:25, Thiede, Christoph <[hidden email]> wrote:
>
> Hi all,
>
> consider the following example (print it):
>
> "Example 1"
> f := Form extent: 1 asPoint depth: 1.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 2.
> g colorAt: 0 @ 0
>
> Expected output: Color red.
> Actual output: Color black!

No, Forms of depth 1 are black and white, and of depth2 are gray.

>
> Other examples:
>
> "Example 2"
> f := Form extent: 1 asPoint depth: 1.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 32.
> g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"

yes, because you go from black/white to 32bit. I would have expected r0g0b0, but there might some rounding go on.

>
> "Example 3"
> f := Form extent: 1 asPoint depth: 16.
> f colorAt: 0 @ 0 put: Color red.
> g := f asFormOfDepth: 32.
> g colorAt: 0 @ 0 "--> (Color r: 0.973 g: 0.0 b: 0.0)"



Something's wonky here!
If we do

        (((Form extent: 1 asPoint depth: 16)
                colorAt: 0 @ 0 put: Color red)
                asFormOfDepth: 32)
        pixelValueAt: 0@0

we get
        4294443008 (aka 0xFFF80000)  which is a 32bit value.
But the meaning is

        11111111 11111000 00000000 00000000
        ^ alpha  ^ r      ^ g      ^ b

which means that the r component is not  "upscaled" during the #asFormOfDepth: process o.O (see PS)




>
> I am not familiar with color depths, but afaik Color red could be stored exactly using only 1 bit? Do I misunderstand the concept or is this really a bad output?

No, the first bit depth to support red is 4 bit.

Have a look at Color class>>colorFromPixelValue: p depth: d

BTW: You can use a ColorForm to work with your own palette, so that you can have for example a 1-bit form with 1=yellow & 0=red…


Best regards
        -Tobias

>
> (I came across to this when performing #collectColors: on an 8 bit ColorForm loaded from disk, which did not work as expected.)
>
> Best,
> Christoph

PS: PS:
Color red is r:1.0 g:0.0 b:0.0 but stored in a different fashion:

Color comment:
"
Think of Color's instance variables as:
        r       amount of red, a Float between 0.0 and 1.0.
        g       amount of green, a Float between 0.0 and 1.0.
        b       amount of blue, a Float between 0.0 and 1.0.
(But, in fact, the three are encoded as values from 0 to 1023 and combined in a single integer, rgb.  The user does not need to know this.)
"
that means "Color red" is stored as 0x3FF00000 or,

1111111111 0000000000 0000000000
^ red      ^ green    ^ blue

that makes 10 bit per component.

However, in the 16 bit form we have only 5 bit per component, so,

        f := Form extent: 1 asPoint depth: 16.
        f colorAt: 0 @ 0 put: Color red.
        f pixelValueAt: 0@0.

yields 0x7C00 aka

11111 00000 00000
^ r   ^ g   ^ b




Reply | Threaded
Open this post in threaded view
|

Re: Bug in Form>>#asFormOfDepth:?

Tobias Pape

> On 09.09.2019, at 15:53, Thiede, Christoph <[hidden email]> wrote:
>
> Hi Tobias,
>
> oops, I mistook the depth with the number of bits per channel. Sorry and many thanks for your explanations!
>
> How would one fix the upscaling issue? Form>>#colormapIfNeededFor: returns nil in example 3, the comment in Color>>#colorMapIfNeededFrom:to: states this task is delegated to BitBlt. Is this comment wrong or is the defect in the primitive called that is in BitBlt>>#copyBits?
>
No, that part is only for cross-conversion of Forms and ColorForms
-t

> Best,
> Christoph
>
> Von: Squeak-dev <[hidden email]> im Auftrag von Tobias Pape <[hidden email]>
> Gesendet: Montag, 9. September 2019 14:56 Uhr
> An: The general-purpose Squeak developers list
> Betreff: Re: [squeak-dev] Bug in Form>>#asFormOfDepth:?
>  
> Hi Christoph,
>
> > On 09.09.2019, at 13:25, Thiede, Christoph <[hidden email]> wrote:
> >
> > Hi all,
> >
> > consider the following example (print it):
> >
> > "Example 1"
> > f := Form extent: 1 asPoint depth: 1.
> > f colorAt: 0 @ 0 put: Color red.
> > g := f asFormOfDepth: 2.
> > g colorAt: 0 @ 0
> >
> > Expected output: Color red.
> > Actual output: Color black!
>
> No, Forms of depth 1 are black and white, and of depth2 are gray.
>
> >
> > Other examples:
> >
> > "Example 2"
> > f := Form extent: 1 asPoint depth: 1.
> > f colorAt: 0 @ 0 put: Color red.
> > g := f asFormOfDepth: 32.
> > g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"
>
> yes, because you go from black/white to 32bit. I would have expected r0g0b0, but there might some rounding go on.
>
> >
> > "Example 3"
> > f := Form extent: 1 asPoint depth: 16.
> > f colorAt: 0 @ 0 put: Color red.
> > g := f asFormOfDepth: 32.
> > g colorAt: 0 @ 0 "--> (Color r: 0.973 g: 0.0 b: 0.0)"
>
>
>
> Something's wonky here!
> If we do
>
>         (((Form extent: 1 asPoint depth: 16)
>                 colorAt: 0 @ 0 put: Color red)
>                 asFormOfDepth: 32)
>         pixelValueAt: 0@0
>
> we get
>         4294443008 (aka 0xFFF80000)  which is a 32bit value.
> But the meaning is
>
>         11111111 11111000 00000000 00000000
>         ^ alpha  ^ r      ^ g      ^ b
>
> which means that the r component is not  "upscaled" during the #asFormOfDepth: process o.O (see PS)
>
>
>
>
> >
> > I am not familiar with color depths, but afaik Color red could be stored exactly using only 1 bit? Do I misunderstand the concept or is this really a bad output?
>
> No, the first bit depth to support red is 4 bit.
>
> Have a look at Color class>>colorFromPixelValue: p depth: d
>
> BTW: You can use a ColorForm to work with your own palette, so that you can have for example a 1-bit form with 1=yellow & 0=red…
>
>
> Best regards
>         -Tobias
>
> >
> > (I came across to this when performing #collectColors: on an 8 bit ColorForm loaded from disk, which did not work as expected.)
> >
> > Best,
> > Christoph
>
> PS: PS:
> Color red is r:1.0 g:0.0 b:0.0 but stored in a different fashion:
>
> Color comment:
> "
> Think of Color's instance variables as:
>         r       amount of red, a Float between 0.0 and 1.0.
>         g       amount of green, a Float between 0.0 and 1.0.
>         b       amount of blue, a Float between 0.0 and 1.0.
> (But, in fact, the three are encoded as values from 0 to 1023 and combined in a single integer, rgb.  The user does not need to know this.)
> "
> that means "Color red" is stored as 0x3FF00000 or,
>
> 1111111111 0000000000 0000000000
> ^ red      ^ green    ^ blue
>
> that makes 10 bit per component.
>
> However, in the 16 bit form we have only 5 bit per component, so,
>
>         f := Form extent: 1 asPoint depth: 16.
>         f colorAt: 0 @ 0 put: Color red.
>         f pixelValueAt: 0@0.
>
> yields 0x7C00 aka
>
> 11111 00000 00000
> ^ r   ^ g   ^ b



Reply | Threaded
Open this post in threaded view
|

Re: Bug in Form>>#asFormOfDepth:?

Bob Arning-2
In reply to this post by Tobias Pape
fwiw, Color r: 0.0 g: 0.0 b: 0.004 is squeak's way of representing black in 16 bits so 0 can mean transparent

On 9/9/19 8:56 AM, Tobias Pape wrote:
Other examples:

"Example 2"
f := Form extent: 1 asPoint depth: 1.
f colorAt: 0 @ 0 put: Color red.
g := f asFormOfDepth: 32.
g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"
yes, because you go from black/white to 32bit. I would have expected r0g0b0, but there might some rounding go on.




Reply | Threaded
Open this post in threaded view
|

Re: Bug in Form>>#asFormOfDepth:?

Tobias Pape

> On 09.09.2019, at 17:03, Bob Arning <[hidden email]> wrote:
>
> fwiw, Color r: 0.0 g: 0.0 b: 0.004 is squeak's way of representing black in 16 bits so 0 can mean transparent

ah; i remember. thanks bob!

>
> On 9/9/19 8:56 AM, Tobias Pape wrote:
>>> Other examples:
>>>
>>> "Example 2"
>>> f := Form extent: 1 asPoint depth: 1.
>>> f colorAt: 0 @ 0 put: Color red.
>>> g := f asFormOfDepth: 32.
>>> g colorAt: 0 @ 0 "--> (Color r: 0.0 g: 0.0 b: 0.004)"
>>>
>> yes, because you go from black/white to 32bit. I would have expected r0g0b0, but there might some rounding go on.
>>
>>
>
>