[squeak-dev] Color from pixel value bug

Stéphane Rollandin lecteur at zogotounga.net
Mon Oct 3 08:27:00 UTC 2011


Hello,

Working in Squeak 4.1, I stumbled upon a PNG image saving bug, which I 
traced down to the fact that

((Color black pixelWordForDepth: 32) asColorOfDepth: 32)
  = Color black

is false.

I found something looking like a fix, which is attached.

Then I looked at Squeak 4.3 (update 11636) to see if someone else 
already fixed that bug, and indeed Nicolas Cellier did, in December 
2010, by modifying Color>>pixelValueForDepth:

But we still have

((Color black pixelWordForDepth: 32) asColorOfDepth: 32)
  = Color black

false, because black is being replaced with, as the comment says, the 
"closest non-transparent black"

At this point I guess I missed something, since I have no idea of what 
this business of "transparent black" is about.

Nicolas, could you please tell if my fix is correct ?

Best,


Stef
-------------- next part --------------
'From Squeak4.1 of 17 April 2010 [latest update: #9957] on 3 October 2011 at 10:14:24 am'!

!Color class methodsFor: 'instance creation' stamp: 'spfa 10/3/2011 10:14'!
colorFromPixelValue: p depth: d
	"Convert a pixel value for the given display depth into a color."
	"Details: For depths of 8 or less, the pixel value is simply looked up in a table. For greater depths, the color components are extracted and converted into a color."

	| r g b alpha |
	d = 8 ifTrue: [^ IndexedColors at: (p bitAnd: 16rFF) + 1].
	d = 4 ifTrue: [^ IndexedColors at: (p bitAnd: 16r0F) + 1].
	d = 2 ifTrue: [^ IndexedColors at: (p bitAnd: 16r03) + 1].
	d = 1 ifTrue: [^ IndexedColors at: (p bitAnd: 16r01) + 1].

	(d = 16) | (d = 15) ifTrue: [
		"five bits per component"
		r := (p bitShift: -10) bitAnd: 16r1F.
		g := (p bitShift: -5) bitAnd: 16r1F.
		b := p bitAnd: 16r1F.
		(r = 0 and: [g = 0]) ifTrue: [
			b = 0 ifTrue: [^Color transparent].
			b = 1 ifTrue: [^Color black]].
		^ Color r: r g: g b: b range: 31].

	d = 32 ifTrue: [
		"eight bits per component; 8 bits of alpha"
		r := (p bitShift: -16) bitAnd: 16rFF.
		g := (p bitShift: -8) bitAnd: 16rFF.
		b := p bitAnd: 16rFF.
		alpha := p bitShift: -24.
		alpha = 0 ifTrue: [^Color transparent].
		alpha < 255 ifTrue: [
				(r = 0 and: [g = 0 and: [b = 0]])  ifTrue: [^Color transparent].
				^ (Color r: r g: g b: b range: 255) alpha: (alpha asFloat / 255.0)]
			ifFalse: [^ (Color r: r g: g b: b range: 255)]].

	d = 12 ifTrue: [
		"four bits per component"
		r := (p bitShift: -8) bitAnd: 16rF.
		g := (p bitShift: -4) bitAnd: 16rF.
		b := p bitAnd: 16rF.
		^ Color r: r g: g b: b range: 15].

	d = 9 ifTrue: [
		"three bits per component"
		r := (p bitShift: -6) bitAnd: 16r7.
		g := (p bitShift: -3) bitAnd: 16r7.
		b := p bitAnd: 16r7.
		^ Color r: r g: g b: b range: 7].

	self error: 'unknown pixel depth: ', d printString
! !


More information about the Squeak-dev mailing list