--- a/Depth32Image.st Tue Aug 22 17:41:57 2017 +0200
+++ b/Depth32Image.st Tue Aug 22 17:53:06 2017 +0200
@@ -43,11 +43,12 @@
Only the minimum protocol is implemented here; much more is
needed for higher performance operations on depth32 images.
- (however, 32bit images are currntly relatively seldom used,
- so falling back into the slow general methods from Image does not hurt too much.
- This situation will change, when more support for alpha channels is added and they
- are more heavily used in ST/X...)
-
+ Sometimes, 32bit images with no alpha information (i.e. r,g,b,0) is encountered.
+ In this case, we treat the low byte as red, the next as green, the 2rd as blue byte,
+ and ignore the fourth byte.
+ When reading/writing pixel values, these are treated like argb (i.e. the blue bits are in low bit positions,
+ not shifted).
+
[author:]
Claus Gittinger
@@ -127,25 +128,30 @@
|index "{ Class: SmallInteger }"|
+ index := 1 + (((width * y) + x) * 4).
(photometric == #rgb) ifTrue:[
- index := 1 + (((width * y) + x) * 4).
bytes at:(index) put:(aColor redByte).
bytes at:(index + 1) put:(aColor greenByte).
bytes at:(index + 2) put:(aColor blueByte).
bytes at:(index + 3) put:0.
^ self
].
- (photometric == #rgba) ifTrue:[
- index := 1 + (((width * y) + x) * 4).
+ (photometric == #rgbx) ifTrue:[
bytes at:(index) put:(aColor redByte).
bytes at:(index + 1) put:(aColor greenByte).
bytes at:(index + 2) put:(aColor blueByte).
- bytes at:(index + 3) put:(aColor alphaByte). "alpha channel"
+ bytes at:(index + 3) put:255.
+ ^ self
+ ].
+ (photometric == #rgba) ifTrue:[
+ bytes at:(index) put:(aColor redByte).
+ bytes at:(index + 1) put:(aColor greenByte).
+ bytes at:(index + 2) put:(aColor blueByte).
+ bytes at:(index + 3) put:(aColor alphaByte). "alpha channel in last byte"
^ self
].
(photometric == #argb) ifTrue:[
- index := 1 + (((width * y) + x) * 4).
- bytes at:(index) put:255. "alpha channel"
+ bytes at:(index) put:(aColor alphaByte). "alpha channel in first byte"
bytes at:(index + 1) put:(aColor redByte).
bytes at:(index + 2) put:(aColor greenByte).
bytes at:(index + 3) put:(aColor blueByte).
@@ -154,7 +160,7 @@
super colorAtX:x y:y put:aColor.
- "Modified: / 21-02-2017 / 01:49:58 / cg"
+ "Modified: / 22-08-2017 / 17:12:28 / cg"
!
pixelAtX:x y:y
@@ -812,19 +818,22 @@
r := bytes at:index.
newBytes at:index put:(255-r).
index := index + 1.
+
g := bytes at:index.
newBytes at:index put:(255-g).
index := index + 1.
+
b := bytes at:index.
newBytes at:index put:(255-b).
index := index + 1.
+
a := bytes at:index.
newBytes at:index put:a.
index := index + 1.
].
^ newImage
- "Modified (comment): / 21-02-2017 / 17:09:03 / cg"
+ "Modified (format): / 22-08-2017 / 17:13:38 / cg"
! !
!Depth32Image methodsFor:'initialization'!
@@ -890,20 +899,18 @@
alphaBitsOf:pixel
"given a pixel-value, return the alpha component as byteValue (0..255)"
+ photometric == #argb ifTrue:[
+ "a,r,g,b; MSB"
+ ^ (pixel bitShift:-24) bitAnd:16rFF.
+ ].
photometric == #rgba ifTrue:[
"r,g,b,a; MSB"
^ pixel bitAnd:16rFF.
].
- photometric == #argb ifTrue:[
- "a,r,g,b; MSB"
- ^ (pixel bitShift:-24) bitAnd:16rFF.
- ].
- photometric == #rgb ifTrue:[
- ^ 0
- ].
- self error:'unsupported photometric'
+ "r,g,b,0; MSB"
+ ^ 0
- "Modified (format): / 11-04-2017 / 12:50:20 / cg"
+ "Modified: / 22-08-2017 / 17:18:44 / cg"
!
alphaComponentOf:pixel
@@ -925,24 +932,15 @@
"return the shift amount used with translation from pixelValues to alphaBits.
That is the number of bits to shift the alpha value into the pixel value."
- photometric == #rgba ifTrue:[
- "/ alpha in low byte
- "r,g,b,a"
- ^ 0
- ].
photometric == #argb ifTrue:[
- "/ alpha in high byte
- "a,r,g,b"
+ "/ a,r,g,b - alpha in high byte
^ 24.
].
- photometric == #rgb ifTrue:[
- "r,g,b - no alpha"
- "/ Logger warning:'oops - image has depth 32, but photometric is #rgb'.
- ^ 0.
- ].
- self error:'unsupported photometric: ',(photometric printString)
+ "/ r,g,b,a - alpha in low byte
+ "/ or r,g,b,0 - no alpha
+ ^ 0
- "Modified (format): / 21-02-2017 / 16:42:42 / cg"
+ "Modified: / 22-08-2017 / 17:19:36 / cg"
!
bitsPerPixel
@@ -974,17 +972,14 @@
blueBitsOf:pixel
"given a pixel-value, return the blue component as byteValue (0..255)"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ (pixel bitShift:-8) bitAnd:16rFF.
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ pixel bitAnd:16rFF.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ (pixel bitShift:-8) bitAnd:16rFF.
- "Modified: / 21-02-2017 / 16:45:12 / cg"
+ "Modified: / 22-08-2017 / 17:16:43 / cg"
!
blueComponentOf:pixel
@@ -1002,17 +997,14 @@
blueShiftForPixelValue
"return the shift amount used with translation from pixelValues to blueBits"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ -8
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ 0.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ -8
- "Modified: / 21-02-2017 / 17:03:36 / cg"
+ "Modified: / 22-08-2017 / 17:19:55 / cg"
!
bytesPerRow
@@ -1026,17 +1018,14 @@
greenBitsOf:pixel
"given a pixel-value, return the green component as byteValue (0..255)"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ (pixel bitShift:-16) bitAnd:16rFF.
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ (pixel bitShift:-8) bitAnd:16rFF.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ (pixel bitShift:-16) bitAnd:16rFF.
- "Modified (format): / 21-02-2017 / 16:44:50 / cg"
+ "Modified: / 22-08-2017 / 17:17:12 / cg"
!
greenComponentOf:pixel
@@ -1054,17 +1043,14 @@
greenShiftForPixelValue
"return the shift amount used with translation from pixelValues to greenBits"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ -16
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ -8.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ -16
- "Modified: / 21-02-2017 / 17:03:47 / cg"
+ "Modified: / 22-08-2017 / 17:20:14 / cg"
!
hasAlphaChannel
@@ -1075,20 +1061,47 @@
"Modified: / 21-02-2017 / 15:00:17 / cg"
!
+numAlphaBits
+ photometric == #argb ifTrue:[
+ ^ 8.
+ ].
+ photometric == #rgba ifTrue:[
+ ^ 8.
+ ].
+ ^ 0
+
+ "Created: / 22-08-2017 / 17:38:59 / cg"
+!
+
+numBlueBits
+ ^ 8
+
+ "Created: / 22-08-2017 / 17:38:31 / cg"
+!
+
+numGreenBits
+ ^ 8
+
+ "Created: / 22-08-2017 / 17:38:28 / cg"
+!
+
+numRedBits
+ ^ 8
+
+ "Created: / 22-08-2017 / 17:38:25 / cg"
+!
+
redBitsOf:pixel
"given a pixel-value, return the red component as byteValue (0..255)"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ (pixel bitShift:-24) bitAnd:16rFF.
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ (pixel bitShift:-16) bitAnd:16rFF.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ (pixel bitShift:-24) bitAnd:16rFF.
- "Modified (format): / 21-02-2017 / 16:45:18 / cg"
+ "Modified: / 22-08-2017 / 17:17:34 / cg"
!
redComponentOf:pixel
@@ -1106,17 +1119,14 @@
redShiftForPixelValue
"return the shift amount used with translation from pixelValues to redBits"
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
- "r,g,b,a or r,g,b,0"
- ^ -24
- ].
photometric == #argb ifTrue:[
"a,r,g,b"
^ -16.
].
- self error:'unsupported photometric'
+ "r,g,b,a or r,g,b,0"
+ ^ -24
- "Modified: / 21-02-2017 / 17:04:04 / cg"
+ "Modified: / 22-08-2017 / 17:20:29 / cg"
!
rgbFromValue:pixelValue
@@ -1141,7 +1151,7 @@
!
valueFromRedBits:redBits greenBits:greenBits blueBits:blueBits
- ((photometric == #rgba) or:[photometric == #rgb]) ifTrue:[
+ ((photometric == #rgba) or:[photometric == #rgbX]) ifTrue:[
"/ alpha in low byte
^ (((((redBits bitShift:8) bitOr:greenBits) bitShift:8) bitOr:blueBits) bitShift:8) bitOr:16rFF
].
@@ -1149,9 +1159,13 @@
"/ alpha in high byte
^ (((((redBits bitShift:8) bitOr:greenBits) bitShift:8) bitOr:blueBits)) bitOr:16rFF000000
].
+ (photometric == #rgb) ifTrue:[
+ "/ no alpha in low byte
+ ^ (((((redBits bitShift:8) bitOr:greenBits) bitShift:8) bitOr:blueBits) bitShift:8) bitOr:0
+ ].
self error:'unsupported photometric'
- "Modified: / 21-02-2017 / 17:07:11 / cg"
+ "Modified: / 22-08-2017 / 17:21:19 / cg"
! !
!Depth32Image class methodsFor:'documentation'!