Image.st
changeset 8665 aa7342c1b59f
parent 8664 8cc70d4053f4
child 8691 bfa5c82bf5a1
--- a/Image.st	Sat Mar 23 11:49:50 2019 +0100
+++ b/Image.st	Mon Mar 25 14:51:28 2019 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1991 by Claus Gittinger
               All Rights Reserved
@@ -4928,12 +4926,18 @@
     "/ a hack, for now - alpha is in the low-byte !!!!!!
     (myDepth == 24 and:[otherDepth == 32]) ifTrue:[
         ((samePhotometric and:[photometric == #rgb])
-          or:[ (photometric == #rgb and:[otherPhotometric == #rgba]) ]
+          or:[ (photometric == #rgb and:[otherPhotometric == #argb]) ]
         ) ifTrue:[
             "/ can do the bits by simple stripping off the alpha channel
             self copyPixels32AlphaLowTo24From:anImage.
             ^ self
         ].
+        (photometric == #rgb and:[otherPhotometric == #rgba])
+        ifTrue:[
+            "/ can do the bits by simple stripping off the alpha channel
+            self copyPixels32AlphaHighTo24From:anImage.
+            ^ self
+        ].
     ].
 
     "/ this is a veeery slow fallback
@@ -4980,7 +4984,7 @@
 
     "Modified (format): / 30-01-2017 / 20:46:22 / stefan"
     "Modified: / 24-08-2017 / 17:28:25 / cg"
-    "Modified (comment): / 22-03-2019 / 14:02:03 / Claus Gittinger"
+    "Modified: / 25-03-2019 / 14:43:27 / Claus Gittinger"
 !
 
 fromSubImage:anImage in:aRectangle
@@ -7079,6 +7083,90 @@
     "Created: / 17-07-2012 / 12:13:18 / anwild"
 !
 
+copyPixels32AlphaHighTo24From:anImage
+    "tuned helper to copy pixels from a 32bit rgba (alpha in high byte)
+     to me as a 24bit non-alpha rgb image"
+
+    |imageBits|
+
+    imageBits := anImage bits.
+%{
+    OBJ _myBits = __INST(bytes);
+    OBJ w = __INST(width);
+    OBJ h = __INST(height);
+
+    if (__isByteArrayLike(_myBits)
+     && __isByteArrayLike(imageBits)
+     && __bothSmallInteger(w, h)) {
+        int _idx;
+        int _w = __intVal(w);
+        int _h = __intVal(h);
+        int _mySize = __byteArraySize(_myBits);
+        int _imgSize = __byteArraySize(imageBits);
+        char *_myBitsPtr = __ByteArrayInstPtr(_myBits)->ba_element;
+        char *_imgBitsPtr = __ByteArrayInstPtr(imageBits)->ba_element;
+        char *_myBitsEndPtr = _myBitsPtr + (_w * _h * 3);
+        char *_imgBitsEndPtr = _imgBitsPtr + (_w * _h * 4);
+
+        if ((_w * _h * 3) > _mySize) goto error;
+        if ((_w * _h * 4) > _imgSize) goto error;
+
+#if (__POINTER_SIZE__ == 8) && defined(__LSBFIRST__)
+        // fetch 4 pixels (4*32bit); store in 3 (4*24bit)
+        while (_myBitsPtr < (_myBitsEndPtr-sizeof(int)*3)) {
+            // LSB argbargb; r in LSB
+            // a2 b2 g2 r2 a1 b1 g1 r1 
+            unsigned INT in12 = ((unsigned INT*)_imgBitsPtr)[0];
+            // a4 b4 g4 r4 a3 b3 g3 r3
+            unsigned INT in34 = ((unsigned INT*)_imgBitsPtr)[1];
+
+            // a2 b2 g2 r2 a1 b1 g1 r1 =>    b1 g1 r1
+            // a2 b2 g2 r2 a1 b1 g1 r1 => r2    
+            ((unsigned int*)_myBitsPtr)[0] = (unsigned int)(((in12) & 0x00FFFFFFLL) 
+                                                         | ((in12 >> 8) & 0xFF000000LL));
+            // a2 b2 g2 r2 a1 b1 g1 r1 =>       b2 g2
+            // a4 b4 g4 r4 a3 b3 g3 r3 => g3 r3
+            ((unsigned int*)_myBitsPtr)[1] = (unsigned int)(((in12 >> 40) & 0x0000FFFFLL) 
+                                                         |   ((in34 << 16) & 0xFFFF0000LL));
+            // a4 b4 g4 r4 a3 b3 g3 r3 =>          b3
+            // a4 b4 g4 r4 a3 b3 g3 r3 => b4 g4 r4
+            ((unsigned int*)_myBitsPtr)[2] = (unsigned int)(((in34 >> 16) & 0x000000FFLL) 
+                                                         |  ((in34 >> 24) & 0xFFFFFF00LL));
+            _imgBitsPtr += (2 * sizeof(INT));
+            _myBitsPtr += (3 * sizeof(int));
+        }
+#endif
+        while (_myBitsPtr < _myBitsEndPtr) {
+            // fetch rgba => r..g..b
+#if defined(__LSBFIRST__)
+            unsigned int in = ((unsigned int*)_imgBitsPtr)[0];
+            _myBitsPtr[0] = (in) & 0xFF;
+            _myBitsPtr[1] = (in >> 8) & 0xFF;
+            _myBitsPtr[2] = (in >> 16) & 0xFF;
+#else
+            unsigned char _r = _imgBitsPtr[0];
+            unsigned char _g = _imgBitsPtr[1];
+            unsigned char _b = _imgBitsPtr[2];
+            _myBitsPtr[0] = _r;
+            _myBitsPtr[1] = _g;
+            _myBitsPtr[2] = _b;
+#endif
+            _imgBitsPtr += 4;
+            _myBitsPtr += 3;
+        }
+        RETURN( self );
+    }
+error: ;
+    console_printf("Image: oops - bits-size in copyPixels32\n");
+%}.
+
+    anImage valuesFromX:0 y:0 toX:(self width-1) y:(self height-1) do:[:x :y :pixel |
+        self pixelAtX:x y:y put:(pixel bitAnd:16rFFFFFF)
+    ].
+
+    "Created: / 25-03-2019 / 14:48:52 / Claus Gittinger"
+!
+
 copyPixels32AlphaLowTo24From:anImage
     "tuned helper to copy pixels from a 32bit argb (alpha in low byte)
      to me as a 24bit non-alpha rgb image"
@@ -7157,18 +7245,10 @@
 %}.
 
     anImage valuesFromX:0 y:0 toX:(self width-1) y:(self height-1) do:[:x :y :pixel |
-        |a r g b rgbPixel|
-
-        "/ bgra-pixel
-        "/ a := pixel bitAnd:16rFF.
-        r := (pixel bitShift:-8) bitAnd:16rFF.
-        g := (pixel bitShift:-16) bitAnd:16rFF.
-        b := (pixel bitShift:-24) bitAnd:16rFF.
-        rgbPixel := r + (g bitShift:8) + (b bitShift:16).
-        self pixelAtX:x y:y put:rgbPixel
-    ].
-
-    "Modified: / 22-03-2019 / 15:04:41 / Claus Gittinger"
+        self pixelAtX:x y:y put:((pixel bitShift:-8) bitAnd:16rFFFFFF)
+    ].
+
+    "Modified: / 25-03-2019 / 14:50:50 / Claus Gittinger"
 !
 
 rgbImageAsFormOn:aDevice