<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">2014/1/1 Tobias Pape <span dir="ltr">&lt;<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div><br>
On 01.01.2014, at 19:55, <a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> wrote:<br>
<br>
&gt; Nicolas Cellier uploaded a new version of Graphics to project The Inbox:<br>
&gt; <a href="http://source.squeak.org/inbox/Graphics-nice.285.mcz" target="_blank">http://source.squeak.org/inbox/Graphics-nice.285.mcz</a><br>
&gt;<br>
&gt; ==================== Summary ====================<br>
&gt;<br>
&gt; Name: Graphics-nice.285<br>
&gt; Author: nice<br>
&gt; Time: 1 January 2014, 8:53:32.416 pm<br>
&gt; UUID: 04aee02d-83ae-4b4d-aed9-968a6a7487db<br>
&gt; Ancestors: Graphics-nice.284<br>
&gt;<br>
&gt; Change Color implementation from 10 bits per (rgb) component to 8 bits per component.<br>
&gt; Several considerations motivate this change:<br>
&gt; - no Graphic output is using 10 bits;<br>
<br>
</div>Au contraire!<br>
<a href="http://lmgtfy.com/?q=10+bit+graphics" target="_blank">http://lmgtfy.com/?q=10+bit+graphics</a><br>
<a href="https://nvidia.custhelp.com/app/answers/detail/a_id/3011/~/10-bit-per-color-support-on-nvidia-geforce-gpus" target="_blank">https://nvidia.custhelp.com/app/answers/detail/a_id/3011/~/10-bit-per-color-support-on-nvidia-geforce-gpus</a><br>



<a href="http://www.luminous-landscape.com/reviews/accessories/10bit.shtml" target="_blank">http://www.luminous-landscape.com/reviews/accessories/10bit.shtml</a><br>
<a href="http://www.amd.com/us/Documents/10-Bit.pdf" target="_blank">http://www.amd.com/us/Documents/10-Bit.pdf</a><br>
<br>
Best<br>
<span><font color="#888888">        -Tobias<br></font></span></blockquote><div><br></div><div>Thanks for the links Tobias, that&#39;s interesting.<br></div><div>Well, no graphics output in Squeak was what I meaned.<br></div>
<div>Squeak is far from being able to exploit those 10 bits, because it would require<br></div><div>- BitBlt support with a new format (30 bits depth)<br></div><div>- per device gamma correction<br></div><div>It&#39;s also unclear for me how the alpha channel is represented/processed (pre-processed?)<br>
<br></div><div>Do you have plans for such support?<br><br></div><div>Nicolas<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<span><font color="#888888">
</font></span><div><div><br>
&gt; - alpha channel is already stored using 8 bits;<br>
&gt; - 8 bits matches nowadays most used 32 bits depth Form - thus it&#39;s an optimization.<br>
&gt; Note that the tolerance for testing Color components has to be increased to a value &gt;= (1/255), I suggest 0.005.<br>
&gt;<br>
&gt; =============== Diff against Graphics-nice.284 ===============<br>
&gt;<br>
&gt; Item was added:<br>
&gt; + (PackageInfo named: &#39;Graphics&#39;) preamble: &#39;&quot;Change color components from 10 to 8 bits&quot;<br>
&gt; + Color allSubInstancesDo:<br>
&gt; +     [:c |<br>
&gt; +     | rgb |<br>
&gt; +     rgb := c instVarNamed: &#39;&#39;rgb&#39;&#39;.<br>
&gt; +     rgb := (rgb bitAnd: 16r3FC00000) &gt;&gt; 2 + (rgb bitAnd: 16rFF000) &gt;&gt; 2 + (rgb bitAnd: 16r3FC) &gt;&gt; 2.<br>
&gt; +     c instVarNamed: &#39;&#39;rgb&#39;&#39; put: rgb; flushCache].&#39;!<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color class&gt;&gt;initialize (in category &#39;class initialization&#39;) -----<br>
&gt;  initialize<br>
&gt;       &quot;Color initialize&quot;<br>
&gt;<br>
&gt;       &quot;Details: Externally, the red, green, and blue components of color<br>
&gt;       are floats in the range [0.0..1.0]. Internally, they are represented<br>
&gt;       as integers in the range [0..ComponentMask] packing into a<br>
&gt;       small integer to save space and to allow fast hashing and<br>
&gt;       equality testing.<br>
&gt;<br>
&gt;       For a general description of color representations for computer<br>
&gt;       graphics, including the relationship between the RGB and HSV<br>
&gt;       color models used here, see Chapter 17 of Foley and van Dam,<br>
&gt;       Fundamentals of Interactive Computer Graphics, Addison-Wesley,<br>
&gt;       1982.&quot;<br>
&gt;<br>
&gt; +     ComponentMask := 255.<br>
&gt; +     HalfComponentMask := 128.  &quot;used to round up in integer calculations&quot;<br>
&gt; +     ComponentMax := 255.0.  &quot;a Float used to normalize components&quot;<br>
&gt; +     RedShift := 16.<br>
&gt; +     GreenShift := 8.<br>
&gt; -     ComponentMask := 1023.<br>
&gt; -     HalfComponentMask := 512.  &quot;used to round up in integer calculations&quot;<br>
&gt; -     ComponentMax := 1023.0.  &quot;a Float used to normalize components&quot;<br>
&gt; -     RedShift := 20.<br>
&gt; -     GreenShift := 10.<br>
&gt;       BlueShift := 0.<br>
&gt;<br>
&gt;       PureRed          := self r: 1 g: 0 b: 0.<br>
&gt;       PureGreen        := self r: 0 g: 1 b: 0.<br>
&gt;       PureBlue         := self r: 0 g: 0 b: 1.<br>
&gt;       PureYellow       := self r: 1 g: 1 b: 0.<br>
&gt;       PureCyan         := self r: 0 g: 1 b: 1.<br>
&gt;       PureMagenta := self r: 1 g: 0 b: 1.<br>
&gt;<br>
&gt;       RandomStream := Random new.<br>
&gt;<br>
&gt;       self initializeIndexedColors.<br>
&gt;       self initializeGrayToIndexMap.<br>
&gt;       self initializeNames.<br>
&gt;       self initializeHighLights.<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color class&gt;&gt;initializeGrayToIndexMap (in category &#39;class initialization&#39;) -----<br>
&gt;  initializeGrayToIndexMap<br>
&gt;       &quot;Build an array of gray values available in the 8-bit colormap. This array is indexed by a gray level between black (1) and white (256) and returns the pixel value for the corresponding gray level.&quot;<br>



&gt;       &quot;Note: This method must be called after initializeIndexedColors, since it uses IndexedColors.&quot;<br>
&gt;       &quot;Color initializeGrayToIndexMap&quot;<br>
&gt;<br>
&gt;       | grayLevels grayIndices c distToClosest dist indexOfClosest |<br>
&gt;       &quot;record the level and index of each gray in the 8-bit color table&quot;<br>
&gt;       grayLevels := OrderedCollection new.<br>
&gt;       grayIndices := OrderedCollection new.<br>
&gt;       &quot;Note: skip the first entry, which is reserved for transparent&quot;<br>
&gt;       2 to: IndexedColors size do: [:i |<br>
&gt;               c := IndexedColors at: i.<br>
&gt;               c saturation = 0.0 ifTrue: [  &quot;c is a gray&quot;<br>
&gt; +                     grayLevels add: c privateBlue.  &quot;top 8 bits; R, G, and B are the same&quot;<br>
&gt; -                     grayLevels add: (c privateBlue) &gt;&gt; 2.  &quot;top 8 bits; R, G, and B are the same&quot;<br>
&gt;                       grayIndices add: i - 1]].  &quot;pixel values are zero-based&quot;<br>
&gt;       grayLevels := grayLevels asArray.<br>
&gt;       grayIndices := grayIndices asArray.<br>
&gt;<br>
&gt;       &quot;for each gray level in [0..255], select the closest match&quot;<br>
&gt;       GrayToIndexMap := ByteArray new: 256.<br>
&gt;       0 to: 255 do: [:level |<br>
&gt;               distToClosest := 10000.  &quot;greater than distance to any real gray&quot;<br>
&gt;               1 to: grayLevels size do: [:i |<br>
&gt;                       dist := (level - (grayLevels at: i)) abs.<br>
&gt;                       dist &lt; distToClosest ifTrue: [<br>
&gt;                               distToClosest := dist.<br>
&gt;                               indexOfClosest := grayIndices at: i]].<br>
&gt;               GrayToIndexMap at: (level + 1) put: indexOfClosest].<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;asHTMLColor (in category &#39;conversions&#39;) -----<br>
&gt;  asHTMLColor<br>
&gt; +     ^&#39;#&#39; , (rgb printStringBase: 16 length: 6 padded: true)!<br>
&gt; -     | s |<br>
&gt; -     s := &#39;#000000&#39; copy.<br>
&gt; -     s at: 2 put: (Character digitValue: ((rgb bitShift: -6 - RedShift) bitAnd: 15)).<br>
&gt; -     s at: 3 put: (Character digitValue: ((rgb bitShift: -2 - RedShift) bitAnd: 15)).<br>
&gt; -     s at: 4 put: (Character digitValue: ((rgb bitShift: -6 - GreenShift) bitAnd: 15)).<br>
&gt; -     s at: 5 put: (Character digitValue: ((rgb bitShift: -2 - GreenShift) bitAnd: 15)).<br>
&gt; -     s at: 6 put: (Character digitValue: ((rgb bitShift: -6 - BlueShift) bitAnd: 15)).<br>
&gt; -     s at: 7 put: (Character digitValue: ((rgb bitShift: -2 - BlueShift) bitAnd: 15)).<br>
&gt; -     ^ s!<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;closestPixelValue1 (in category &#39;conversions&#39;) -----<br>
&gt;  closestPixelValue1<br>
&gt;       &quot;Return the nearest approximation to this color for a monochrome Form.&quot;<br>
&gt;<br>
&gt;       &quot;fast special cases&quot;<br>
&gt;       rgb = 0 ifTrue: [^ 1].  &quot;black&quot;<br>
&gt; +     rgb = 16rFFFFFFF ifTrue: [^ 0].  &quot;white&quot;<br>
&gt; -     rgb = 16r3FFFFFFF ifTrue: [^ 0].  &quot;white&quot;<br>
&gt;<br>
&gt;       self luminance &gt; 0.5<br>
&gt;               ifTrue: [^ 0]  &quot;white&quot;<br>
&gt;               ifFalse: [^ 1].  &quot;black&quot;<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;closestPixelValue2 (in category &#39;conversions&#39;) -----<br>
&gt;  closestPixelValue2<br>
&gt;       &quot;Return the nearest approximation to this color for a 2-bit deep Form.&quot;<br>
&gt;<br>
&gt;       | lum |<br>
&gt;       &quot;fast special cases&quot;<br>
&gt;       rgb = 0 ifTrue: [^ 1].  &quot;black&quot;<br>
&gt; +     rgb = 16rFFFFFFF ifTrue: [^ 2].  &quot;opaque white&quot;<br>
&gt; -     rgb = 16r3FFFFFFF ifTrue: [^ 2].  &quot;opaque white&quot;<br>
&gt;<br>
&gt;       lum := self luminance.<br>
&gt;       lum &lt; 0.2 ifTrue: [^ 1].  &quot;black&quot;<br>
&gt;       lum &gt; 0.6 ifTrue: [^ 2].  &quot;opaque white&quot;<br>
&gt;       ^ 3  &quot;50% gray&quot;<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;closestPixelValue4 (in category &#39;conversions&#39;) -----<br>
&gt;  closestPixelValue4<br>
&gt;       &quot;Return the nearest approximation to this color for a 4-bit deep Form.&quot;<br>
&gt;<br>
&gt;       | bIndex |<br>
&gt;       &quot;fast special cases&quot;<br>
&gt;       rgb = 0 ifTrue: [^ 1].  &quot;black&quot;<br>
&gt; +     rgb = 16rFFFFFFF ifTrue: [^ 2].  &quot;opaque white&quot;<br>
&gt; -     rgb = 16r3FFFFFFF ifTrue: [^ 2].  &quot;opaque white&quot;<br>
&gt;<br>
&gt;       rgb = PureRed privateRGB ifTrue: [^ 4].<br>
&gt;       rgb = PureGreen privateRGB ifTrue: [^ 5].<br>
&gt;       rgb = PureBlue privateRGB ifTrue: [^ 6].<br>
&gt;       rgb = PureCyan privateRGB ifTrue: [^ 7].<br>
&gt;       rgb = PureYellow privateRGB ifTrue: [^ 8].<br>
&gt;       rgb = PureMagenta privateRGB ifTrue: [^ 9].<br>
&gt;<br>
&gt;       bIndex := (self luminance * 8.0) rounded.  &quot;bIndex in [0..8]&quot;<br>
&gt;       ^ #(<br>
&gt;               1       &quot;black&quot;<br>
&gt;               10      &quot;1/8 gray&quot;<br>
&gt;               11      &quot;2/8 gray&quot;<br>
&gt;               12      &quot;3/8 gray&quot;<br>
&gt;               3       &quot;4/8 gray&quot;<br>
&gt;               13      &quot;5/8 gray&quot;<br>
&gt;               14      &quot;6/8 gray&quot;<br>
&gt;               15      &quot;7/8 gray&quot;<br>
&gt;               2       &quot;opaque white&quot;<br>
&gt;       ) at: bIndex + 1.<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;closestPixelValue8 (in category &#39;conversions&#39;) -----<br>
&gt;  closestPixelValue8<br>
&gt;       &quot;Return the nearest approximation to this color for an 8-bit deep Form.&quot;<br>
&gt;<br>
&gt;       &quot;fast special cases&quot;<br>
&gt;       rgb = 0 ifTrue: [^ 1].  &quot;black&quot;<br>
&gt; +     rgb = 16rFFFFFFF ifTrue: [^ 255].  &quot;white&quot;<br>
&gt; -     rgb = 16r3FFFFFFF ifTrue: [^ 255].  &quot;white&quot;<br>
&gt;<br>
&gt;       self saturation &lt; 0.2 ifTrue: [<br>
&gt; +             ^ GrayToIndexMap at: self privateGreen + 1.  &quot;nearest gray&quot;<br>
&gt; -             ^ GrayToIndexMap at: (self privateGreen &gt;&gt; 2) + 1.  &quot;nearest gray&quot;<br>
&gt;       ] ifFalse: [<br>
&gt;               &quot;compute nearest entry in the color cube&quot;<br>
&gt;               ^ 40 +<br>
&gt;                 ((((self privateRed * 5) + HalfComponentMask) // ComponentMask) * 36) +<br>
&gt;                 ((((self privateBlue * 5) + HalfComponentMask) // ComponentMask) * 6) +<br>
&gt;                 (((self privateGreen * 5) + HalfComponentMask) // ComponentMask)].<br>
&gt;  !<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Color&gt;&gt;pixelValueForDepth: (in category &#39;conversions&#39;) -----<br>
&gt;  pixelValueForDepth: d<br>
&gt;       &quot;Returns an integer representing the bits that appear in a single pixel of this color in a Form of the given depth. The depth must be one of 1, 2, 4, 8, 16, or 32. Contrast with pixelWordForDepth: and bitPatternForDepth:, which return either a 32-bit word packed with the given pixel value or a multiple-word Bitmap containing a pattern. The inverse is the class message colorFromPixelValue:depth:&quot;<br>



&gt;       &quot;Details: For depths of 8 or less, the result is a colorMap index. For depths of 16 and 32, it is a direct color value with 5 or 8 bits per color component.&quot;<br>
&gt;       &quot;Transparency: The pixel value zero is reserved for transparent. For depths greater than 8, black maps to the darkest possible blue.&quot;<br>
&gt;<br>
&gt;       | val |<br>
&gt;       d &gt; 8 &quot;most common case&quot;<br>
&gt;               ifTrue:<br>
&gt;                       [d = 32 ifTrue: [<br>
&gt;                               &quot;eight bits per component; top 8 bits set to all ones (opaque alpha)&quot;<br>
&gt; +                             ^rgb = 0 ifTrue: [16rFF000001] ifFalse: [rgb bitOr: 16rFF000000]].<br>
&gt; -                             val := (LargePositiveInteger new: 4)<br>
&gt; -                                     at: 4 put: 16rFF;<br>
&gt; -                                     at: 3 put: ((rgb bitShift: -22) bitAnd: 16rFF);<br>
&gt; -                                     at: 2 put: ((rgb bitShift: -12) bitAnd: 16rFF);<br>
&gt; -                                     at: 1 put: ((rgb bitShift: -2) bitAnd: 16rFF);<br>
&gt; -                                     normalize. &quot;normalize is not necessary as long as SmallInteger maxVal highBit &lt; 32, but let&#39;s be future proof&quot;<br>
&gt; -                             ^val &lt; 16rFF000001 ifTrue: [16rFF000001] ifFalse: [val]].<br>
&gt;<br>
&gt;                       d = 16 ifTrue: [<br>
&gt;                               &quot;five bits per component; top bits ignored&quot;<br>
&gt; +                             val := (((rgb bitShift: -9) bitAnd: 16r7C00) bitOr:<br>
&gt; +                                      ((rgb bitShift: -6) bitAnd: 16r03E0)) bitOr:<br>
&gt; +                                      ((rgb bitShift: -3) bitAnd: 16r001F).<br>
&gt; -                             val := (((rgb bitShift: -15) bitAnd: 16r7C00) bitOr:<br>
&gt; -                                      ((rgb bitShift: -10) bitAnd: 16r03E0)) bitOr:<br>
&gt; -                                      ((rgb bitShift: -5) bitAnd: 16r001F).<br>
&gt;                               ^val &lt; 1 ifTrue: [1] ifFalse: [val]].<br>
&gt;<br>
&gt;                       d = 12 ifTrue: [  &quot;for indexing a color map with 4 bits per color component&quot;<br>
&gt; +                             val := (((rgb bitShift: -12) bitAnd: 16r0F00) bitOr:<br>
&gt; +                                      ((rgb bitShift: -8) bitAnd: 16r00F0)) bitOr:<br>
&gt; +                                      ((rgb bitShift: -4) bitAnd: 16r000F).<br>
&gt; -                             val := (((rgb bitShift: -18) bitAnd: 16r0F00) bitOr:<br>
&gt; -                                      ((rgb bitShift: -12) bitAnd: 16r00F0)) bitOr:<br>
&gt; -                                      ((rgb bitShift: -6) bitAnd: 16r000F).<br>
&gt;                               ^val &lt; 1 ifTrue: [1] ifFalse: [val]].<br>
&gt;<br>
&gt;                       d = 9 ifTrue: [  &quot;for indexing a color map with 3 bits per color component&quot;<br>
&gt; +                             val := (((rgb bitShift: -15) bitAnd: 16r01C0) bitOr:<br>
&gt; +                                      ((rgb bitShift: -10) bitAnd: 16r0038)) bitOr:<br>
&gt; +                                      ((rgb bitShift: -5) bitAnd: 16r0007).<br>
&gt; -                             val := (((rgb bitShift: -21) bitAnd: 16r01C0) bitOr:<br>
&gt; -                                      ((rgb bitShift: -14) bitAnd: 16r0038)) bitOr:<br>
&gt; -                                      ((rgb bitShift: -7) bitAnd: 16r0007).<br>
&gt;                               ^val &lt; 1 ifTrue: [1] ifFalse: [val]]].<br>
&gt;       d = 8 ifTrue: [^ self closestPixelValue8].<br>
&gt;       d = 4 ifTrue: [^ self closestPixelValue4].<br>
&gt;       d = 2 ifTrue: [^ self closestPixelValue2]..<br>
&gt;       d = 1 ifTrue: [^ self closestPixelValue1].<br>
&gt;<br>
&gt;       self error: &#39;unknown pixel depth: &#39;, d printString<br>
&gt;  !<br>
&gt;<br>
&gt; Item was added:<br>
&gt; + (PackageInfo named: &#39;Graphics&#39;) postscript: &#39;&quot;The cache might hold incorrect values during 10-&gt;8 bits per component transition&quot;<br>
&gt; + Color allSubInstancesDo: [:c | c flushCache].&#39;!<br>
&gt;<br>
&gt;<br>
<br>
</div></div><br><br>
<br></blockquote></div><br></div></div>