tuned conversion to trueColor
authorClaus Gittinger <cg@exept.de>
Mon, 27 Jul 1998 10:18:11 +0200
changeset 2186 4e4b6f9b0d27
parent 2185 756d58c52113
child 2187 995bb5c1f6d2
tuned conversion to trueColor
Depth4Image.st
--- a/Depth4Image.st	Mon Jul 27 10:13:45 1998 +0200
+++ b/Depth4Image.st	Mon Jul 27 10:18:11 1998 +0200
@@ -167,6 +167,347 @@
     "Modified: 21.7.1997 / 18:05:47 / cg"
 ! !
 
+!Depth4Image methodsFor:'converting images'!
+
+anyImageAsTrueColorFormOn:aDevice
+    "return a true-color device-form for the palette-image receiver.
+     Supports true color devices with depths: 8, 16, 24 and 32"
+
+    |depth 
+     nColors "{ Class: SmallInteger }"
+     colorValues 
+     scaleRed scaleGreen scaleBlue redShift greenShift blueShift
+     form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel 
+     usedDevicePadding usedDeviceBytesPerRow padd n|
+
+    depth := aDevice depth.
+
+    "/ gather r/g/b values for all colors in the map ...
+
+    nColors := 1 bitShift:(self depth).
+
+    "/ precompute scales to map from 0..100 into devices range
+    "/ (this may be different for the individual components)
+
+    scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 100.
+    scaleGreen := ((1 bitShift:aDevice bitsGreen) - 1) / 100.
+    scaleBlue := ((1 bitShift:aDevice bitsBlue) - 1) / 100.
+    redShift := aDevice shiftRed.
+    greenShift := aDevice shiftGreen.
+    blueShift := aDevice shiftBlue.
+
+    colorValues := Array uninitializedNew:nColors.
+
+    0 to:nColors-1 do:[:pixel |
+        |clr rv gv bv v "{ Class: SmallInteger }" |
+
+        clr := self colorFromValue:pixel.
+
+        rv := (clr red * scaleRed) rounded.
+        gv := (clr green * scaleGreen) rounded.
+        bv := (clr blue * scaleBlue) rounded.
+
+        v := rv bitShift:redShift.
+        v := v bitOr:(gv bitShift:greenShift).
+        v := v bitOr:(bv bitShift:blueShift).
+
+        colorValues at:(pixel+1) put:v.
+"/ clr print. ' ' print.
+"/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print.
+"/ ' -> ' print. v printNL.
+    ].
+
+    bestFormat := self bestSupportedImageFormatFor:aDevice.
+    usedDeviceDepth := bestFormat at:#depth.
+    usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel.
+    usedDevicePadding := bestFormat at:#padding.
+
+    usedDeviceBytesPerRow := self class bytesPerRowForWidth:width depth:usedDeviceBitsPerPixel padding:usedDevicePadding.
+    padd := usedDeviceBytesPerRow -( self class bytesPerRowForWidth:width depth:usedDeviceBitsPerPixel padding:8).
+    imageBits := ByteArray uninitializedNew:(usedDeviceBytesPerRow * height).
+
+    "/ for now, only support some depths
+
+    usedDeviceBitsPerPixel == 16 ifTrue:[
+        "/ 16 bits/pixel
+
+        "/ now, walk over the image and replace
+        "/ colorMap indices by color values in the bits array
+
+%{  
+        if (__bothSmallInteger(_INST(height), _INST(width))
+         && __isArray(colorValues)
+         && __isByteArray(_INST(bytes))
+         && __isByteArray(imageBits)) {
+            int r,p;
+            int x, y, w, h, nPix;
+            int byte;
+
+            unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element;
+            unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element;
+            OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
+
+            w = __intVal(_INST(width));
+            h = __intVal(_INST(height));
+            r = 0;
+            p = __intVal(padd);
+            nPix = w * h;
+            while (nPix-- > 0) {
+                unsigned idx, v;
+                OBJ clr;
+
+                if (r & 1) {
+                    idx = byte & 0xF;
+                } else {
+                    byte = *srcPtr++;
+                    idx = (byte>>4) & 0xF;
+                }
+                clr = ap[idx];
+                v = __intVal(clr);
+#ifdef MSBFIRST
+                ((short *)dstPtr)[0] = v;
+#else
+                dstPtr[0] = (v>>8) & 0xFF;
+                dstPtr[1] = (v) & 0xFF;
+#endif
+                dstPtr += 2;
+
+                if (++r == w) {
+                    dstPtr += p;
+                    r = 0;
+                }
+            }
+        }
+%}.
+    ] ifFalse:[
+        usedDeviceBitsPerPixel == 32 ifTrue:[
+            "/ 32 bits/pixel
+
+            "/ now, walk over the image and replace
+            "/ colorMap indices by color values in the bits array
+
+%{       
+            if (__bothSmallInteger(_INST(height), _INST(width))
+             && __isArray(colorValues)
+             && __isByteArray(_INST(bytes))
+             && __isByteArray(imageBits)) {
+                int x, y, w, h, nPix;
+                int r,p;
+                int byte;
+
+                unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element;
+                unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element;
+                OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
+
+                w = __intVal(_INST(width));
+                h = __intVal(_INST(height));
+                r = 0;
+                p = __intVal(padd);
+                nPix = w * h;
+                while (nPix > 0) {
+                    unsigned idx, v;
+                    OBJ clr;
+
+                    if (r & 1) {
+                        byte = *srcPtr++;
+                        idx = (byte>>4) & 0xF;
+                    } else {
+                        idx = byte & 0xF;
+                    }
+                    clr = ap[idx];
+                    v = __intVal(clr);
+#ifdef MSBFIRST
+                    ((long *)dstPtr)[0] = v;
+#else
+                    dstPtr[0] = (v>>24) & 0xFF;
+                    dstPtr[1] = (v>>16) & 0xFF;
+                    dstPtr[2] = (v>>8) & 0xFF;
+                    dstPtr[3] = (v) & 0xFF;
+#endif
+                    dstPtr += 4;
+                    nPix--;
+
+                    if (++r == w) {
+                        dstPtr += p;
+                        r = 0;
+                    }
+                }
+            }
+%}.
+        ] ifFalse:[
+            usedDeviceBitsPerPixel == 8 ifTrue:[
+                "/ 8 bits/pixel
+
+                "/ now, walk over the image and replace
+                "/ colorMap indices by color values in the bits array
+
+%{       
+                if (__bothSmallInteger(_INST(height), _INST(width))
+                 && __isArray(colorValues)
+                 && __isByteArray(_INST(bytes))
+                 && __isByteArray(imageBits)) {
+                    int x, y, w, h, nPix;
+                    int r,p, byte;
+
+                    unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element;
+                    unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element;
+                    OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
+
+                    w = __intVal(_INST(width));
+                    h = __intVal(_INST(height));
+                    r = 0;
+                    p = __intVal(padd);
+
+                    nPix = w * h;
+                    while (nPix > 0) {
+                        unsigned idx, v;
+                        OBJ clr;
+
+                        if (r & 1) {
+                            byte = *srcPtr++;
+                            idx = (byte>>4) & 0xF;
+                        } else {
+                            idx = byte & 0xF;
+                        }
+                        clr = ap[idx];
+                        v = __intVal(clr);
+
+                        dstPtr[0] = v;
+
+                        dstPtr += 1;
+                        nPix--;
+
+                        if (++r == w) {
+                            dstPtr += p;
+                            r = 0;
+                        }
+                    }
+                }
+%}.
+            ] ifFalse:[
+                usedDeviceBitsPerPixel == 24 ifTrue:[
+                    "/ 24 bits/pixel
+
+                    "/ now, walk over the image and replace
+                    "/ colorMap indices by color values in the bits array
+
+%{       
+                    if (__bothSmallInteger(_INST(height), _INST(width))
+                     && __isArray(colorValues)
+                     && __isByteArray(_INST(bytes))
+                     && __isByteArray(imageBits)) {
+                        int x, y, w, h, nPix;
+                        int r, p, byte;
+
+                        unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element;
+                        unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element;
+                        OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
+
+                        w = __intVal(_INST(width));
+                        h = __intVal(_INST(height));
+                        r = 0;
+                        p = __intVal(padd);
+
+                        nPix = w * h;
+                        while (nPix > 0) {
+                            unsigned idx, v;
+                            OBJ clr;
+
+                            if (r & 1) {
+                                byte = *srcPtr++;
+                                idx = (byte>>4) & 0xF;
+                            } else {
+                                idx = byte & 0xF;
+                            }
+                            clr = ap[idx];
+                            v = __intVal(clr);
+
+                            dstPtr[0] = (v>>16) & 0xFF;
+                            dstPtr[1] = (v>>8) & 0xFF;
+                            dstPtr[2] = (v) & 0xFF;
+
+                            dstPtr += 3;
+                            nPix--;
+
+                            if (++r == w) {
+                                dstPtr += p;
+                                r = 0;
+                            }
+                        }
+                    }
+%}.
+                ] ifFalse:[
+                    'Image [warning]: unimplemented trueColor depth in anyImageAsTrueColorFormOn: ' errorPrint. usedDeviceBitsPerPixel errorPrintCR.
+                    ^ nil
+                ]
+            ]
+        ]
+    ].
+
+    imageBits isNil ifTrue:[            
+        ^ nil
+    ].
+
+    form := Form width:width height:height depth:usedDeviceDepth on:aDevice.
+    form isNil ifTrue:[^ nil].
+    form initGC.
+
+    form
+        copyBitsFrom:imageBits
+        bitsPerPixel:usedDeviceBitsPerPixel
+        depth:usedDeviceDepth
+        padding:usedDevicePadding
+        width:width height:height 
+        x:0 y:0
+        toX:0 y:0. 
+
+    ^ form
+
+    "Created: 20.10.1995 / 22:05:10 / cg"
+    "Modified: 21.10.1995 / 19:30:26 / cg"
+
+
+!
+
+greyImageAsTrueColorFormOn:aDevice
+    "return a true-color device-form for the grey-image receiver.
+     Supports true color devices with depths: 8, 16, 24 and 32"
+
+    |f|
+
+    f := self anyImageAsTrueColorFormOn:aDevice.
+    f notNil ifTrue:[^ f].
+    ^ super greyImageAsTrueColorFormOn:aDevice
+
+    "Created: / 24.7.1998 / 01:21:28 / cg"
+!
+
+paletteImageAsTrueColorFormOn:aDevice
+    "return a true-color device-form for the palette-image receiver.
+     Supports true color devices with depths: 8, 16, 24 and 32"
+
+    |f|
+
+    f := self anyImageAsTrueColorFormOn:aDevice.
+    f notNil ifTrue:[^ f].
+    ^ super paletteImageAsTrueColorFormOn:aDevice
+
+    "Created: / 24.7.1998 / 01:20:46 / cg"
+!
+
+rgbImageAsTrueColorFormOn:aDevice
+    "return a true-color device-form for the rgb-image receiver.
+     Supports true color devices with depths: 8, 16, 24 and 32"
+
+    |f|
+
+    f := self anyImageAsTrueColorFormOn:aDevice.
+    f notNil ifTrue:[^ f].
+    ^ super rgbImageAsTrueColorFormOn:aDevice
+
+    "Created: / 24.7.1998 / 01:21:57 / cg"
+! !
+
 !Depth4Image methodsFor:'dither helpers'!
 
 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth
@@ -668,5 +1009,5 @@
 !Depth4Image class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Depth4Image.st,v 1.29 1998-07-23 14:31:33 tz Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Depth4Image.st,v 1.30 1998-07-27 08:18:11 cg Exp $'
 ! !