[squeak-dev] The Inbox: Graphics-nice.285.mcz
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Thu Jan 2 14:14:49 UTC 2014
2014/1/1 Tobias Pape <Das.Linux at gmx.de>
>
> On 01.01.2014, at 19:55, commits at source.squeak.org wrote:
>
> > Nicolas Cellier uploaded a new version of Graphics to project The Inbox:
> > http://source.squeak.org/inbox/Graphics-nice.285.mcz
> >
> > ==================== Summary ====================
> >
> > Name: Graphics-nice.285
> > Author: nice
> > Time: 1 January 2014, 8:53:32.416 pm
> > UUID: 04aee02d-83ae-4b4d-aed9-968a6a7487db
> > Ancestors: Graphics-nice.284
> >
> > Change Color implementation from 10 bits per (rgb) component to 8 bits
> per component.
> > Several considerations motivate this change:
> > - no Graphic output is using 10 bits;
>
> Au contraire!
> http://lmgtfy.com/?q=10+bit+graphics
>
> https://nvidia.custhelp.com/app/answers/detail/a_id/3011/~/10-bit-per-color-support-on-nvidia-geforce-gpus
> http://www.luminous-landscape.com/reviews/accessories/10bit.shtml
> http://www.amd.com/us/Documents/10-Bit.pdf
>
> Best
> -Tobias
>
Thanks for the links Tobias, that's interesting.
Well, no graphics output in Squeak was what I meaned.
Squeak is far from being able to exploit those 10 bits, because it would
require
- BitBlt support with a new format (30 bits depth)
- per device gamma correction
It's also unclear for me how the alpha channel is represented/processed
(pre-processed?)
Do you have plans for such support?
Nicolas
>
> > - alpha channel is already stored using 8 bits;
> > - 8 bits matches nowadays most used 32 bits depth Form - thus it's an
> optimization.
> > Note that the tolerance for testing Color components has to be increased
> to a value >= (1/255), I suggest 0.005.
> >
> > =============== Diff against Graphics-nice.284 ===============
> >
> > Item was added:
> > + (PackageInfo named: 'Graphics') preamble: '"Change color components
> from 10 to 8 bits"
> > + Color allSubInstancesDo:
> > + [:c |
> > + | rgb |
> > + rgb := c instVarNamed: ''rgb''.
> > + rgb := (rgb bitAnd: 16r3FC00000) >> 2 + (rgb bitAnd: 16rFF000) >>
> 2 + (rgb bitAnd: 16r3FC) >> 2.
> > + c instVarNamed: ''rgb'' put: rgb; flushCache].'!
> >
> > Item was changed:
> > ----- Method: Color class>>initialize (in category 'class
> initialization') -----
> > initialize
> > "Color initialize"
> >
> > "Details: Externally, the red, green, and blue components of color
> > are floats in the range [0.0..1.0]. Internally, they are
> represented
> > as integers in the range [0..ComponentMask] packing into a
> > small integer to save space and to allow fast hashing and
> > equality testing.
> >
> > For a general description of color representations for computer
> > graphics, including the relationship between the RGB and HSV
> > color models used here, see Chapter 17 of Foley and van Dam,
> > Fundamentals of Interactive Computer Graphics, Addison-Wesley,
> > 1982."
> >
> > + ComponentMask := 255.
> > + HalfComponentMask := 128. "used to round up in integer
> calculations"
> > + ComponentMax := 255.0. "a Float used to normalize components"
> > + RedShift := 16.
> > + GreenShift := 8.
> > - ComponentMask := 1023.
> > - HalfComponentMask := 512. "used to round up in integer
> calculations"
> > - ComponentMax := 1023.0. "a Float used to normalize components"
> > - RedShift := 20.
> > - GreenShift := 10.
> > BlueShift := 0.
> >
> > PureRed := self r: 1 g: 0 b: 0.
> > PureGreen := self r: 0 g: 1 b: 0.
> > PureBlue := self r: 0 g: 0 b: 1.
> > PureYellow := self r: 1 g: 1 b: 0.
> > PureCyan := self r: 0 g: 1 b: 1.
> > PureMagenta := self r: 1 g: 0 b: 1.
> >
> > RandomStream := Random new.
> >
> > self initializeIndexedColors.
> > self initializeGrayToIndexMap.
> > self initializeNames.
> > self initializeHighLights.
> > !
> >
> > Item was changed:
> > ----- Method: Color class>>initializeGrayToIndexMap (in category 'class
> initialization') -----
> > initializeGrayToIndexMap
> > "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."
> > "Note: This method must be called after initializeIndexedColors,
> since it uses IndexedColors."
> > "Color initializeGrayToIndexMap"
> >
> > | grayLevels grayIndices c distToClosest dist indexOfClosest |
> > "record the level and index of each gray in the 8-bit color table"
> > grayLevels := OrderedCollection new.
> > grayIndices := OrderedCollection new.
> > "Note: skip the first entry, which is reserved for transparent"
> > 2 to: IndexedColors size do: [:i |
> > c := IndexedColors at: i.
> > c saturation = 0.0 ifTrue: [ "c is a gray"
> > + grayLevels add: c privateBlue. "top 8 bits; R, G,
> and B are the same"
> > - grayLevels add: (c privateBlue) >> 2. "top 8
> bits; R, G, and B are the same"
> > grayIndices add: i - 1]]. "pixel values are
> zero-based"
> > grayLevels := grayLevels asArray.
> > grayIndices := grayIndices asArray.
> >
> > "for each gray level in [0..255], select the closest match"
> > GrayToIndexMap := ByteArray new: 256.
> > 0 to: 255 do: [:level |
> > distToClosest := 10000. "greater than distance to any
> real gray"
> > 1 to: grayLevels size do: [:i |
> > dist := (level - (grayLevels at: i)) abs.
> > dist < distToClosest ifTrue: [
> > distToClosest := dist.
> > indexOfClosest := grayIndices at: i]].
> > GrayToIndexMap at: (level + 1) put: indexOfClosest].
> > !
> >
> > Item was changed:
> > ----- Method: Color>>asHTMLColor (in category 'conversions') -----
> > asHTMLColor
> > + ^'#' , (rgb printStringBase: 16 length: 6 padded: true)!
> > - | s |
> > - s := '#000000' copy.
> > - s at: 2 put: (Character digitValue: ((rgb bitShift: -6 - RedShift)
> bitAnd: 15)).
> > - s at: 3 put: (Character digitValue: ((rgb bitShift: -2 - RedShift)
> bitAnd: 15)).
> > - s at: 4 put: (Character digitValue: ((rgb bitShift: -6 -
> GreenShift) bitAnd: 15)).
> > - s at: 5 put: (Character digitValue: ((rgb bitShift: -2 -
> GreenShift) bitAnd: 15)).
> > - s at: 6 put: (Character digitValue: ((rgb bitShift: -6 -
> BlueShift) bitAnd: 15)).
> > - s at: 7 put: (Character digitValue: ((rgb bitShift: -2 -
> BlueShift) bitAnd: 15)).
> > - ^ s!
> >
> > Item was changed:
> > ----- Method: Color>>closestPixelValue1 (in category 'conversions')
> -----
> > closestPixelValue1
> > "Return the nearest approximation to this color for a monochrome
> Form."
> >
> > "fast special cases"
> > rgb = 0 ifTrue: [^ 1]. "black"
> > + rgb = 16rFFFFFFF ifTrue: [^ 0]. "white"
> > - rgb = 16r3FFFFFFF ifTrue: [^ 0]. "white"
> >
> > self luminance > 0.5
> > ifTrue: [^ 0] "white"
> > ifFalse: [^ 1]. "black"
> > !
> >
> > Item was changed:
> > ----- Method: Color>>closestPixelValue2 (in category 'conversions')
> -----
> > closestPixelValue2
> > "Return the nearest approximation to this color for a 2-bit deep
> Form."
> >
> > | lum |
> > "fast special cases"
> > rgb = 0 ifTrue: [^ 1]. "black"
> > + rgb = 16rFFFFFFF ifTrue: [^ 2]. "opaque white"
> > - rgb = 16r3FFFFFFF ifTrue: [^ 2]. "opaque white"
> >
> > lum := self luminance.
> > lum < 0.2 ifTrue: [^ 1]. "black"
> > lum > 0.6 ifTrue: [^ 2]. "opaque white"
> > ^ 3 "50% gray"
> > !
> >
> > Item was changed:
> > ----- Method: Color>>closestPixelValue4 (in category 'conversions')
> -----
> > closestPixelValue4
> > "Return the nearest approximation to this color for a 4-bit deep
> Form."
> >
> > | bIndex |
> > "fast special cases"
> > rgb = 0 ifTrue: [^ 1]. "black"
> > + rgb = 16rFFFFFFF ifTrue: [^ 2]. "opaque white"
> > - rgb = 16r3FFFFFFF ifTrue: [^ 2]. "opaque white"
> >
> > rgb = PureRed privateRGB ifTrue: [^ 4].
> > rgb = PureGreen privateRGB ifTrue: [^ 5].
> > rgb = PureBlue privateRGB ifTrue: [^ 6].
> > rgb = PureCyan privateRGB ifTrue: [^ 7].
> > rgb = PureYellow privateRGB ifTrue: [^ 8].
> > rgb = PureMagenta privateRGB ifTrue: [^ 9].
> >
> > bIndex := (self luminance * 8.0) rounded. "bIndex in [0..8]"
> > ^ #(
> > 1 "black"
> > 10 "1/8 gray"
> > 11 "2/8 gray"
> > 12 "3/8 gray"
> > 3 "4/8 gray"
> > 13 "5/8 gray"
> > 14 "6/8 gray"
> > 15 "7/8 gray"
> > 2 "opaque white"
> > ) at: bIndex + 1.
> > !
> >
> > Item was changed:
> > ----- Method: Color>>closestPixelValue8 (in category 'conversions')
> -----
> > closestPixelValue8
> > "Return the nearest approximation to this color for an 8-bit deep
> Form."
> >
> > "fast special cases"
> > rgb = 0 ifTrue: [^ 1]. "black"
> > + rgb = 16rFFFFFFF ifTrue: [^ 255]. "white"
> > - rgb = 16r3FFFFFFF ifTrue: [^ 255]. "white"
> >
> > self saturation < 0.2 ifTrue: [
> > + ^ GrayToIndexMap at: self privateGreen + 1. "nearest gray"
> > - ^ GrayToIndexMap at: (self privateGreen >> 2) + 1.
> "nearest gray"
> > ] ifFalse: [
> > "compute nearest entry in the color cube"
> > ^ 40 +
> > ((((self privateRed * 5) + HalfComponentMask) //
> ComponentMask) * 36) +
> > ((((self privateBlue * 5) + HalfComponentMask) //
> ComponentMask) * 6) +
> > (((self privateGreen * 5) + HalfComponentMask) //
> ComponentMask)].
> > !
> >
> > Item was changed:
> > ----- Method: Color>>pixelValueForDepth: (in category 'conversions')
> -----
> > pixelValueForDepth: d
> > "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:"
> > "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."
> > "Transparency: The pixel value zero is reserved for transparent.
> For depths greater than 8, black maps to the darkest possible blue."
> >
> > | val |
> > d > 8 "most common case"
> > ifTrue:
> > [d = 32 ifTrue: [
> > "eight bits per component; top 8 bits set
> to all ones (opaque alpha)"
> > + ^rgb = 0 ifTrue: [16rFF000001] ifFalse:
> [rgb bitOr: 16rFF000000]].
> > - val := (LargePositiveInteger new: 4)
> > - at: 4 put: 16rFF;
> > - at: 3 put: ((rgb bitShift: -22)
> bitAnd: 16rFF);
> > - at: 2 put: ((rgb bitShift: -12)
> bitAnd: 16rFF);
> > - at: 1 put: ((rgb bitShift: -2)
> bitAnd: 16rFF);
> > - normalize. "normalize is not
> necessary as long as SmallInteger maxVal highBit < 32, but let's be future
> proof"
> > - ^val < 16rFF000001 ifTrue: [16rFF000001]
> ifFalse: [val]].
> >
> > d = 16 ifTrue: [
> > "five bits per component; top bits ignored"
> > + val := (((rgb bitShift: -9) bitAnd:
> 16r7C00) bitOr:
> > + ((rgb bitShift: -6) bitAnd:
> 16r03E0)) bitOr:
> > + ((rgb bitShift: -3) bitAnd:
> 16r001F).
> > - val := (((rgb bitShift: -15) bitAnd:
> 16r7C00) bitOr:
> > - ((rgb bitShift: -10) bitAnd:
> 16r03E0)) bitOr:
> > - ((rgb bitShift: -5) bitAnd:
> 16r001F).
> > ^val < 1 ifTrue: [1] ifFalse: [val]].
> >
> > d = 12 ifTrue: [ "for indexing a color map with 4
> bits per color component"
> > + val := (((rgb bitShift: -12) bitAnd:
> 16r0F00) bitOr:
> > + ((rgb bitShift: -8) bitAnd:
> 16r00F0)) bitOr:
> > + ((rgb bitShift: -4) bitAnd:
> 16r000F).
> > - val := (((rgb bitShift: -18) bitAnd:
> 16r0F00) bitOr:
> > - ((rgb bitShift: -12) bitAnd:
> 16r00F0)) bitOr:
> > - ((rgb bitShift: -6) bitAnd:
> 16r000F).
> > ^val < 1 ifTrue: [1] ifFalse: [val]].
> >
> > d = 9 ifTrue: [ "for indexing a color map with 3
> bits per color component"
> > + val := (((rgb bitShift: -15) bitAnd:
> 16r01C0) bitOr:
> > + ((rgb bitShift: -10) bitAnd:
> 16r0038)) bitOr:
> > + ((rgb bitShift: -5) bitAnd:
> 16r0007).
> > - val := (((rgb bitShift: -21) bitAnd:
> 16r01C0) bitOr:
> > - ((rgb bitShift: -14) bitAnd:
> 16r0038)) bitOr:
> > - ((rgb bitShift: -7) bitAnd:
> 16r0007).
> > ^val < 1 ifTrue: [1] ifFalse: [val]]].
> > d = 8 ifTrue: [^ self closestPixelValue8].
> > d = 4 ifTrue: [^ self closestPixelValue4].
> > d = 2 ifTrue: [^ self closestPixelValue2]..
> > d = 1 ifTrue: [^ self closestPixelValue1].
> >
> > self error: 'unknown pixel depth: ', d printString
> > !
> >
> > Item was added:
> > + (PackageInfo named: 'Graphics') postscript: '"The cache might hold
> incorrect values during 10->8 bits per component transition"
> > + Color allSubInstancesDo: [:c | c flushCache].'!
> >
> >
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140102/03b5d0a8/attachment.htm
More information about the Squeak-dev
mailing list
|