/* Copyright (C) 1978-2001 Ken Turkowski. * * All rights reserved. * * Warranty Information * Even though I have reviewed this software, I make no warranty * or representation, either express or implied, with respect to this * software, its quality, accuracy, merchantability, or fitness for a * particular purpose. As a result, this software is provided "as is," * and you, its user, are assuming the entire risk as to its quality * and accuracy. * * This code may be used and freely distributed as long as it includes * this copyright notice and the above warranty information. */ #include /******************************************************************************** * Procedure declarations for header: RotateGWorld.h ********************************************************************************/ void RotateImage90CW( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ); void RotateImage90CCW( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ); void RotateImage180( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ); void RotateGWorld(GWorldPtr srcGW, GWorldPtr dstGW, long degrees); /******************************************************************************** * RotateImage90CW * Rotate buffer 90 degrees clockwise. * Height and width are specified in terms of the destination. ********************************************************************************/ void RotateImage90CW( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ) { register long count; register char *s0 = (char*)src + (width-1) * srcRB; /* lower left */ register char *d0 = (char*)dst; /* upper left */ switch (bytesPerPixel) { case 1: { register char *s, *d; for ( ; width--; s0 -= srcRB, d0 += sizeof(char)) for (count = height, s = (char*)s0, d = (char*)d0; count--; s++, d = (char*)((char*)d + dstRB)) *d = *s; } break; case 2: { register short *s, *d; for ( ; width--; s0 -= srcRB, d0 += sizeof(short)) for (count = height, s = (short*)s0, d = (short*)d0; count--; s++, d = (short*)((char*)d + dstRB)) *d = *s; } break; case 3: { register char *s, *d; for ( ; width--; s0 -= srcRB, d0 += 3) for (count = height, s = (char*)s0, d = (char*)d0; count--; s += 3, d += dstRB) { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; } } break; case 4: { register long *s, *d; for ( ; width--; s0 -= srcRB, d0 += sizeof(long)) for (count = height, s = (long*)s0, d = (long*)d0; count--; s++, d = (long*)((char*)d + dstRB)) *d = *s; } break; } } /******************************************************************************** * RotateImage90CCW * Rotate buffer 90 degrees counterclockwise. * Height and width are specified in terms of the destination. ********************************************************************************/ void RotateImage90CCW( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ) { register long count; register char *s0 = (char*)src + (height-1) * bytesPerPixel; /* upper right */ register char *d0 = (char*)dst; /* upper left */ switch (bytesPerPixel) { case 1: { register char *s, *d; for ( ; width--; s0 += srcRB, d0 += sizeof(char)) for (count = height, s = (char*)s0, d = (char*)d0; count--; s--, d = (char*)((char*)d + dstRB)) *d = *s; } break; case 2: { register short *s, *d; for ( ; width--; s0 += srcRB, d0 += sizeof(short)) for (count = height, s = (short*)s0, d = (short*)d0; count--; s--, d = (short*)((char*)d + dstRB)) *d = *s; } break; case 3: { register char *s, *d; for ( ; width--; s0 += srcRB, d0 += 3) for (count = height, s = (char*)s0, d = (char*)d0; count--; s -= 3, d += dstRB) { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; } } break; case 4: { register long *s, *d; for ( ; width--; s0 += srcRB, d0 += sizeof(long)) for (count = height, s = (long*)s0, d = (long*)d0; count--; s--, d = (long*)((char*)d + dstRB)) *d = *s; } break; } } /******************************************************************************** * RotateImage180 * Rotate buffer 180 degrees. * Height and width are specified in terms of the destination. ********************************************************************************/ void RotateImage180( void *src, long srcRB, void *dst, long dstRB, long width, long height, long bytesPerPixel ) { register long count; register char *s0 = (char*)src + (width-1) * bytesPerPixel + (height-1) * srcRB; /* lower right */ register char *d0 = (char*)dst; /* upper left */ switch (bytesPerPixel) { case 1: { register char *s, *d; for ( ; height--; s0 -= srcRB, d0 += dstRB) for (count = width, s = (char*)s0, d = (char*)d0; count--; s--, d++) *d = *s; } break; case 2: { register short *s, *d; for ( ; height--; s0 -= srcRB, d0 += dstRB) for (count = width, s = (short*)s0, d = (short*)d0; count--; s--, d++) *d = *s; } break; case 3: { register char *s, *d; for ( ; height--; s0 -= srcRB, d0 += dstRB) for (count = width, s = (char*)s0, d = (char*)d0; count--; s -= 3, d++) { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; } } break; case 4: { register long *s, *d; for ( ; height--; s0 -= srcRB, d0 += dstRB) for (count = width, s = (long*)s0, d = (long*)d0; count--; s--, d++) *d = *s; } break; } } typedef void (*RotateProc)(void *s, long srb, void *d, long drb, long w, long h, long dpb); /******************************************************************************** * RotateGWorld * Rotate buffer 90CW 90CCW and 180 degrees. * Height and width are specified in terms of the destination. ********************************************************************************/ void RotateGWorld(GWorldPtr srcGW, GWorldPtr dstGW, long degrees) { PixMapHandle srcPM, dstPM; void *srcBaseAddr, *dstBaseAddr; long srcRowBytes, dstRowBytes; long srcPixelBytes, dstPixelBytes; long dstWidth, dstHeight; Rect gwRect, pmRect; RotateProc rotate; /* Get src info */ srcPM = GetGWorldPixMap(srcGW); srcRowBytes = QTGetPixMapHandleRowBytes(srcPM); srcPixelBytes = (**srcPM).pixelSize >> 3; gwRect = srcGW->portRect; pmRect = (**srcPM).bounds; LockPixels(srcPM); srcBaseAddr = GetPixBaseAddr(srcPM) + (gwRect.left - pmRect.left) * srcPixelBytes + (gwRect.top - pmRect.top ) * srcRowBytes; /* Get dst info */ dstPM = GetGWorldPixMap(dstGW); dstRowBytes = QTGetPixMapHandleRowBytes(dstPM); dstPixelBytes = (**dstPM).pixelSize >> 3; gwRect = dstGW->portRect; pmRect = (**dstPM).bounds; dstWidth = gwRect.right - gwRect.left; dstHeight = gwRect.bottom - gwRect.top; LockPixels(dstPM); dstBaseAddr = GetPixBaseAddr(dstPM) + (gwRect.left - pmRect.left) * dstPixelBytes + (gwRect.top - pmRect.top ) * dstRowBytes; degrees = (degrees / 90) % 4; if (degrees < 0) degrees += 4; switch (degrees) { case 1: rotate = RotateImage90CW; break; case 2: rotate = RotateImage180; break; case 3: rotate = RotateImage90CCW; break; default: goto done; } (*rotate)(srcBaseAddr, srcRowBytes, dstBaseAddr, dstRowBytes, dstWidth, dstHeight, dstPixelBytes); done: UnlockPixels(srcPM); UnlockPixels(dstPM); }