[squeak-dev] The Trunk: Graphics-nice.536.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Aug 21 21:17:01 UTC 2022


Hi Karl,
Specifying Color with a Number between 0 and 1 is the right way.
It can also be a Fraction, not necessarily a Float.
Specifying scaled component (i.e. in [0..255]) and scale (range) thru
r:g:b:range: is a possible alternative, convenient for example for
converting HTML color spec to Squeak Color. Since we often do that, this is
the point of this micro-optimization.

10 bits per Color channel is an implementation detail. We use Integer
because BitBlt works on Integer not Floats.
It fits well in (32 bits) Squeak, because 30 bits positive integers fit in
a SmallInteger, so I guess that it has driven the design.
But for example, Cuis has made another choice to stick to Float.

How many bits really matter depends where Color is used.
Most often, we use only 8 most significant bits in 32bits deep Form (with
ARGB format).
It can be less in less deep Form (see pixelValueForDepth:)
I once proposed to change internal representation and switch to 8 bits.
https://source.squeak.org/inbox/Graphics-nice.285.diff

But it was objected that it's not really simplifying implementation.
http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-January/175863.html


Le dim. 21 août 2022 à 21:07, karl ramberg <karlramberg at gmail.com> a écrit :

> Hi,
> I read in comment for Color:
> "(r, b and g) amount, 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.)"
>
> But in several places colors are also represented as 0 to 255 for r, g, b
> and alpha.
> So when are we using 8 bits and when are we using 10 bits for each color
> value?
>
> Best,
> Karl
>
>
>
>
>
> On Sun, Aug 21, 2022 at 5:37 PM <commits at source.squeak.org> wrote:
>
>> Nicolas Cellier uploaded a new version of Graphics to project The Trunk:
>> http://source.squeak.org/trunk/Graphics-nice.536.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Graphics-nice.536
>> Author: nice
>> Time: 21 August 2022, 5:36:40.736262 pm
>> UUID: a4930d0f-a408-724e-b9e0-4eb4841607e3
>> Ancestors: Graphics-nice.535
>>
>> Further accelerate Color creation from 8 bits components.
>>
>> For this we pre-multiply the constants by the destination shift - 8, so
>> as to omit the right shift >> 8 followed by the left shift <<
>> Red/GreenShift.
>> - RedShift = 20 bits, 16r403 >> (20-8) = 16r403000
>> - GreenShift = 10 bits, 16r403 >> (10-8) = 16r100C
>>
>> =============== Diff against Graphics-nice.535 ===============
>>
>> Item was changed:
>>   ----- Method: Color>>setRed8:green8:blue8: (in category 'private') -----
>>   setRed8: r green8: g blue8: b
>>         "Initialize this color's r, g, and b components to the given
>> values in the range [0..255].
>>         Use an optimized operation rather than a slow division"
>>
>>         "
>>         self assert: ((0 to: 255) allSatisfy: [:e | (e*1023/255) rounded
>> = (e * 16r403 + 16r81 >> 8)]).
>>         "
>>
>>         ComponentMax = 1023 ifFalse: [^self setRed: r / 255 green: g /
>> 255 blue: b / 255].
>>         rgb == nil ifFalse: [self attemptToMutateError].
>> +       rgb := (r* 16r403000 + 16r81000 bitAnd: 16r3FF00000
>> "ComponentMask << RedShift" )
>> +               + (g* 16r100C + 16r204 bitAnd: 16rFFC00 "ComponentMask <<
>> GreenShift" )
>> +               + (b* 16r403 + 16r81 >> 8).
>> -       rgb := ((r* 16r403 + 16r81 >> 8) bitShift: RedShift)
>> -               + ((g* 16r403 + 16r81 >> 8) bitShift: GreenShift)
>> -               + ((b* 16r403 + 16r81 >> 8)).
>>         cachedDepth := nil.
>>         cachedBitPattern := nil.!
>>
>> Item was changed:
>>   ----- Method: Color>>setRed:green:blue:range: (in category 'private')
>> -----
>>   setRed: r green: g blue: b range: range
>>         "Initialize this color's r, g, and b components to the given
>> values in the range [0..r]."
>>
>> +       range = ComponentMax  ifTrue: [^self setPrivateRed: r green: g
>> blue: b].
>>         range = 255 ifTrue: [^self setRed8: r green8: g blue8: b].
>>         ^ self setRed: r / range green: g / range blue: b / range!
>>
>> Item was changed:
>>   DisplayMedium subclass: #Form
>>         instanceVariableNames: 'bits width height depth offset'
>>         classVariableNames: 'CompressOnSnapshot'
>>         poolDictionaries: ''
>>         category: 'Graphics-Display Objects'!
>>
>> + !Form commentStamp: 'nice 5/3/2020 18:04' prior: 0!
>> - !Form commentStamp: 'cbc 5/5/2017 10:07' prior: 0!
>>   A rectangular array of pixels, used for holding images.  All pictures,
>> including character images are Forms.  The depth of a Form is how many bits
>> are used to specify the color at each pixel.  The actual bits are held in a
>> Bitmap, whose internal structure is different at each depth.  Class Color
>> allows you to deal with colors without knowing how they are actually
>> encoded inside a Bitmap.
>>           The supported depths (in bits) are 1, 2, 4, 8, 16, and 32.  The
>> number of actual colors at these depths are: 2, 4, 16, 256, 32768, and 16
>> million.
>>         Forms are indexed starting at 0 instead of 1; thus, the top-left
>> pixel of a Form has coordinates 0 at 0.
>>         Forms are combined using BitBlt.  See the comment in class
>> BitBlt.  Forms that repeat many times to fill a large destination are
>> InfiniteForms.
>>
>>         colorAt: x at y            Returns the abstract Color at this
>> location
>>         displayAt: x at y          shows this form on the screen
>>         displayOn: aMedium at: x at y      shows this form in a Window, a
>> Form, or other DisplayMedium
>>         fillColor: aColor               Set all the pixels to the color.
>>         edit            launch an editor to change the bits of this form.
>>         pixelValueAt: x at y       The encoded color.  The encoding depends
>> on the depth.
>>
>> + Details about internal format for Bitmap:
>> + Pixels are organised left to right, top to bottom, that is as a
>> contiguous serie of lines.
>> + Each pixel is made of a fixed quantity of bits (depth).
>> + Thus a Bitmap can be viewed as a rectangular area of size (width*depth
>> x height) in bits.
>> + However, the beginning of each line in the bitmap must fall on a 32-bit
>> word boundary.
>> + Thus the actual bitSize of a line is rounded up to next multiple of 32.
>> + The Bitmap may somehow have unsued bits near the end of each line.
>> +
>> + Note: If you want to hook up other external forms/displayScreens,
>> please look at the (successful) Graphics-External package in
>> http://www.squeaksource.com/Balloon3D.
>> +
>> + !
>> - Note: If you want to hook up other external forms/displayScreens,
>> please look at the (successful) Graphics-External package in
>> http://www.squeaksource.com/Balloon3D.!
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220821/c8147683/attachment-0001.html>


More information about the Squeak-dev mailing list