skip leading empty space in hardRotated (10-20% speedup);
authorClaus Gittinger <cg@exept.de>
Thu, 24 Apr 1997 12:03:04 +0200
changeset 1650 eb56b36925fc
parent 1649 fa5238a71c2e
child 1651 85f2b72134f1
skip leading empty space in hardRotated (10-20% speedup); added #close.
Image.st
--- a/Image.st	Thu Apr 24 12:00:37 1997 +0200
+++ b/Image.st	Thu Apr 24 12:03:04 1997 +0200
@@ -7655,36 +7655,36 @@
 
     maxX := minX := p1 x.
     (t := p2 x) > maxX ifTrue:[
-	maxX := t
+        maxX := t
     ] ifFalse:[
-	t < minX ifTrue:[minX := t].
+        t < minX ifTrue:[minX := t].
     ].
     (t := p3 x) > maxX ifTrue:[
-	maxX := t
+        maxX := t
     ] ifFalse:[
-	t < minX ifTrue:[minX := t].
+        t < minX ifTrue:[minX := t].
     ].
     (t := p4 x) > maxX ifTrue:[
-	maxX := t
+        maxX := t
     ] ifFalse:[
-	t < minX ifTrue:[minX := t].
+        t < minX ifTrue:[minX := t].
     ].
 
     maxY := minY := p1 y.
     (t := p2 y) > maxY ifTrue:[
-	maxY := t
+        maxY := t
     ] ifFalse:[
-	t < minY ifTrue:[minY := t].
+        t < minY ifTrue:[minY := t].
     ].
     (t := p3 y) > maxY ifTrue:[
-	maxY := t
+        maxY := t
     ] ifFalse:[
-	t < minY ifTrue:[minY := t].
+        t < minY ifTrue:[minY := t].
     ].
     (t := p4 y) > maxY ifTrue:[
-	maxY := t
+        maxY := t
     ] ifFalse:[
-	t < minY ifTrue:[minY := t].
+        t < minY ifTrue:[minY := t].
     ].
 
 
@@ -7703,36 +7703,38 @@
     newImage colorMap:colorMap copy.
     newImage maskedPixelsAre0:maskedPixelsAre0.
     mask notNil ifTrue:[
-	newImage mask:(mask rotated:degrees)
+        newImage mask:(mask rotated:degrees)
     ] ifFalse:[
-	self isMask ifFalse:[
-	    m := ImageMask width:width height:height.
-	    m bits:(maskBits := ByteArray new:(m bytesPerRow * height)).
-	    maskBits atAllPut:16rFF.
-	    newImage mask:(m rotated:degrees)
-	]
+        self isMask ifFalse:[
+            m := ImageMask width:width height:height.
+            m bits:(maskBits := ByteArray new:(m bytesPerRow * height)).
+            maskBits atAllPut:16rFF.
+            newImage mask:(m rotated:degrees)
+        ]
     ].
 
     maskedPixelsAre0 ifTrue:[
-	blackPixel := 0.
+        blackPixel := 0.
     ] ifFalse:[
-	blackPixel := self valueFromColor:Color black.
-	blackPixel isNil ifTrue:[
-	    blackPixel := self valueFromColor:Color white.
-	    blackPixel isNil ifTrue:[
-		blackPixel := 0.
-	    ]
-	]
+        blackPixel := self valueFromColor:Color black.
+        blackPixel isNil ifTrue:[
+            blackPixel := self valueFromColor:Color white.
+            blackPixel isNil ifTrue:[
+                blackPixel := 0.
+            ]
+        ]
     ].
     self isMask ifTrue:[
-	blackPixel := 0.
+        blackPixel := 0.
     ].
 
     myDepth := self depth.
     newBits atAllPut:0.
 
     "/ now, walk over destination pixels,
-    "/ fetching from source.
+    "/ fetching from source. 
+    "/ (if we walked over the source, we could get holes
+    "/  in the destination image ...)
 
     halfW := (width - 1) / 2.0.
     halfH := (height - 1) / 2.0.
@@ -7762,7 +7764,7 @@
 #   define Float_PI 3.14159
 
     if (__isSmallInteger(degrees) && (__intVal(degrees)<90)) {
-	__rot1 = 1;
+        __rot1 = 1;
     }
 
     bad = true;
@@ -7774,493 +7776,560 @@
      && __isFloat(halfH)
      && __isByteArray(newBits)
      && __isByteArray(__INST(bytes))) {
-	__srcBytes = __ByteArrayInstPtr(__INST(bytes))->ba_element;
-	__dstBytes = __ByteArrayInstPtr(newBits)->ba_element;
-	__nSrcBytes = __byteArraySize(__INST(bytes));
-	__nDstBytes = __byteArraySize(newBits);
-	__blackPixel = __intVal(blackPixel);
-
-	__radians = __floatVal(radians);
-	__radians = -__radians; /* sigh: clock-wise */
-	__sin = sin(__radians);
-	__cos = cos(__radians);
-	__minX = __floatVal(minX);
-	__minY = __floatVal(minY);
-	__halfW = __floatVal(halfW);
-	__halfH = __floatVal(halfH);
-
-	__dstRowPtr = __dstBytes;
-	__dstEndPtr = __dstBytes + __nDstBytes;
+        __srcBytes = __ByteArrayInstPtr(__INST(bytes))->ba_element;
+        __dstBytes = __ByteArrayInstPtr(newBits)->ba_element;
+        __nSrcBytes = __byteArraySize(__INST(bytes));
+        __nDstBytes = __byteArraySize(newBits);
+        __blackPixel = __intVal(blackPixel);
+
+        __radians = __floatVal(radians);
+        __radians = -__radians; /* sigh: clock-wise */
+        __sin = sin(__radians);
+        __cos = cos(__radians);
+        __minX = __floatVal(minX);
+        __minY = __floatVal(minY);
+        __halfW = __floatVal(halfW);
+        __halfH = __floatVal(halfH);
+
+        __dstRowPtr = __dstBytes;
+        __dstEndPtr = __dstBytes + __nDstBytes;
 
 #       define EARLY_OUT
-
-	switch (__depth) {
-	    case 8:
-		for (__dstY = 0; __dstY < __newHeight; __dstY++) {
-		    double __pY, __sinPY, __cosPY;
+#       define FAST_ADVANCE 5
+#       define FAST_ADVANCE2
+
+        switch (__depth) {
+            case 8:
+                for (__dstY = 0; __dstY < __newHeight; __dstY++) {
+                    double __pY, __sinPY, __cosPY;
 #ifdef EARLY_OUT
-		    int didFetchInRow = 0;
+                    int didFetchInRow = 0;
 #endif
-		    __pY = (double)__dstY + __minY;
-
-		    __sinPY = __sin * __pY;
-		    __cosPY = __cos * __pY;
-
-		    __dstPtr = __dstRowPtr;
-		    __dstRowPtr += __dstBytesPerRow;
-
-		    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
-			double __pX, __nX;
-			unsigned __pix;
-
-			/* translate X in destination (center to 0/0) */
-			__pX = (double)__dstX + __minX;
-			/* rotate X */
-			__nX = (__cos * __pX) - __sinPY;
-
-			/* translate X in source (origin to 0/0) */
-			__nX = __nX + __halfW + 0.5;
-
-			/* inside ? */
-			if (__nX < 0) {
+                    __pY = (double)(__dstY + __minY);
+
+                    __sinPY = __sin * __pY;
+                    __cosPY = __cos * __pY;
+
+                    __dstPtr = __dstRowPtr;
+                    __dstRowPtr += __dstBytesPerRow;
+
+                    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
+                        double __pX, __nX;
+                        unsigned __pix;
+
+                        /* translate X in destination (center to 0/0) */
+                        __pX = (double)(__dstX + __minX);
+                        /* rotate X */
+                        __nX = (__cos * __pX) - __sinPY;
+
+                        /* translate X in source (origin to 0/0) */
+                        __nX = __nX + __halfW + 0.5;
+
+                        /* inside ? */
+                        if (__nX < 0) {
 #ifdef EARLY_OUT
-			    if (didFetchInRow) {
-				if (__rot1) break;
-			    }
-#endif
-			    __pix = __blackPixel;
-			} else {
-			    int __srcX;
-
-			    __srcX = (int)__nX;
-			    /* inside ? */
-			    if (__srcX >= __width) {
-#ifdef EARLY_OUT
-				if (didFetchInRow) {
-				    if (__rot1) break;
-				}
+                            if (didFetchInRow) {
+                                if (__rot1) break;
+                            }
 #endif
-				__pix = __blackPixel;
-			    } else {
-				double __nY;
-
-				/* rotate Y */
-				__nY = (__sin * __pX) + __cosPY;
-				/* translate Y in source (origin to 0/0) */
-				__nY = __nY + __halfH + 0.5;
-
-				/* inside ? */
-				if (__nY < 0) {
+#ifdef FAST_ADVANCE
+                            if (__blackPixel == 0) {
+                                do {
+                                    /* try advance by FAST_ADVANCE pixels ... */
+                                    __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE;
+                                    if (__dstX >= __newWidth) {
+                                        break;
+                                    }
+                                    __pX = (double)(__dstX + __minX);
+                                    __nX = (__cos * __pX) - __sinPY;
+                                    __nX = __nX + __halfW + 0.5;
+                                } while (__nX < 0);
+                                __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE;
+                            }
+#endif
+                            __pix = __blackPixel;
+                        } else {
+                            int __srcX;
+
+                            __srcX = (int)__nX;
+                            /* inside ? */
+                            if (__srcX >= __width) {
 #ifdef EARLY_OUT
-				    if (didFetchInRow) {
-					if (__rot1) break;
-				    }
-#endif
-				    __pix = __blackPixel;
-				} else {
-				    int __srcY;
-
-				    __srcY = (int)__nY;
-				    /* inside ? */
-				    if (__srcY >= __height) {
-#ifdef EARLY_OUT
-					if (didFetchInRow) {
-					    if (__rot1) break;
-					}
+                                if (didFetchInRow) {
+                                    if (__rot1) break;
+                                }
 #endif
-					__pix = __blackPixel;
-				    } else {
-					/* fetch source pixel */
-
-					int idx;
-#ifdef EARLY_OUT
-					didFetchInRow = 1;
+#ifdef FAST_ADVANCE2
+                                if (__blackPixel == 0) {
+                                    do {
+                                        /* try advance by FAST_ADVANCE pixels ... */
+                                        __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE;
+                                        if (__dstX >= __newWidth) {
+                                            break;
+                                        }
+                                        __pX = (double)(__dstX + __minX);
+                                        __nX = (__cos * __pX) - __sinPY;
+                                        __nX = __nX + __halfW + 0.5;
+                                        __srcX = (int)__nX;
+                                    } while (__srcX >= __width);
+                                    __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE;
+                                }
 #endif
-					idx = __srcY * __srcBytesPerRow + __srcX;
-					if ((unsigned)idx < __nSrcBytes) {
-					    __pix = __srcBytes[idx];
-					} else {
-					    __pix = __blackPixel;
-					}
-				    }
-				}
-			    }
-			}
-
-			if (__pix != 0) {
-			    *__dstPtr = __pix;
-			}
-			__dstPtr++;
-		    }
-		}
-		break;
-
-	    case 1:
-		for (__dstY = 0; __dstY < __newHeight; __dstY++) {
-		    double __pY, __sinPY, __cosPY;
+                                __pix = __blackPixel;
+                            } else {
+                                double __nY;
+
+                                /* rotate Y */
+                                __nY = (__sin * __pX) + __cosPY;
+                                /* translate Y in source (origin to 0/0) */
+                                __nY = __nY + __halfH + 0.5;
+
+                                /* inside ? */
+                                if (__nY < 0) {
 #ifdef EARLY_OUT
-		    int didFetchInRow = 0;
+                                    if (didFetchInRow) {
+                                        if (__rot1) break;
+                                    }
+#endif
+#ifdef FAST_ADVANCE2
+                                    if (__blackPixel == 0) {
+                                        do {
+                                            /* try advance by FAST_ADVANCE pixels ... */
+                                            __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE;
+                                            if (__dstX >= __newWidth) {
+                                                break;
+                                            }
+                                            __pX = (double)(__dstX + __minX);
+                                            __nY = (__sin * __pX) + __cosPY;
+                                            __nY = __nY + __halfH + 0.5;
+                                        } while (__nY < 0);
+                                        __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE;
+                                    }
 #endif
-		    __pY = (double)__dstY + __minY;
-
-		    __sinPY = __sin * __pY;
-		    __cosPY = __cos * __pY;
-
-		    __dstPtr = __dstRowPtr;
-		    __dstMask = 0x80;
-		    __dstRowPtr += __dstBytesPerRow;
-
-		    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
-			double __pX, __nX;
-			int __pix;
-
-			/* translate X in destination (center to 0/0) */
-			__pX = (double)__dstX + __minX;
-			/* rotate X */
-			__nX = (__cos * __pX) - __sinPY;
-
-			/* translate X in source (origin to 0/0) */
-			__nX = __nX + __halfW + 0.5;
-
-			/* inside ? */
-			if (__nX < 0) {
+                                    __pix = __blackPixel;
+                                } else {
+                                    int __srcY;
+
+                                    __srcY = (int)__nY;
+                                    /* inside ? */
+                                    if (__srcY >= __height) {
 #ifdef EARLY_OUT
-			    if (didFetchInRow) {
-				if (__rot1) break;
-			    }
+                                        if (didFetchInRow) {
+                                            if (__rot1) break;
+                                        }
 #endif
-			    __pix = __blackPixel;
-			} else {
-			    int __srcX;
-
-			    __srcX = (int)__nX;
-			    /* inside ? */
-			    if (__srcX >= __width) {
+#ifdef FAST_ADVANCE
+                                        if (__blackPixel == 0) {
+                                            do {
+                                                /* try advance by FAST_ADVANCE pixels ... */
+                                                __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE;
+                                                if (__dstX >= __newWidth) {
+                                                    break;
+                                                }
+                                                __pX = (double)(__dstX + __minX);
+                                                __nY = (__sin * __pX) + __cosPY;
+                                                __nY = __nY + __halfH + 0.5;
+                                                __srcY = (int)__nY;
+                                            } while (__srcY >= __height);
+                                            __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE;
+                                        }
+#endif
+                                        __pix = __blackPixel;
+                                    } else {
+                                        /* fetch source pixel */
+
+                                        int idx;
 #ifdef EARLY_OUT
-				if (didFetchInRow) {
-				    if (__rot1) break;
-				}
+                                        didFetchInRow = 1;
 #endif
-				__pix = __blackPixel;
-			    } else {
-				double __nY;
-
-				/* rotate Y */
-				__nY = (__sin * __pX) + __cosPY;
-				/* translate Y in source (origin to 0/0) */
-				__nY = __nY + __halfH + 0.5;
-
-				/* inside ? */
-				if (__nY < 0) {
+                                        idx = __srcY * __srcBytesPerRow + __srcX;
+                                        if ((unsigned)idx < __nSrcBytes) {
+                                            __pix = __srcBytes[idx];
+                                        } else {
+                                            __pix = __blackPixel;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        if (__pix != 0) {
+                            *__dstPtr = __pix;
+                        }
+                        __dstPtr++;
+                    }
+                }
+                break;
+
+            case 1:
+                for (__dstY = 0; __dstY < __newHeight; __dstY++) {
+                    double __pY, __sinPY, __cosPY;
 #ifdef EARLY_OUT
-				    if (didFetchInRow) {
-					if (__rot1) break;
-				    }
-#endif
-				    __pix = __blackPixel;
-				} else {
-				    int __srcY;
-
-				    __srcY = (int)__nY;
-				    /* inside ? */
-				    if (__srcY >= __height) {
-#ifdef EARLY_OUT
-					if (didFetchInRow) {
-					    if (__rot1) break;
-					}
+                    int didFetchInRow = 0;
 #endif
-					__pix = __blackPixel;
-				    } else {
-					/* fetch source pixel */
-
-					int idx, pV;
+                    __pY = (double)(__dstY + __minY);
+
+                    __sinPY = __sin * __pY;
+                    __cosPY = __cos * __pY;
+
+                    __dstPtr = __dstRowPtr;
+                    __dstMask = 0x80;
+                    __dstRowPtr += __dstBytesPerRow;
+
+                    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
+                        double __pX, __nX;
+                        int __pix;
+
+                        /* translate X in destination (center to 0/0) */
+                        __pX = (double)(__dstX + __minX);
+                        /* rotate X */
+                        __nX = (__cos * __pX) - __sinPY;
+
+                        /* translate X in source (origin to 0/0) */
+                        __nX = __nX + __halfW + 0.5;
+
+                        /* inside ? */
+                        if (__nX < 0) {
 #ifdef EARLY_OUT
-					didFetchInRow = 1;
+                            if (didFetchInRow) {
+                                if (__rot1) break;
+                            }
 #endif
-					idx = __srcY * __srcBytesPerRow + (__srcX >> 3);
-					if ((unsigned)idx < __nSrcBytes) {
-					    pV = __srcBytes[idx];
-					    __pix = (pV & (0x80 >> (__srcX & 7))) ? 1 : 0;
-					} else {
-					    __pix = __blackPixel;
-					}
-				    }
-				}
-			    }
-			}
-
-			/* store pixel */
-			if (__pix != 0) {
-			    *__dstPtr |= __dstMask;
-			}
-			__dstMask >>= 1;
-			if (__dstMask == 0) {
-			    __dstMask = 0x80;
-			    __dstPtr++;
-			}
-		    }
-		}
-		break;
-
-	    case 24:
-		for (__dstY = 0; __dstY < __newHeight; __dstY++) {
-		    double __pY, __sinPY, __cosPY;
+                            __pix = __blackPixel;
+                        } else {
+                            int __srcX;
+
+                            __srcX = (int)__nX;
+                            /* inside ? */
+                            if (__srcX >= __width) {
+#ifdef EARLY_OUT
+                                if (didFetchInRow) {
+                                    if (__rot1) break;
+                                }
+#endif
+                                __pix = __blackPixel;
+                            } else {
+                                double __nY;
+
+                                /* rotate Y */
+                                __nY = (__sin * __pX) + __cosPY;
+                                /* translate Y in source (origin to 0/0) */
+                                __nY = __nY + __halfH + 0.5;
+
+                                /* inside ? */
+                                if (__nY < 0) {
+#ifdef EARLY_OUT
+                                    if (didFetchInRow) {
+                                        if (__rot1) break;
+                                    }
+#endif
+                                    __pix = __blackPixel;
+                                } else {
+                                    int __srcY;
+
+                                    __srcY = (int)__nY;
+                                    /* inside ? */
+                                    if (__srcY >= __height) {
 #ifdef EARLY_OUT
-		    int didFetchInRow = 0;
+                                        if (didFetchInRow) {
+                                            if (__rot1) break;
+                                        }
 #endif
-		    __pY = (double)__dstY + __minY;
-
-		    __sinPY = __sin * __pY;
-		    __cosPY = __cos * __pY;
-
-		    __dstPtr = __dstRowPtr;
-		    __dstRowPtr += __dstBytesPerRow;
-
-		    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
-			double __pX, __nX;
-			unsigned __pix;
-
-			/* translate X in destination (center to 0/0) */
-			__pX = (double)__dstX + __minX;
-			/* rotate X */
-			__nX = (__cos * __pX) - __sinPY;
-
-			/* translate X in source (origin to 0/0) */
-			__nX = __nX + __halfW + 0.5;
-
-			/* inside ? */
-			if (__nX < 0) {
+                                        __pix = __blackPixel;
+                                    } else {
+                                        /* fetch source pixel */
+
+                                        int idx, pV;
 #ifdef EARLY_OUT
-			    if (didFetchInRow) {
-				if (__rot1) break;
-			    }
+                                        didFetchInRow = 1;
 #endif
-			    __pix = __blackPixel;
-			} else {
-			    int __srcX;
-
-			    __srcX = (int)__nX;
-			    /* inside ? */
-			    if (__srcX >= __width) {
-#ifdef EARLY_OUT
-				if (didFetchInRow) {
-				    if (__rot1) break;
-				}
-#endif
-				__pix = __blackPixel;
-			    } else {
-				double __nY;
-
-				/* rotate Y */
-				__nY = (__sin * __pX) + __cosPY;
-				/* translate Y in source (origin to 0/0) */
-				__nY = __nY + __halfH + 0.5;
-
-				/* inside ? */
-				if (__nY < 0) {
+                                        idx = __srcY * __srcBytesPerRow + (__srcX >> 3);
+                                        if ((unsigned)idx < __nSrcBytes) {
+                                            pV = __srcBytes[idx];
+                                            __pix = (pV & (0x80 >> (__srcX & 7))) ? 1 : 0;
+                                        } else {
+                                            __pix = __blackPixel;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        /* store pixel */
+                        if (__pix != 0) {
+                            *__dstPtr |= __dstMask;
+                        }
+                        __dstMask >>= 1;
+                        if (__dstMask == 0) {
+                            __dstMask = 0x80;
+                            __dstPtr++;
+                        }
+                    }
+                }
+                break;
+
+            case 24:
+                for (__dstY = 0; __dstY < __newHeight; __dstY++) {
+                    double __pY, __sinPY, __cosPY;
 #ifdef EARLY_OUT
-				    if (didFetchInRow) {
-					if (__rot1) break;
-				    }
+                    int didFetchInRow = 0;
 #endif
-				    __pix = __blackPixel;
-				} else {
-				    int __srcY;
-
-				    __srcY = (int)__nY;
-				    /* inside ? */
-				    if (__srcY >= __height) {
+                    __pY = (double)(__dstY + __minY);
+
+                    __sinPY = __sin * __pY;
+                    __cosPY = __cos * __pY;
+
+                    __dstPtr = __dstRowPtr;
+                    __dstRowPtr += __dstBytesPerRow;
+
+                    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
+                        double __pX, __nX;
+                        unsigned __pix;
+
+                        /* translate X in destination (center to 0/0) */
+                        __pX = (double)(__dstX + __minX);
+                        /* rotate X */
+                        __nX = (__cos * __pX) - __sinPY;
+
+                        /* translate X in source (origin to 0/0) */
+                        __nX = __nX + __halfW + 0.5;
+
+                        /* inside ? */
+                        if (__nX < 0) {
 #ifdef EARLY_OUT
-					if (didFetchInRow) {
-					    if (__rot1) break;
-					}
-#endif
-					__pix = __blackPixel;
-				    } else {
-					/* fetch source pixel */
-
-					int idx;
-#ifdef EARLY_OUT
-					didFetchInRow = 1;
+                            if (didFetchInRow) {
+                                if (__rot1) break;
+                            }
 #endif
-					idx = __srcY * __srcBytesPerRow + __srcX + __srcX + __srcX;
-					if ((unsigned)idx < __nSrcBytes) {
-					    __pix = __srcBytes[idx];
-					    __pix = (__pix<<8) | __srcBytes[idx+1];
-					    __pix = (__pix<<8) | __srcBytes[idx+2];
-					    break;
-					}
-				    }
-				}
-			    }
-			}
-
-			/* store pixel */
-			if (__pix != 0) {
-			    __dstPtr[0] = (__pix >> 16 & 0xFF);
-			    __dstPtr[1] = (__pix >> 8) & 0xFF;
-			    __dstPtr[2] = __pix & 0xFF;
-			}
-			__dstPtr += 3;
-		    }
-		}
-		break;
-
-	    default:
-		for (__dstY = 0; __dstY < __newHeight; __dstY++) {
-		    double __pY, __sinPY, __cosPY;
+                            __pix = __blackPixel;
+                        } else {
+                            int __srcX;
+
+                            __srcX = (int)__nX;
+                            /* inside ? */
+                            if (__srcX >= __width) {
+#ifdef EARLY_OUT
+                                if (didFetchInRow) {
+                                    if (__rot1) break;
+                                }
+#endif
+                                __pix = __blackPixel;
+                            } else {
+                                double __nY;
+
+                                /* rotate Y */
+                                __nY = (__sin * __pX) + __cosPY;
+                                /* translate Y in source (origin to 0/0) */
+                                __nY = __nY + __halfH + 0.5;
+
+                                /* inside ? */
+                                if (__nY < 0) {
 #ifdef EARLY_OUT
-		    int didFetchInRow = 0;
+                                    if (didFetchInRow) {
+                                        if (__rot1) break;
+                                    }
+#endif
+                                    __pix = __blackPixel;
+                                } else {
+                                    int __srcY;
+
+                                    __srcY = (int)__nY;
+                                    /* inside ? */
+                                    if (__srcY >= __height) {
+#ifdef EARLY_OUT
+                                        if (didFetchInRow) {
+                                            if (__rot1) break;
+                                        }
+#endif
+                                        __pix = __blackPixel;
+                                    } else {
+                                        /* fetch source pixel */
+
+                                        int idx;
+#ifdef EARLY_OUT
+                                        didFetchInRow = 1;
 #endif
-		    __pY = (double)__dstY + __minY;
-
-		    __sinPY = __sin * __pY;
-		    __cosPY = __cos * __pY;
-
-		    __dstPtr = __dstRowPtr;
-		    __dstMask = 0x80;
-		    __dstRowPtr += __dstBytesPerRow;
-
-		    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
-			double __pX, __nX;
-			OBJ __pix;
-
-			/* translate X in destination (center to 0/0) */
-			__pX = (double)__dstX + __minX;
-			/* rotate X */
-			__nX = (__cos * __pX) - __sinPY;
-
-			/* translate X in source (origin to 0/0) */
-			__nX = __nX + __halfW + 0.5;
-
-			/* inside ? */
-			if (__nX < 0) {
+                                        idx = __srcY * __srcBytesPerRow + __srcX + __srcX + __srcX;
+                                        if ((unsigned)idx < __nSrcBytes) {
+                                            __pix = __srcBytes[idx];
+                                            __pix = (__pix<<8) | __srcBytes[idx+1];
+                                            __pix = (__pix<<8) | __srcBytes[idx+2];
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        /* store pixel */
+                        if (__pix != 0) {
+                            __dstPtr[0] = (__pix >> 16 & 0xFF);
+                            __dstPtr[1] = (__pix >> 8) & 0xFF;
+                            __dstPtr[2] = __pix & 0xFF;
+                        }
+                        __dstPtr += 3;
+                    }
+                }
+                break;
+
+            default:
+                for (__dstY = 0; __dstY < __newHeight; __dstY++) {
+                    double __pY, __sinPY, __cosPY;
 #ifdef EARLY_OUT
-			    if (didFetchInRow) {
-				if (__rot1) break;
-			    }
+                    int didFetchInRow = 0;
 #endif
-			    __pix = blackPixel;
-			} else {
-			    int __srcX;
-
-			    __srcX = (int)__nX;
-			    /* inside ? */
-			    if (__srcX >= __width) {
+                    __pY = (double)(__dstY + __minY);
+
+                    __sinPY = __sin * __pY;
+                    __cosPY = __cos * __pY;
+
+                    __dstPtr = __dstRowPtr;
+                    __dstMask = 0x80;
+                    __dstRowPtr += __dstBytesPerRow;
+
+                    for (__dstX = 0; __dstX < __newWidth; __dstX++) {
+                        double __pX, __nX;
+                        OBJ __pix;
+
+                        /* translate X in destination (center to 0/0) */
+                        __pX = (double)(__dstX + __minX);
+                        /* rotate X */
+                        __nX = (__cos * __pX) - __sinPY;
+
+                        /* translate X in source (origin to 0/0) */
+                        __nX = __nX + __halfW + 0.5;
+
+                        /* inside ? */
+                        if (__nX < 0) {
 #ifdef EARLY_OUT
-				if (didFetchInRow) {
-				    if (__rot1) break;
-				}
+                            if (didFetchInRow) {
+                                if (__rot1) break;
+                            }
 #endif
-				__pix = blackPixel;
-			    } else {
-				double __nY;
-
-				/* rotate Y */
-				__nY = (__sin * __pX) + __cosPY;
-				/* translate Y in source (origin to 0/0) */
-				__nY = __nY + __halfH + 0.5;
-
-				/* inside ? */
-				if (__nY < 0) {
+                            __pix = blackPixel;
+                        } else {
+                            int __srcX;
+
+                            __srcX = (int)__nX;
+                            /* inside ? */
+                            if (__srcX >= __width) {
 #ifdef EARLY_OUT
-				    if (didFetchInRow) {
-					if (__rot1) break;
-				    }
+                                if (didFetchInRow) {
+                                    if (__rot1) break;
+                                }
 #endif
-				    __pix = blackPixel;
-				} else {
-				    int __srcY;
-
-				    __srcY = (int)__nY;
-				    /* inside ? */
-				    if (__srcY >= __height) {
+                                __pix = blackPixel;
+                            } else {
+                                double __nY;
+
+                                /* rotate Y */
+                                __nY = (__sin * __pX) + __cosPY;
+                                /* translate Y in source (origin to 0/0) */
+                                __nY = __nY + __halfH + 0.5;
+
+                                /* inside ? */
+                                if (__nY < 0) {
 #ifdef EARLY_OUT
-					if (didFetchInRow) {
-					    if (__rot1) break;
-					}
+                                    if (didFetchInRow) {
+                                        if (__rot1) break;
+                                    }
 #endif
-					__pix = blackPixel;
-				    } else {
-					/* fetch source pixel */
-
-					static struct inlineCache valAt = _ILC2;
+                                    __pix = blackPixel;
+                                } else {
+                                    int __srcY;
+
+                                    __srcY = (int)__nY;
+                                    /* inside ? */
+                                    if (__srcY >= __height) {
 #ifdef EARLY_OUT
-					didFetchInRow = 1;
+                                        if (didFetchInRow) {
+                                            if (__rot1) break;
+                                        }
 #endif
-					__pix = (*valAt.ilc_func)(self,
-							      @symbol(valueAtX:y:),
-							      nil, &valAt,
-							      __MKSMALLINT(__srcX),
-							      __MKSMALLINT(__srcY));
-				    }
-				}
-			    }
-			}
-
-			/* store pixel */
-			{
-			    static struct inlineCache atPutVal = _ILC3;
-
-			    if (__pix != __MKSMALLINT(0)) {
-				(*atPutVal.ilc_func)(newImage,
-						      @symbol(atX:y:putValue:),
-						      nil, &atPutVal,
-						      __MKSMALLINT(__dstX),
-						      __MKSMALLINT(__dstY),
-						      __pix
-						     );
-			    }
-			}
-		    }
-		}
-		break;
-	}
-
-	bad = false;
+                                        __pix = blackPixel;
+                                    } else {
+                                        /* fetch source pixel */
+
+                                        static struct inlineCache valAt = _ILC2;
+#ifdef EARLY_OUT
+                                        didFetchInRow = 1;
+#endif
+                                        __pix = (*valAt.ilc_func)(self,
+                                                              @symbol(valueAtX:y:),
+                                                              nil, &valAt,
+                                                              __MKSMALLINT(__srcX),
+                                                              __MKSMALLINT(__srcY));
+                                    }
+                                }
+                            }
+                        }
+
+                        /* store pixel */
+                        {
+                            static struct inlineCache atPutVal = _ILC3;
+
+                            if (__pix != __MKSMALLINT(0)) {
+                                (*atPutVal.ilc_func)(newImage,
+                                                      @symbol(atX:y:putValue:),
+                                                      nil, &atPutVal,
+                                                      __MKSMALLINT(__dstX),
+                                                      __MKSMALLINT(__dstY),
+                                                      __pix
+                                                     );
+                            }
+                        }
+                    }
+                }
+                break;
+        }
+
+        bad = false;
     }
 %}.
 
     bad ifTrue:[
-	sinRot := radians negated sin.
-	cosRot := radians negated cos.
-
-	0 to:newHeight-1 do:[:dstY |
-	    pY := (dstY + minY).
-	    sinPY := (sinRot * pY).
-	    cosPY := (cosRot * pY).
-
-	    0 to:newWidth-1 do:[:dstX |
-
-		"/ translate center to origin
-		pX := (dstX + minX).
-
-		nX := (cosRot * pX) - sinPY.
-
-		"/ translate in source
-		srcX := nX + halfW.
-		srcX := srcX rounded.
-		"/ inside ?
-
-		(srcX >= 0 and:[srcX < width]) ifTrue:[
-		    nY := (sinRot * pX) + cosPY.
-		    srcY := nY + halfH.
-		    srcY := srcY rounded.
-
-		    "/ inside ?
-		    (srcY >= 0 and:[srcY < height]) ifTrue:[
-			pix := self valueAtX:srcX y:srcY
-		    ] ifFalse:[
-			pix := blackPixel.        
-		    ].
-		] ifFalse:[
-		    pix := blackPixel.        
-		].
-		pix ~~ blackPixel ifTrue:[
-		    newImage atX:dstX y:dstY putValue:pix.        
-		]
-	    ].
-	].
+        "/ should not happen
+        self primitiveFailed
+
+"/        sinRot := radians negated sin.
+"/        cosRot := radians negated cos.
+"/
+"/        0 to:newHeight-1 do:[:dstY |
+"/            pY := (dstY + minY).
+"/            sinPY := (sinRot * pY).
+"/            cosPY := (cosRot * pY).
+"/
+"/            0 to:newWidth-1 do:[:dstX |
+"/
+"/                "/ translate center to origin
+"/                pX := (dstX + minX).
+"/
+"/                nX := (cosRot * pX) - sinPY.
+"/
+"/                "/ translate in source
+"/                srcX := nX + halfW.
+"/                srcX := srcX rounded.
+"/                "/ inside ?
+"/
+"/                (srcX >= 0 and:[srcX < width]) ifTrue:[
+"/                    nY := (sinRot * pX) + cosPY.
+"/                    srcY := nY + halfH.
+"/                    srcY := srcY rounded.
+"/
+"/                    "/ inside ?
+"/                    (srcY >= 0 and:[srcY < height]) ifTrue:[
+"/                        pix := self valueAtX:srcX y:srcY
+"/                    ] ifFalse:[
+"/                        pix := blackPixel.        
+"/                    ].
+"/                ] ifFalse:[
+"/                    pix := blackPixel.        
+"/                ].
+"/                pix ~~ blackPixel ifTrue:[
+"/                    newImage atX:dstX y:dstY putValue:pix.        
+"/                ]
+"/            ].
+"/        ].
     ].
 
     ^ newImage
@@ -8286,9 +8355,9 @@
 
      i := Image fromFile:'bitmaps/gifImages/garfield.gif'.
      Transcript showCR:(
-	Time millisecondsToRun:[
-	   i rotated:45.
-	]
+        Time millisecondsToRun:[
+           i rotated:45.
+        ]
      ).
     "
     "
@@ -8299,10 +8368,12 @@
      v openAndWait.
      rot := 0.
      [true] whileTrue:[
-	rI := i rotated:rot.
-	v clear.
-	v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2).
-	rot := rot + 5.
+        rI := i rotated:rot.
+        rI := rI on:v device.
+        v clear.
+        v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2).
+        rot := rot + 5.
+        rI close.
      ]
     "
     "
@@ -8313,10 +8384,12 @@
      v openAndWait.
      rot := 0.
      [true] whileTrue:[
-	rI := i rotated:rot.
-	v clear.
-	v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2).
-	rot := rot + 5.
+        rI := i rotated:rot.
+        rI := rI on:v device.
+        v clear.
+        v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2).
+        rot := rot + 5.
+        rI close.
      ]
     "
 
@@ -8751,6 +8824,32 @@
 
 !Image methodsFor:'instance release'!
 
+close
+    "release device resources; destroy any device-resources"
+
+    deviceForm notNil ifTrue:[
+        deviceForm destroy.
+        deviceForm := nil.
+    ].
+    monoDeviceForm notNil ifTrue:[
+        monoDeviceForm destroy.
+        monoDeviceForm := nil.
+    ].
+    fullColorDeviceForm notNil ifTrue:[
+        fullColorDeviceForm destroy.
+        fullColorDeviceForm := nil.
+    ].
+
+    device := nil.
+    mask notNil ifTrue:[
+        mask close.
+    ].
+    Lobby unregister:self.
+
+    "Modified: 21.6.1996 / 19:08:19 / cg"
+    "Created: 24.4.1997 / 11:55:20 / cg"
+!
+
 disposed
     "some Image has been collected - nothing to do"
 !
@@ -10217,6 +10316,6 @@
 !Image class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.183 1997-04-23 13:39:31 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.184 1997-04-24 10:03:04 cg Exp $'
 ! !
 Image initialize!