Image.st
changeset 8086 c2e7b74ac2d3
parent 8059 1e08cb836ecb
child 8087 24c87d7fdfdf
--- a/Image.st	Tue Aug 22 17:53:06 2017 +0200
+++ b/Image.st	Tue Aug 22 17:53:17 2017 +0200
@@ -13602,19 +13602,29 @@
     |redBits greenBits blueBits alphaBits|
 
     samplesPerPixel >= 4 ifTrue:[
-        redBits := bitsPerSample at:1.
-        greenBits := bitsPerSample at:2.
-        blueBits := bitsPerSample at:3.
-        alphaBits := bitsPerSample at:4.
-
-        ^ (pixel bitShift:(redBits + greenBits + blueBits) negated)
-           bitAnd:(1 bitShift:alphaBits)-1
+        photometric == #rgba ifTrue:[
+            "/ alpha in low bits
+            alphaBits := bitsPerSample at:4.
+
+            ^ pixel bitAnd:(1 bitShift:alphaBits)-1
+        ].
+        photometric == #argb ifTrue:[
+            "/ alpha in high bits
+            redBits := bitsPerSample at:1.
+            greenBits := bitsPerSample at:2.
+            blueBits := bitsPerSample at:3.
+            alphaBits := bitsPerSample at:4.
+
+            ^ (pixel bitShift:(redBits + greenBits + blueBits) negated)
+                bitAnd:(1 bitShift:alphaBits)-1
+        ].
+        ^ 0
     ].
 
     self subclassResponsibility
 
-    "Created: 8.6.1996 / 09:44:51 / cg"
-    "Modified: 10.6.1996 / 14:59:05 / cg"
+    "Created: / 08-06-1996 / 09:44:51 / cg"
+    "Modified: / 22-08-2017 / 17:47:36 / cg"
 !
 
 alphaMaskForPixelValue
@@ -13623,11 +13633,19 @@
     |alphaBits|
 
     samplesPerPixel >= 4 ifTrue:[
-        alphaBits := bitsPerSample at:4.
-        ^ (1 bitShift:alphaBits)-1
+        photometric == #argb ifTrue:[
+            alphaBits := bitsPerSample at:1.
+            ^ (1 bitShift:alphaBits)-1
+        ].
+        photometric == #rgba ifTrue:[
+            alphaBits := bitsPerSample at:4.
+            ^ (1 bitShift:alphaBits)-1
+        ].
     ].
 
     self subclassResponsibility
+
+    "Modified: / 22-08-2017 / 17:29:22 / cg"
 !
 
 alphaShiftForPixelValue
@@ -13637,16 +13655,20 @@
     |redBits greenBits blueBits|
 
     samplesPerPixel >= 3 ifTrue:[
-        redBits := bitsPerSample at:1.
-        greenBits := bitsPerSample at:2.
-        blueBits := bitsPerSample at:3.
-
-        ^ (greenBits + blueBits + redBits)
+        photometric == #argb ifTrue:[
+            redBits := bitsPerSample at:2.
+            greenBits := bitsPerSample at:3.
+            blueBits := bitsPerSample at:4.
+
+            ^ (greenBits + blueBits + redBits)
+        ].
+        "/ rgba or rgb
+        ^ 0
     ].
 
     self subclassResponsibility
 
-    "Modified: / 21-02-2017 / 16:41:42 / cg"
+    "Modified (comment): / 22-08-2017 / 17:26:16 / cg"
 !
 
 ascentOn:aGC
@@ -13746,17 +13768,26 @@
      of blue bits i.e. (1 bitShift:bitsBlue)-1.
      This has to be redefined by subclasses."
 
-    |blueBits|
-
+    |alphaBits blueBits blueMask|
+
+    blueBits := self numBlueBits.
+    blueMask := (1 bitShift:blueBits)-1.
+    
     samplesPerPixel >= 3 ifTrue:[
-        blueBits := bitsPerSample at:3.
-        ^ pixel bitAnd:(1 bitShift:blueBits)-1
+        photometric == #rgba ifTrue:[
+            "/ alpha in low bits
+            alphaBits := self numAlphaBits.
+            ^ (pixel bitShift:alphaBits negated) bitAnd:blueMask
+        ].
+        ((photometric == #rgb) or:[photometric == #argb]) ifTrue:[
+            ^ pixel bitAnd:blueMask
+        ].
     ].
 
     self subclassResponsibility
 
-    "Created: 8.6.1996 / 09:44:21 / cg"
-    "Modified: 10.6.1996 / 14:59:44 / cg"
+    "Created: / 08-06-1996 / 09:44:21 / cg"
+    "Modified: / 22-08-2017 / 17:47:01 / cg"
 !
 
 blueComponentOf:pixel
@@ -13904,7 +13935,7 @@
         ^ Color redPercent:r greenPercent:g bluePercent:b
     ].
 
-    ((p == #rgba) or:[p == #argb]) ifTrue:[
+    (p == #rgba) ifTrue:[
         r := self redBitsOf:pixelValue.
         g := self greenBitsOf:pixelValue.
         b := self blueBitsOf:pixelValue.
@@ -13920,6 +13951,23 @@
         (a == 0) ifFalse:[ a := (100 / ((1 bitShift:numAlphaBits)-1) * a)].
         ^ Color redPercent:r greenPercent:g bluePercent:b alphaPercent:a
     ].
+    (p == #argb) ifTrue:[
+        r := self redBitsOf:pixelValue.
+        g := self greenBitsOf:pixelValue.
+        b := self blueBitsOf:pixelValue.
+        a := self alphaBitsOf:pixelValue.
+        "/ scale...
+        numAlphaBits := bitsPerSample at:1.
+        numRedBits := bitsPerSample at:2.
+        numGreenBits := bitsPerSample at:3.
+        numBlueBits := bitsPerSample at:4.
+        (r == 0) ifFalse:[ r := (100 / ((1 bitShift:numRedBits)-1) * r)].
+        (g == 0) ifFalse:[ g := (100 / ((1 bitShift:numGreenBits)-1) * g)].
+        (b == 0) ifFalse:[ b := (100 / ((1 bitShift:numBlueBits)-1) * b)].
+        (a == 0) ifFalse:[ a := (100 / ((1 bitShift:numAlphaBits)-1) * a)].
+        ^ Color redPercent:r greenPercent:g bluePercent:b alphaPercent:a
+    ].
+
 
     p == #cmyk ifTrue:[
         c := self cyanComponentOfCMYK:pixelValue.
@@ -13939,7 +13987,7 @@
     self error:'invalid (unsupported) photometric'
 
     "Created: / 08-06-1996 / 08:46:18 / cg"
-    "Modified: / 06-06-2007 / 11:21:57 / cg"
+    "Modified: / 22-08-2017 / 16:58:39 / cg"
 !
 
 cyanComponentOfCMY:pixel
@@ -13981,19 +14029,25 @@
      of green bits i.e. (1 bitShift:bitsGreen)-1.
      This has to be redefined by subclasses."
 
-    |blueBits greenBits|
-
+    |blueBits greenBits greenMask alphaBits|
+
+    greenBits := self numBlueBits.
+    greenMask := (1 bitShift:greenBits)-1.
+    
     samplesPerPixel >= 3 ifTrue:[
-        greenBits := bitsPerSample at:2.
-        blueBits := bitsPerSample at:3.
-
-        ^ (pixel bitShift:blueBits negated) bitAnd:(1 bitShift:greenBits)-1
+        photometric == #rgba ifTrue:[
+            alphaBits := self numAlphaBits.
+            (pixel bitShift:(blueBits + alphaBits) negated) bitAnd:greenMask.   
+        ].
+        ((photometric == #rgb) or:[photometric == #argb]) ifTrue:[
+            ^ (pixel bitShift:blueBits negated) bitAnd:greenMask
+        ].
     ].
 
     self subclassResponsibility
 
-    "Created: 8.6.1996 / 09:44:37 / cg"
-    "Modified: 10.6.1996 / 14:59:35 / cg"
+    "Created: / 08-06-1996 / 09:44:37 / cg"
+    "Modified: / 22-08-2017 / 17:46:44 / cg"
 !
 
 greenComponentOf:pixel
@@ -14128,6 +14182,74 @@
     ^ self realUsedValues size
 !
 
+numAlphaBits
+    photometric == #rgba ifTrue:[
+        "/ alpha in low bits
+        ^ bitsPerSample at:4.
+    ].
+    photometric == #argb ifTrue:[
+        "/ alpha in high bits
+        ^ bitsPerSample at:1.
+    ].
+    ^ 0.
+
+    "Created: / 22-08-2017 / 17:34:38 / cg"
+!
+
+numBlueBits
+    photometric == #rgba ifTrue:[
+        "/ alpha in low bits
+        ^ bitsPerSample at:3.
+    ].
+    photometric == #argb ifTrue:[
+        "/ alpha in high bits
+        ^ bitsPerSample at:4.
+    ].
+    photometric == #rgb ifTrue:[
+        "/ no alpha
+        ^ bitsPerSample at:3.
+    ].
+    self subclassResponsibility
+
+    "Created: / 22-08-2017 / 17:35:24 / cg"
+!
+
+numGreenBits
+    photometric == #rgba ifTrue:[
+        "/ alpha in low bits
+        ^ bitsPerSample at:2.
+    ].
+    photometric == #argb ifTrue:[
+        "/ alpha in high bits
+        ^ bitsPerSample at:3.
+    ].
+    photometric == #rgb ifTrue:[
+        "/ no alpha
+        ^ bitsPerSample at:2.
+    ].
+    self subclassResponsibility
+
+    "Created: / 22-08-2017 / 17:35:52 / cg"
+!
+
+numRedBits
+    photometric == #rgba ifTrue:[
+        "/ alpha in low bits
+        ^ bitsPerSample at:1.
+    ].
+    photometric == #argb ifTrue:[
+        "/ alpha in high bits
+        ^ bitsPerSample at:2.
+    ].
+    photometric == #rgb ifTrue:[
+        "/ no alpha
+        ^ bitsPerSample at:1.
+    ].
+    self subclassResponsibility
+
+    "Created: / 22-08-2017 / 17:36:15 / cg"
+!
+
 pixelArraySpecies
     "return the kind of pixel-value container in rowAt:/rowAt:put: methods"
 
@@ -14215,21 +14337,27 @@
      of red bits i.e. (1 bitShift:bitsRed)-1.
      This has to be redefined by subclasses."
 
-    |redBits greenBits blueBits|
-
+    |redBits greenBits blueBits alphaBits redMask|
+
+    redBits := self numRedBits.
+    greenBits := self numGreenBits.
+    blueBits := self numBlueBits.
+    redMask := (1 bitShift:redBits)-1.
+    
     samplesPerPixel >= 3 ifTrue:[
-        redBits := bitsPerSample at:1.
-        greenBits := bitsPerSample at:2.
-        blueBits := bitsPerSample at:3.
-
-        ^ (pixel bitShift:(greenBits + blueBits) negated)
-           bitAnd:(1 bitShift:redBits)-1
+        photometric == #rgba ifTrue:[
+            alphaBits := self numAlphaBits.
+            ^ (pixel bitShift:(greenBits+blueBits+alphaBits) negated) bitAnd:redMask.
+        ].
+        ((photometric == #rgb) or:[photometric == #argb]) ifTrue:[
+            ^ (pixel bitShift:(greenBits+blueBits) negated) bitAnd:redMask.
+        ].
     ].
 
     self subclassResponsibility
 
-    "Created: 8.6.1996 / 09:44:51 / cg"
-    "Modified: 10.6.1996 / 14:59:05 / cg"
+    "Created: / 08-06-1996 / 09:44:51 / cg"
+    "Modified: / 22-08-2017 / 17:52:14 / cg"
 !
 
 redComponentOf:pixel
@@ -14509,7 +14637,7 @@
         pixel := colorMap indexOf:color.
         pixel == 0 ifTrue:[
             "
-             the color is not in the images colormap
+             the color is not in the image's colormap
             "
             ^ nil
         ].
@@ -14519,9 +14647,9 @@
     photometric == #rgb ifTrue:[
         samplesPerPixel isNil ifTrue:[self breakPoint:#cg. samplesPerPixel := 3].
         samplesPerPixel >= 3 ifTrue:[
-            redBits := bitsPerSample at:1.
-            greenBits := bitsPerSample at:2.
-            blueBits := bitsPerSample at:3.
+            redBits := self numRedBits.
+            greenBits := self numGreenBits.
+            blueBits := self numBlueBits.
 
             "/ map r/g/b to 0..255
             r := (color red / 100.0 * ((1 bitShift:redBits)-1)) rounded.
@@ -14545,6 +14673,23 @@
             g := (color green / 100.0 * ((1 bitShift:greenBits)-1)) rounded.
             b := (color blue / 100.0 * ((1 bitShift:blueBits)-1)) rounded.
             a := (color alpha * ((1 bitShift:alphaBits)-1)) rounded.
+            pixel := (((((r bitShift:greenBits) + g) bitShift:blueBits) + b) bitShift:alphaBits) + a.
+            ^ pixel
+        ]
+    ].
+    photometric == #argb ifTrue:[
+        samplesPerPixel isNil ifTrue:[self breakPoint:#cg. samplesPerPixel := 4].
+        samplesPerPixel >= 4 ifTrue:[
+            alphaBits := bitsPerSample at:1.
+            redBits := bitsPerSample at:2.
+            greenBits := bitsPerSample at:3.
+            blueBits := bitsPerSample at:4.
+
+            "/ map r/g/b/a to 0..255
+            r := (color red / 100.0 * ((1 bitShift:redBits)-1)) rounded.
+            g := (color green / 100.0 * ((1 bitShift:greenBits)-1)) rounded.
+            b := (color blue / 100.0 * ((1 bitShift:blueBits)-1)) rounded.
+            a := (color alpha * ((1 bitShift:alphaBits)-1)) rounded.
             pixel := (((((a bitShift:redBits) + r) bitShift:greenBits) + g) bitShift:blueBits) + b.
             ^ pixel
         ]
@@ -14552,14 +14697,14 @@
     ImageErrorSignal raiseErrorString:'format not supported'.
     ^ nil
 
-    "Modified: / 23-02-2017 / 15:55:29 / cg"
+    "Modified (format): / 22-08-2017 / 17:52:39 / cg"
 !
 
 valueFromRGB:rgb
     "given a color, return the corresponding pixel value.
      Non-representable colors return nil."
 
-    |pixel redBits greenBits blueBits r g b a|
+    |pixel redBits greenBits blueBits alphaBits r g b a|
 
     r := rgb bitAnd:16rFF.
     g := (rgb bitShift:-8) bitAnd:16rFF.
@@ -14604,14 +14749,25 @@
         ]
     ].
 
+    photometric == #argb ifTrue:[
+        samplesPerPixel >= 4 ifTrue:[
+            "/ a,r,g,b  b at low end
+            "/ alphaBits := bitsPerSample at:1.
+            redBits := bitsPerSample at:2.
+            greenBits := bitsPerSample at:3.
+            blueBits := bitsPerSample at:4.
+            pixel := (((((a bitShift:redBits) + r) bitShift:greenBits) + g) bitShift:blueBits) + b.
+            ^ pixel
+        ]
+    ].
     photometric == #rgba ifTrue:[
         samplesPerPixel >= 4 ifTrue:[
-            "/ a,r,g,b  b at low end
+            "/ r,g,b,a  a at low end
             redBits := bitsPerSample at:1.
             greenBits := bitsPerSample at:2.
             blueBits := bitsPerSample at:3.
-"/            alphaBits := bitsPerSample at:4.
-            pixel := (((((a bitShift:redBits) + r) bitShift:greenBits) + g) bitShift:blueBits) + b.
+            alphaBits := bitsPerSample at:4.
+            pixel := (((((r bitShift:greenBits) + g) bitShift:blueBits) + b) bitShift:alphaBits) + a.
             ^ pixel
         ]
     ].
@@ -14620,6 +14776,7 @@
 
     "Created: / 15-01-2008 / 15:55:08 / cg"
     "Modified: / 31-01-2017 / 14:45:00 / stefan"
+    "Modified: / 22-08-2017 / 16:56:42 / cg"
 !
 
 valueFromRedBits:redBits greenBits:greenBits blueBits:blueBits