Mercurial > projects > dwt-mac
diff dwt/graphics/ImageData.d @ 32:b9226997409c
Ported dwt.graphics.Image*
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Fri, 12 Sep 2008 13:44:30 +0200 |
parents | e831403a80a9 |
children | d8635bb48c7c |
line wrap: on
line diff
--- a/dwt/graphics/ImageData.d Fri Sep 12 12:36:09 2008 +0200 +++ b/dwt/graphics/ImageData.d Fri Sep 12 13:44:30 2008 +0200 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. + * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,25 +7,35 @@ * * Contributors: * IBM Corporation - initial API and implementation + * + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + * Jacob Carlborg <jacob.carlborg@gmail.com> *******************************************************************************/ module dwt.graphics.ImageData; -import dwt.dwthelper.utils; - - -import java.io.InputStream; import dwt.DWT; import dwt.DWTException; import dwt.internal.CloneableCompatibility; +public import dwt.dwthelper.InputStream; +import dwt.dwthelper.utils; +import dwt.graphics.Device; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.ImageDataLoader; +import dwt.graphics.PaletteData; +import dwt.graphics.RGB; + + /** * Instances of this class are device-independent descriptions * of images. They are typically used as an intermediate format - * between loading from or writing to streams and creating an + * between loading from or writing to streams and creating an * <code>Image</code>. * <p> - * Note that the public fields <code>x</code>, <code>y</code>, + * Note that the public fields <code>x</code>, <code>y</code>, * <code>disposalMethod</code> and <code>delayTime</code> are * typically only used when the image is in a set of images used * for animation. @@ -33,10 +43,13 @@ * * @see Image * @see ImageLoader + * @see <a href="http://www.eclipse.org/swt/snippets/#image">ImageData snippets</a> + * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ImageAnalyzer</a> + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public final class ImageData : CloneableCompatibility { - + /** * The width of the image, in pixels. */ @@ -122,7 +135,7 @@ * </p> */ public int maskPad; - + /** * The alpha data of the image. * <p> @@ -133,7 +146,7 @@ * </p> */ public byte[] alphaData; - + /** * The global alpha value to be used for every pixel. * <p> @@ -149,7 +162,7 @@ /** * The type of file from which the image was read. - * + * * It is expressed as one of the following values: * <dl> * <dt><code>IMAGE_BMP</code></dt> @@ -185,7 +198,7 @@ /** * A description of how to dispose of the current image * before displaying the next. - * + * * It is expressed as one of the following values: * <dl> * <dt><code>DM_UNSPECIFIED</code></dt> @@ -211,31 +224,40 @@ /** * Arbitrary channel width data to 8-bit conversion table. */ - static final byte[][] ANY_TO_EIGHT = new byte[9][]; - static { - for (int b = 0; b < 9; ++b) { - byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b]; - if (b is 0) continue; - int inc = 0; - for (int bit = 0x10000; (bit >>= b) !is 0;) inc |= bit; - for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = cast(byte)(v >> 8); + private static byte[][] ANY_TO_EIGHT; + private static byte[] ONE_TO_ONE_MAPPING; + + private static bool static_this_completed = false; + private static void static_this() { + if( static_this_completed ) return; + synchronized { + if( static_this_completed ) return; + ANY_TO_EIGHT = new byte[][](9); + for (int b = 0; b < 9; ++b) { + byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b]; + if (b is 0) continue; + int inc = 0; + for (int bit = 0x10000; (bit >>= b) !is 0;) inc |= bit; + for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = cast(byte)(v >> 8); + } + ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8]; + static_this_completed = true; } } - static final byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8]; /** * Scaled 8x8 Bayer dither matrix. */ - static final int[][] DITHER_MATRIX = { - { 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 }, - { 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 }, - { 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 }, - { 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 }, - { 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 }, - { 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 }, - { 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 }, - { 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 } - }; + static const int[][] DITHER_MATRIX = [ + [ 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 ], + [ 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 ], + [ 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 ], + [ 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 ], + [ 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 ], + [ 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 ], + [ 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 ], + [ 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 ] + ]; /** * Constructs a new, empty ImageData with the given width, height, @@ -293,7 +315,7 @@ * <p> * This constructor is provided for convenience when loading a single * image only. If the stream contains multiple images, only the first - * one will be loaded. To load multiple images, use + * one will be loaded. To load multiple images, use * <code>ImageLoader.load()</code>. * </p><p> * This constructor may be used to load a resource as follows: @@ -359,7 +381,7 @@ * <p> * This constructor is provided for convenience when loading a single * image only. If the file contains multiple images, only the first - * one will be loaded. To load multiple images, use + * one will be loaded. To load multiple images, use * <code>ImageLoader.load()</code>. * </p> * @@ -401,7 +423,7 @@ /** * Prevents uninitialized instances from being created outside the package. */ -this() { +private this() { } /** @@ -416,7 +438,6 @@ byte[] alphaData, int alpha, int transparentPixel, int type, int x, int y, int disposalMethod, int delayTime) { - if (palette is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (!(depth is 1 || depth is 2 || depth is 4 || depth is 8 || depth is 16 || depth is 24 || depth is 32)) { @@ -429,7 +450,7 @@ int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1)) / scanlinePad * scanlinePad; - + /* * When the image is being loaded from a PNG, we need to use the theoretical minimum * number of bytes per line to check whether there is enough data, because the actual @@ -493,7 +514,7 @@ this.delayTime = delayTime; } -/** +/** * Invokes internal DWT functionality to create a new instance of * this class. * <p> @@ -585,6 +606,8 @@ /** * Returns the alpha value at offset <code>x</code> in * scanline <code>y</code> in the receiver's alpha data. + * The alpha value is between 0 (transparent) and + * 255 (opaque). * * @param x the x coordinate of the pixel to get the alpha value of * @param y the y coordinate of the pixel to get the alpha value of @@ -604,7 +627,9 @@ /** * Returns <code>getWidth</code> alpha values starting at offset * <code>x</code> in scanline <code>y</code> in the receiver's alpha - * data starting at <code>startIndex</code>. + * data starting at <code>startIndex</code>. The alpha values + * are unsigned, between <code>(byte)0</code> (transparent) and + * <code>(byte)255</code> (opaque). * * @param x the x position of the pixel to begin getting alpha values * @param y the y position of the pixel to begin getting alpha values @@ -693,6 +718,7 @@ } else { return 1; } + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); return 0; @@ -841,6 +867,7 @@ } } return; + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); } @@ -1035,6 +1062,7 @@ } } return; + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); } @@ -1084,7 +1112,7 @@ /** * Returns the byte order of the receiver. - * + * * @return MSB_FIRST or LSB_FIRST */ int getByteOrder() { @@ -1103,9 +1131,9 @@ */ public ImageData scaledTo(int width, int height) { /* Create a destination image with no data */ - final bool flipX = (width < 0); + bool flipX = (width < 0); if (flipX) width = - width; - final bool flipY = (height < 0); + bool flipY = (height < 0); if (flipY) height = - height; ImageData dest = new ImageData( @@ -1125,7 +1153,7 @@ ALPHA_OPAQUE, null, 0, 0, 0, dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null, flipX, flipY); - + /* Scale the image mask or alpha */ if (maskData !is null) { dest.maskPad = this.maskPad; @@ -1155,6 +1183,8 @@ /** * Sets the alpha value at offset <code>x</code> in * scanline <code>y</code> in the receiver's alpha data. + * The alpha value must be between 0 (transparent) + * and 255 (opaque). * * @param x the x coordinate of the alpha value to set * @param y the y coordinate of the alpha value to set @@ -1167,16 +1197,17 @@ public void setAlpha(int x, int y, int alpha) { if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255) DWT.error(DWT.ERROR_INVALID_ARGUMENT); - + if (alphaData is null) alphaData = new byte[width * height]; - alphaData[y * width + x] = cast(byte)alpha; + alphaData[y * width + x] = cast(byte)alpha; } /** * Sets the alpha values starting at offset <code>x</code> in * scanline <code>y</code> in the receiver's alpha data to the * values from the array <code>alphas</code> starting at - * <code>startIndex</code>. + * <code>startIndex</code>. The alpha values must be between + * <code>(byte)0</code> (transparent) and <code>(byte)255</code> (opaque) * * @param x the x coordinate of the pixel to being setting the alpha values * @param y the y coordinate of the pixel to being setting the alpha values @@ -1195,7 +1226,7 @@ if (alphas is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); if (putWidth is 0) return; - + if (alphaData is null) alphaData = new byte[width * height]; // may throw an IndexOutOfBoundsException System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth); @@ -1269,6 +1300,7 @@ data[index] = cast(byte)(theByte & (mask ^ -1)); } return; + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); } @@ -1347,7 +1379,7 @@ } return; case 2: - byte [] masks = { cast(byte)0xFC, cast(byte)0xF3, cast(byte)0xCF, cast(byte)0x3F }; + byte [] masks = [ cast(byte)0xFC, cast(byte)0xF3, cast(byte)0xCF, cast(byte)0x3F ]; index = (y * bytesPerLine) + (x >> 2); int offset = 3 - (x % 4); while (n > 0) { @@ -1394,6 +1426,7 @@ } } return; + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); } @@ -1526,7 +1559,7 @@ } return; case 2: - byte [] masks = { cast(byte)0xFC, cast(byte)0xF3, cast(byte)0xCF, cast(byte)0x3F }; + byte [] masks = [ cast(byte)0xFC, cast(byte)0xF3, cast(byte)0xCF, cast(byte)0x3F ]; index = (y * bytesPerLine) + (x >> 2); int offset = 3 - (x % 4); while (n > 0) { @@ -1573,6 +1606,7 @@ } } return; + default: } DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH); } @@ -1581,7 +1615,7 @@ * Returns a palette with 2 colors: black & white. */ static PaletteData bwPalette() { - return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)}); + return new PaletteData( [ new RGB(0, 0, 0), new RGB(255, 255, 255) ] ); } /** @@ -1627,14 +1661,14 @@ static final ImageData convertMask(ImageData mask) { if (mask.depth is 1) return mask; - PaletteData palette = new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255,255,255)}); + PaletteData palette = new PaletteData([new RGB(0, 0, 0), new RGB(255,255,255)]); ImageData newMask = new ImageData(mask.width, mask.height, 1, palette); /* Find index of black in mask palette */ int blackIndex = 0; RGB[] rgbs = mask.getRGBs(); if (rgbs !is null) { while (blackIndex < rgbs.length) { - if (rgbs[blackIndex].equals(palette.colors[0])) break; + if (rgbs[blackIndex] is palette.colors[0] ) break; blackIndex++; } } @@ -1656,7 +1690,7 @@ static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) { if (pad is newPad) return data; int stride = (width * depth + 7) / 8; - int bpl = (stride + (pad - 1)) / pad * pad; + int bpl = (stride + (pad - 1)) / pad * pad; int newBpl = (stride + (newPad - 1)) / newPad * newPad; byte[] newData = new byte[height * newBpl]; int srcIndex = 0, destIndex = 0; @@ -1671,7 +1705,7 @@ /** * Blit operation bits to be OR'ed together to specify the desired operation. */ -static final int +static const int BLIT_SRC = 1, // copy source directly, else applies logic operations BLIT_ALPHA = 2, // enable alpha blending BLIT_DITHER = 4; // enable dithering in low color modes @@ -1679,7 +1713,7 @@ /** * Alpha mode, values 0 - 255 specify global alpha level */ -static final int +static const int ALPHA_OPAQUE = 255, // Fully opaque (ignores any alpha data) ALPHA_TRANSPARENT = 0, // Fully transparent (ignores any alpha data) ALPHA_CHANNEL_SEPARATE = -1, // Use alpha channel from separate alphaData @@ -1692,13 +1726,13 @@ /** * Byte and bit order constants. */ -static final int LSB_FIRST = 0; -static final int MSB_FIRST = 1; +static const int LSB_FIRST = 0; +static const int MSB_FIRST = 1; /** * Data types (internal) */ -private static final int +private static const int // direct / true color formats with arbitrary masks & shifts TYPE_GENERIC_8 = 0, TYPE_GENERIC_16_MSB = 1, @@ -1721,7 +1755,7 @@ * the masks are ignored. Hence when not changing the image * data format, 0 may be specified for the masks. * </p> - * + * * @param op the blitter operation: a combination of BLIT_xxx flags * (see BLIT_xxx constants) * @param srcData the source byte array containing image data @@ -1769,19 +1803,22 @@ int destX, int destY, int destWidth, int destHeight, int destRedMask, int destGreenMask, int destBlueMask, bool flipX, bool flipY) { + + static_this(); + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode is ALPHA_TRANSPARENT)) return; // these should be supplied as params later - final int srcAlphaMask = 0, destAlphaMask = 0; + const int srcAlphaMask = 0, destAlphaMask = 0; /*** Prepare scaling data ***/ - final int dwm1 = destWidth - 1; - final int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; - final int dhm1 = destHeight - 1; - final int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; + int dwm1 = destWidth - 1; + int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; + int dhm1 = destHeight - 1; + int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; /*** Prepare source-related data ***/ - final int sbpp, stype; + int sbpp, stype; switch (srcDepth) { case 8: sbpp = 1; @@ -1802,11 +1839,11 @@ default: //throw new IllegalArgumentException("Invalid source type"); return; - } + } int spr = srcY * srcStride + srcX * sbpp; /*** Prepare destination-related data ***/ - final int dbpp, dtype; + int dbpp, dtype; switch (destDepth) { case 8: dbpp = 1; @@ -1827,10 +1864,10 @@ default: //throw new IllegalArgumentException("Invalid destination type"); return; - } + } int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; - final int dprxi = (flipX) ? -dbpp : dbpp; - final int dpryi = (flipY) ? -destStride : destStride; + int dprxi = (flipX) ? -dbpp : dbpp; + int dpryi = (flipY) ? -destStride : destStride; /*** Prepare special processing data ***/ int apr; @@ -1879,7 +1916,7 @@ sp += (sfx >>> 16); } } - break; + break; case 2: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { @@ -1910,35 +1947,36 @@ } } break; + default: } return; } /*** Comprehensive blit (apply transformations) ***/ - final int srcRedShift = getChannelShift(srcRedMask); - final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; - final int srcGreenShift = getChannelShift(srcGreenMask); - final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; - final int srcBlueShift = getChannelShift(srcBlueMask); - final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; - final int srcAlphaShift = getChannelShift(srcAlphaMask); - final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; + int srcRedShift = getChannelShift(srcRedMask); + byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; + int srcGreenShift = getChannelShift(srcGreenMask); + byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; + int srcBlueShift = getChannelShift(srcBlueMask); + byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; + int srcAlphaShift = getChannelShift(srcAlphaMask); + byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; - final int destRedShift = getChannelShift(destRedMask); - final int destRedWidth = getChannelWidth(destRedMask, destRedShift); - final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; - final int destRedPreShift = 8 - destRedWidth; - final int destGreenShift = getChannelShift(destGreenMask); - final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); - final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; - final int destGreenPreShift = 8 - destGreenWidth; - final int destBlueShift = getChannelShift(destBlueMask); - final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); - final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; - final int destBluePreShift = 8 - destBlueWidth; - final int destAlphaShift = getChannelShift(destAlphaMask); - final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); - final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; - final int destAlphaPreShift = 8 - destAlphaWidth; + int destRedShift = getChannelShift(destRedMask); + int destRedWidth = getChannelWidth(destRedMask, destRedShift); + byte[] destReds = ANY_TO_EIGHT[destRedWidth]; + int destRedPreShift = 8 - destRedWidth; + int destGreenShift = getChannelShift(destGreenMask); + int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); + byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; + int destGreenPreShift = 8 - destGreenWidth; + int destBlueShift = getChannelShift(destBlueMask); + int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); + byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; + int destBluePreShift = 8 - destBlueWidth; + int destAlphaShift = getChannelShift(destAlphaMask); + int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); + byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; + int destAlphaPreShift = 8 - destAlphaWidth; int ap = apr, alpha = alphaMode; int r = 0, g = 0, b = 0, a = 0; @@ -1954,7 +1992,7 @@ /*** READ NEXT PIXEL ***/ switch (stype) { case TYPE_GENERIC_8: { - final int data = srcData[sp] & 0xff; + int data = srcData[sp] & 0xff; sp += (sfx >>> 16); r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -1962,7 +2000,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_MSB: { - final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); + int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); sp += (sfx >>> 16) * 2; r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -1970,7 +2008,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_LSB: { - final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); + int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); sp += (sfx >>> 16) * 2; r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -1978,7 +2016,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_24: { - final int data = (( ((srcData[sp] & 0xff) << 8) | + int data = (( ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp + 2] & 0xff); sp += (sfx >>> 16) * 3; @@ -1988,7 +2026,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_MSB: { - final int data = (( (( ((srcData[sp] & 0xff) << 8) | + int data = (( (( ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp + 2] & 0xff)) << 8) | (srcData[sp + 3] & 0xff); @@ -1999,7 +2037,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_LSB: { - final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | + int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | (srcData[sp + 2] & 0xff)) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp] & 0xff); @@ -2009,6 +2047,7 @@ b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; + default: } /*** DO SPECIAL PROCESSING IF REQUIRED ***/ @@ -2023,7 +2062,7 @@ case ALPHA_MASK_UNPACKED: alpha = (alphaData[ap] !is 0) ? 0x10000 : 0; ap += (sfx >> 16); - break; + break; case ALPHA_MASK_PACKED: alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; ap += (sfx >> 16); @@ -2037,33 +2076,34 @@ } } break; + default: } if (alpha !is 0x10000) { if (alpha is 0x0000) continue; switch (dtype) { case TYPE_GENERIC_8: { - final int data = destData[dp] & 0xff; + int data = destData[dp] & 0xff; rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_MSB: { - final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); + int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_LSB: { - final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); + int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_24: { - final int data = (( ((destData[dp] & 0xff) << 8) | + int data = (( ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp + 2] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; @@ -2072,7 +2112,7 @@ aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_MSB: { - final int data = (( (( ((destData[dp] & 0xff) << 8) | + int data = (( (( ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp + 2] & 0xff)) << 8) | (destData[dp + 3] & 0xff); @@ -2082,7 +2122,7 @@ aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_LSB: { - final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | + int data = (( (( ((destData[dp + 3] & 0xff) << 8) | (destData[dp + 2] & 0xff)) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp] & 0xff); @@ -2091,6 +2131,7 @@ bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; + default: } // Perform alpha blending a = aq + ((a - aq) * alpha >> 16); @@ -2100,7 +2141,7 @@ } /*** WRITE NEXT PIXEL ***/ - final int data = + int data = (r >>> destRedPreShift << destRedShift) | (g >>> destGreenPreShift << destGreenShift) | (b >>> destBluePreShift << destBlueShift) | @@ -2134,9 +2175,10 @@ destData[dp + 2] = cast(byte) (data >>> 16); destData[dp + 3] = cast(byte) (data >>> 24); } break; + default: } } - } + } } /** @@ -2146,7 +2188,7 @@ * arrays may be null if no alpha blending or dither is to be * performed. * </p> - * + * * @param op the blitter operation: a combination of BLIT_xxx flags * (see BLIT_xxx constants) * @param srcData the source byte array containing image data @@ -2194,16 +2236,19 @@ int destX, int destY, int destWidth, int destHeight, byte[] destReds, byte[] destGreens, byte[] destBlues, bool flipX, bool flipY) { + + static_this(); + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode is ALPHA_TRANSPARENT)) return; /*** Prepare scaling data ***/ - final int dwm1 = destWidth - 1; - final int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; - final int dhm1 = destHeight - 1; - final int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; + int dwm1 = destWidth - 1; + int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; + int dhm1 = destHeight - 1; + int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; /*** Prepare source-related data ***/ - final int stype; + int stype; switch (srcDepth) { case 8: stype = TYPE_INDEX_8; @@ -2222,12 +2267,12 @@ break; default: //throw new IllegalArgumentException("Invalid source type"); - return; - } + return; + } int spr = srcY * srcStride + srcX; /*** Prepare destination-related data ***/ - final int dtype; + int dtype; switch (destDepth) { case 8: dtype = TYPE_INDEX_8; @@ -2247,10 +2292,10 @@ default: //throw new IllegalArgumentException("Invalid source type"); return; - } + } int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); - final int dprxi = (flipX) ? -1 : 1; - final int dpryi = (flipY) ? -destStride : destStride; + int dprxi = (flipX) ? -1 : 1; + int dpryi = (flipY) ? -destStride : destStride; /*** Prepare special processing data ***/ int apr; @@ -2281,7 +2326,7 @@ alphaMode = 0x10000; apr = 0; } - final bool ditherEnabled = (op & BLIT_DITHER) !is 0; + bool ditherEnabled = (op & BLIT_DITHER) !is 0; /*** Blit ***/ int dp = dpr; @@ -2338,6 +2383,7 @@ if (minDistance !is 0) isExactPaletteMapping = false; } break; + default: } if ((paletteMapping !is null) && (isExactPaletteMapping || ! ditherEnabled)) { if ((stype is dtype) && (alphaMode is 0x10000)) { @@ -2350,11 +2396,11 @@ sp += (sfx >>> 16); } } - break; + break; case TYPE_INDEX_4: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { - final int v; + int v; if ((sp & 1) !is 0) v = paletteMapping[srcData[sp >> 1] & 0x0f]; else v = (srcData[sp >> 1] >>> 4) & 0x0f; sp += (sfx >>> 16); @@ -2366,33 +2412,34 @@ case TYPE_INDEX_2: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { - final int index = paletteMapping[(srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03]; + int index = paletteMapping[(srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03]; sp += (sfx >>> 16); - final int shift = 6 - (dp & 3) * 2; + int shift = 6 - (dp & 3) * 2; destData[dp >> 2] = cast(byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); } } - break; + break; case TYPE_INDEX_1_MSB: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { - final int index = paletteMapping[(srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01]; + int index = paletteMapping[(srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01]; sp += (sfx >>> 16); - final int shift = 7 - (dp & 7); - destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); - } - } - break; - case TYPE_INDEX_1_LSB: - for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { - for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { - final int index = paletteMapping[(srcData[sp >> 3] >>> (sp & 7)) & 0x01]; - sp += (sfx >>> 16); - final int shift = dp & 7; + int shift = 7 - (dp & 7); destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); } } break; + case TYPE_INDEX_1_LSB: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + int index = paletteMapping[(srcData[sp >> 3] >>> (sp & 7)) & 0x01]; + sp += (sfx >>> 16); + int shift = dp & 7; + destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); + } + } + break; + default: } } else { /*** Convert between indexed modes using mapping and mask ***/ @@ -2409,20 +2456,20 @@ case TYPE_INDEX_8: index = srcData[sp] & 0xff; sp += (sfx >>> 16); - break; + break; case TYPE_INDEX_4: if ((sp & 1) !is 0) index = srcData[sp >> 1] & 0x0f; else index = (srcData[sp >> 1] >>> 4) & 0x0f; sp += (sfx >>> 16); - break; + break; case TYPE_INDEX_2: index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; sp += (sfx >>> 16); - break; + break; case TYPE_INDEX_1_MSB: index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; sp += (sfx >>> 16); - break; + break; case TYPE_INDEX_1_LSB: index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; sp += (sfx >>> 16); @@ -2433,12 +2480,12 @@ /*** APPLY MASK ***/ switch (alphaMode) { case ALPHA_MASK_UNPACKED: { - final byte mask = alphaData[ap]; + byte mask = alphaData[ap]; ap += (sfx >> 16); if (mask is 0) continue; } break; case ALPHA_MASK_PACKED: { - final int mask = alphaData[ap >> 3] & (1 << (ap & 7)); + int mask = alphaData[ap >> 3] & (1 << (ap & 7)); ap += (sfx >> 16); if (mask is 0) continue; } break; @@ -2450,7 +2497,7 @@ if (i < alphaData.length) continue; } break; case ALPHA_MASK_RGB: { - final byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index]; + byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index]; int i = 0; while (i < alphaData.length) { if ((r is alphaData[i]) && (g is alphaData[i + 1]) && (b is alphaData[i + 2])) break; @@ -2458,9 +2505,10 @@ } if (i < alphaData.length) continue; } break; + default: } index = paletteMapping[index] & 0xff; - + /*** WRITE NEXT PIXEL ***/ switch (dtype) { case TYPE_INDEX_8: @@ -2469,32 +2517,33 @@ case TYPE_INDEX_4: if ((dp & 1) !is 0) destData[dp >> 1] = cast(byte)((destData[dp >> 1] & 0xf0) | index); else destData[dp >> 1] = cast(byte)((destData[dp >> 1] & 0x0f) | (index << 4)); - break; + break; case TYPE_INDEX_2: { - final int shift = 6 - (dp & 3) * 2; + int shift = 6 - (dp & 3) * 2; destData[dp >> 2] = cast(byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); - } break; + } break; case TYPE_INDEX_1_MSB: { - final int shift = 7 - (dp & 7); + int shift = 7 - (dp & 7); destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); } break; case TYPE_INDEX_1_LSB: { - final int shift = dp & 7; + int shift = dp & 7; destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); - } break; + } break; + default: } } } } return; } - + /*** Comprehensive blit (apply transformations) ***/ int alpha = alphaMode; int index = 0; int indexq = 0; int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; - final int[] rerr, gerr, berr; + int[] rerr, gerr, berr; if (ditherEnabled) { rerr = new int[destWidth + 2]; gerr = new int[destWidth + 2]; @@ -2534,6 +2583,7 @@ index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; sp += (sfx >>> 16); break; + default: } /*** DO SPECIAL PROCESSING IF REQUIRED ***/ @@ -2546,7 +2596,7 @@ case ALPHA_MASK_UNPACKED: alpha = (alphaData[ap] !is 0) ? 0x10000 : 0; ap += (sfx >> 16); - break; + break; case ALPHA_MASK_PACKED: alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; ap += (sfx >> 16); @@ -2568,6 +2618,7 @@ } if (i < alphaData.length) continue; } break; + default: } if (alpha !is 0x10000) { if (alpha is 0x0000) continue; @@ -2588,11 +2639,12 @@ case TYPE_INDEX_1_LSB: indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; break; + default: } // Perform alpha blending - final int rq = destReds[indexq] & 0xff; - final int gq = destGreens[indexq] & 0xff; - final int bq = destBlues[indexq] & 0xff; + int rq = destReds[indexq] & 0xff; + int gq = destGreens[indexq] & 0xff; + int bq = destBlues[indexq] & 0xff; r = rq + ((r - rq) * alpha >> 16); g = gq + ((g - gq) * alpha >> 16); b = bq + ((b - bq) * alpha >> 16); @@ -2628,7 +2680,7 @@ } if (ditherEnabled) { // Floyd-Steinberg error diffusion, cont'd... - final int dxm1 = dx - 1, dxp1 = dx + 1; + int dxm1 = dx - 1, dxp1 = dx + 1; int acc; rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; rerr[dx] += acc += lrerr + lrerr; @@ -2651,17 +2703,18 @@ else destData[dp >> 1] = cast(byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); break; case TYPE_INDEX_2: { - final int shift = 6 - (dp & 3) * 2; + int shift = 6 - (dp & 3) * 2; destData[dp >> 2] = cast(byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); - } break; + } break; case TYPE_INDEX_1_MSB: { - final int shift = 7 - (dp & 7); + int shift = 7 - (dp & 7); destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); } break; case TYPE_INDEX_1_LSB: { - final int shift = dp & 7; + int shift = dp & 7; destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); - } break; + } break; + default: } } } @@ -2673,7 +2726,7 @@ * Note: The source and destination masks and palettes must * always be fully specified. * </p> - * + * * @param op the blitter operation: a combination of BLIT_xxx flags * (see BLIT_xxx constants) * @param srcData the source byte array containing image data @@ -2721,19 +2774,22 @@ int destX, int destY, int destWidth, int destHeight, int destRedMask, int destGreenMask, int destBlueMask, bool flipX, bool flipY) { + + static_this(); + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode is ALPHA_TRANSPARENT)) return; // these should be supplied as params later - final int destAlphaMask = 0; + int destAlphaMask = 0; /*** Prepare scaling data ***/ - final int dwm1 = destWidth - 1; - final int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; - final int dhm1 = destHeight - 1; - final int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; + int dwm1 = destWidth - 1; + int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; + int dhm1 = destHeight - 1; + int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; /*** Prepare source-related data ***/ - final int stype; + int stype; switch (srcDepth) { case 8: stype = TYPE_INDEX_8; @@ -2753,11 +2809,11 @@ default: //throw new IllegalArgumentException("Invalid source type"); return; - } + } int spr = srcY * srcStride + srcX; /*** Prepare destination-related data ***/ - final int dbpp, dtype; + int dbpp, dtype; switch (destDepth) { case 8: dbpp = 1; @@ -2778,10 +2834,10 @@ default: //throw new IllegalArgumentException("Invalid destination type"); return; - } + } int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; - final int dprxi = (flipX) ? -dbpp : dbpp; - final int dpryi = (flipY) ? -destStride : destStride; + int dprxi = (flipX) ? -dbpp : dbpp; + int dpryi = (flipY) ? -destStride : destStride; /*** Prepare special processing data ***/ int apr; @@ -2814,22 +2870,22 @@ } /*** Comprehensive blit (apply transformations) ***/ - final int destRedShift = getChannelShift(destRedMask); - final int destRedWidth = getChannelWidth(destRedMask, destRedShift); - final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; - final int destRedPreShift = 8 - destRedWidth; - final int destGreenShift = getChannelShift(destGreenMask); - final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); - final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; - final int destGreenPreShift = 8 - destGreenWidth; - final int destBlueShift = getChannelShift(destBlueMask); - final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); - final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; - final int destBluePreShift = 8 - destBlueWidth; - final int destAlphaShift = getChannelShift(destAlphaMask); - final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); - final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; - final int destAlphaPreShift = 8 - destAlphaWidth; + int destRedShift = getChannelShift(destRedMask); + int destRedWidth = getChannelWidth(destRedMask, destRedShift); + byte[] destReds = ANY_TO_EIGHT[destRedWidth]; + int destRedPreShift = 8 - destRedWidth; + int destGreenShift = getChannelShift(destGreenMask); + int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); + byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; + int destGreenPreShift = 8 - destGreenWidth; + int destBlueShift = getChannelShift(destBlueMask); + int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); + byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; + int destBluePreShift = 8 - destBlueWidth; + int destAlphaShift = getChannelShift(destAlphaMask); + int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); + byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; + int destAlphaPreShift = 8 - destAlphaWidth; int dp = dpr; int sp = spr; @@ -2867,6 +2923,7 @@ index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; sp += (sfx >>> 16); break; + default: } /*** DO SPECIAL PROCESSING IF REQUIRED ***/ @@ -2881,7 +2938,7 @@ case ALPHA_MASK_UNPACKED: alpha = (alphaData[ap] !is 0) ? 0x10000 : 0; ap += (sfx >> 16); - break; + break; case ALPHA_MASK_PACKED: alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; ap += (sfx >> 16); @@ -2903,33 +2960,34 @@ } if (i < alphaData.length) continue; } break; + default: } if (alpha !is 0x10000) { if (alpha is 0x0000) continue; switch (dtype) { case TYPE_GENERIC_8: { - final int data = destData[dp] & 0xff; + int data = destData[dp] & 0xff; rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_MSB: { - final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); + int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_LSB: { - final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); + int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_24: { - final int data = (( ((destData[dp] & 0xff) << 8) | + int data = (( ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp + 2] & 0xff); rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; @@ -2938,7 +2996,7 @@ aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_MSB: { - final int data = (( (( ((destData[dp] & 0xff) << 8) | + int data = (( (( ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp + 2] & 0xff)) << 8) | (destData[dp + 3] & 0xff); @@ -2948,7 +3006,7 @@ aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_LSB: { - final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | + int data = (( (( ((destData[dp + 3] & 0xff) << 8) | (destData[dp + 2] & 0xff)) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp] & 0xff); @@ -2957,6 +3015,7 @@ bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; } break; + default: } // Perform alpha blending a = aq + ((a - aq) * alpha >> 16); @@ -2966,7 +3025,7 @@ } /*** WRITE NEXT PIXEL ***/ - final int data = + int data = (r >>> destRedPreShift << destRedShift) | (g >>> destGreenPreShift << destGreenShift) | (b >>> destBluePreShift << destBlueShift) | @@ -3000,9 +3059,10 @@ destData[dp + 2] = cast(byte) (data >>> 16); destData[dp + 3] = cast(byte) (data >>> 24); } break; + default: } } - } + } } /** @@ -3011,7 +3071,7 @@ * Note: The source and destination masks and palettes must * always be fully specified. * </p> - * + * * @param op the blitter operation: a combination of BLIT_xxx flags * (see BLIT_xxx constants) * @param srcData the source byte array containing image data @@ -3059,19 +3119,22 @@ int destX, int destY, int destWidth, int destHeight, byte[] destReds, byte[] destGreens, byte[] destBlues, bool flipX, bool flipY) { + + static_this(); + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode is ALPHA_TRANSPARENT)) return; // these should be supplied as params later - final int srcAlphaMask = 0; + int srcAlphaMask = 0; /*** Prepare scaling data ***/ - final int dwm1 = destWidth - 1; - final int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; - final int dhm1 = destHeight - 1; - final int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; + int dwm1 = destWidth - 1; + int sfxi = (dwm1 !is 0) ? cast(int)(((cast(long)srcWidth << 16) - 1) / dwm1) : 0; + int dhm1 = destHeight - 1; + int sfyi = (dhm1 !is 0) ? cast(int)(((cast(long)srcHeight << 16) - 1) / dhm1) : 0; /*** Prepare source-related data ***/ - final int sbpp, stype; + int sbpp, stype; switch (srcDepth) { case 8: sbpp = 1; @@ -3092,11 +3155,11 @@ default: //throw new IllegalArgumentException("Invalid source type"); return; - } + } int spr = srcY * srcStride + srcX * sbpp; /*** Prepare destination-related data ***/ - final int dtype; + int dtype; switch (destDepth) { case 8: dtype = TYPE_INDEX_8; @@ -3116,10 +3179,10 @@ default: //throw new IllegalArgumentException("Invalid source type"); return; - } + } int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); - final int dprxi = (flipX) ? -1 : 1; - final int dpryi = (flipY) ? -destStride : destStride; + int dprxi = (flipX) ? -1 : 1; + int dpryi = (flipY) ? -destStride : destStride; /*** Prepare special processing data ***/ int apr; @@ -3152,17 +3215,17 @@ alphaMode = 0x10000; apr = 0; } - final bool ditherEnabled = (op & BLIT_DITHER) !is 0; + bool ditherEnabled = (op & BLIT_DITHER) !is 0; /*** Comprehensive blit (apply transformations) ***/ - final int srcRedShift = getChannelShift(srcRedMask); - final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; - final int srcGreenShift = getChannelShift(srcGreenMask); - final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; - final int srcBlueShift = getChannelShift(srcBlueMask); - final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; - final int srcAlphaShift = getChannelShift(srcAlphaMask); - final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; + int srcRedShift = getChannelShift(srcRedMask); + byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; + int srcGreenShift = getChannelShift(srcGreenMask); + byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; + int srcBlueShift = getChannelShift(srcBlueMask); + byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; + int srcAlphaShift = getChannelShift(srcAlphaMask); + byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; int dp = dpr; int sp = spr; @@ -3170,7 +3233,7 @@ int r = 0, g = 0, b = 0, a = 0; int indexq = 0; int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; - final int[] rerr, gerr, berr; + int[] rerr, gerr, berr; int destPaletteSize = 1 << destDepth; if ((destReds !is null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length; if (ditherEnabled) { @@ -3192,7 +3255,7 @@ /*** READ NEXT PIXEL ***/ switch (stype) { case TYPE_GENERIC_8: { - final int data = srcData[sp] & 0xff; + int data = srcData[sp] & 0xff; sp += (sfx >>> 16); r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -3200,7 +3263,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_MSB: { - final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); + int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); sp += (sfx >>> 16) * 2; r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -3208,7 +3271,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_16_LSB: { - final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); + int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); sp += (sfx >>> 16) * 2; r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; @@ -3216,7 +3279,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_24: { - final int data = (( ((srcData[sp] & 0xff) << 8) | + int data = (( ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp + 2] & 0xff); sp += (sfx >>> 16) * 3; @@ -3226,7 +3289,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_MSB: { - final int data = (( (( ((srcData[sp] & 0xff) << 8) | + int data = (( (( ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp + 2] & 0xff)) << 8) | (srcData[sp + 3] & 0xff); @@ -3237,7 +3300,7 @@ a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; case TYPE_GENERIC_32_LSB: { - final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | + int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | (srcData[sp + 2] & 0xff)) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp] & 0xff); @@ -3247,6 +3310,7 @@ b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; } break; + default: } /*** DO SPECIAL PROCESSING IF REQUIRED ***/ @@ -3261,7 +3325,7 @@ case ALPHA_MASK_UNPACKED: alpha = (alphaData[ap] !is 0) ? 0x10000 : 0; ap += (sfx >> 16); - break; + break; case ALPHA_MASK_PACKED: alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; ap += (sfx >> 16); @@ -3275,6 +3339,7 @@ } } break; + default: } if (alpha !is 0x10000) { if (alpha is 0x0000) continue; @@ -3295,11 +3360,12 @@ case TYPE_INDEX_1_LSB: indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; break; + default: } // Perform alpha blending - final int rq = destReds[indexq] & 0xff; - final int gq = destGreens[indexq] & 0xff; - final int bq = destBlues[indexq] & 0xff; + int rq = destReds[indexq] & 0xff; + int gq = destGreens[indexq] & 0xff; + int bq = destBlues[indexq] & 0xff; r = rq + ((r - rq) * alpha >> 16); g = gq + ((g - gq) * alpha >> 16); b = bq + ((b - bq) * alpha >> 16); @@ -3335,7 +3401,7 @@ } if (ditherEnabled) { // Floyd-Steinberg error diffusion, cont'd... - final int dxm1 = dx - 1, dxp1 = dx + 1; + int dxm1 = dx - 1, dxp1 = dx + 1; int acc; rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; rerr[dx] += acc += lrerr + lrerr; @@ -3358,17 +3424,18 @@ else destData[dp >> 1] = cast(byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); break; case TYPE_INDEX_2: { - final int shift = 6 - (dp & 3) * 2; + int shift = 6 - (dp & 3) * 2; destData[dp >> 2] = cast(byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); - } break; + } break; case TYPE_INDEX_1_MSB: { - final int shift = 7 - (dp & 7); + int shift = 7 - (dp & 7); destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); } break; case TYPE_INDEX_1_LSB: { - final int shift = dp & 7; + int shift = dp & 7; destData[dp >> 3] = cast(byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); - } break; + } break; + default: } } } @@ -3403,7 +3470,8 @@ * Extracts a field from packed RGB data given a mask for that field. */ static byte getChannelField(int data, int mask) { - final int shift = getChannelShift(mask); + static_this(); + int shift = getChannelShift(mask); return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >>> shift]; } @@ -3428,16 +3496,16 @@ RGB fromRGB, RGB toRGB, int redBits, int greenBits, int blueBits) { /* Gradients are drawn as tiled bands */ - final int bandWidth, bandHeight, bitmapDepth; - final byte[] bitmapData; - final PaletteData paletteData; + int bandWidth, bandHeight, bitmapDepth; + byte[] bitmapData; + PaletteData paletteData; /* Select an algorithm depending on the depth of the screen */ if (redBits !is 0 && greenBits !is 0 && blueBits !is 0) { paletteData = new PaletteData(0x0000ff00, 0x00ff0000, 0xff000000); bitmapDepth = 32; if (redBits >= 8 && greenBits >= 8 && blueBits >= 8) { /* Precise color */ - final int steps; + int steps; if (vertical) { bandWidth = 1; bandHeight = height; @@ -3447,14 +3515,14 @@ bandHeight = 1; steps = bandWidth > 1 ? bandWidth - 1 : 1; } - final int bytesPerLine = bandWidth * 4; + int bytesPerLine = bandWidth * 4; bitmapData = new byte[bandHeight * bytesPerLine]; buildPreciseGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine); buildPreciseGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine); buildPreciseGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine); } else { /* Dithered color */ - final int steps; + int steps; if (vertical) { bandWidth = (width < 8) ? width : 8; bandHeight = height; @@ -3464,17 +3532,17 @@ bandHeight = (height < 8) ? height : 8; steps = bandWidth > 1 ? bandWidth - 1 : 1; } - final int bytesPerLine = bandWidth * 4; + int bytesPerLine = bandWidth * 4; bitmapData = new byte[bandHeight * bytesPerLine]; buildDitheredGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine, blueBits); buildDitheredGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine, greenBits); - buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits); + buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits); } } else { /* Dithered two tone */ - paletteData = new PaletteData(new RGB[] { fromRGB, toRGB }); + paletteData = new PaletteData([ fromRGB, toRGB ]); bitmapDepth = 8; - final int blendi; + int blendi; if (vertical) { bandWidth = (width < 8) ? width : 8; bandHeight = height; @@ -3484,7 +3552,7 @@ bandHeight = (height < 8) ? height : 8; blendi = (bandWidth > 1) ? 0x1040000 / (bandWidth - 1) + 1 : 1; } - final int bytesPerLine = (bandWidth + 3) & -4; + int bytesPerLine = (bandWidth + 3) & -4; bitmapData = new byte[bandHeight * bytesPerLine]; if (vertical) { for (int dy = 0, blend = 0, dp = 0; dy < bandHeight; @@ -3493,7 +3561,7 @@ bitmapData[dp + dx] = (blend + DITHER_MATRIX[dy & 7][dx]) < 0x1000000 ? cast(byte)0 : cast(byte)1; } - } + } } else { for (int dx = 0, blend = 0; dx < bandWidth; ++dx, blend += blendi) { for (int dy = 0, dptr = dx; dy < bandHeight; ++dy, dptr += bytesPerLine) { @@ -3506,14 +3574,14 @@ return new ImageData(bandWidth, bandHeight, bitmapDepth, paletteData, 4, bitmapData); } -/* +/* * Fill in gradated values for a color channel */ static final void buildPreciseGradientChannel(int from, int to, int steps, int bandWidth, int bandHeight, bool vertical, byte[] bitmapData, int dp, int bytesPerLine) { int val = from << 16; - final int inc = ((to << 16) - val) / steps + 1; + int inc = ((to << 16) - val) / steps + 1; if (vertical) { for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { bitmapData[dp] = cast(byte)(val >>> 16); @@ -3524,22 +3592,22 @@ bitmapData[dp] = cast(byte)(val >>> 16); val += inc; } - } + } } -/* +/* * Fill in dithered gradated values for a color channel */ static final void buildDitheredGradientChannel(int from, int to, int steps, int bandWidth, int bandHeight, bool vertical, byte[] bitmapData, int dp, int bytesPerLine, int bits) { - final int mask = 0xff00 >>> bits; + int mask = 0xff00 >>> bits; int val = from << 16; - final int inc = ((to << 16) - val) / steps + 1; + int inc = ((to << 16) - val) / steps + 1; if (vertical) { for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) { - final int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits; + int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits; int temp = val + thresh; if (temp > 0xffffff) bitmapData[dptr] = -1; else bitmapData[dptr] = cast(byte)((temp >>> 16) & mask); @@ -3549,7 +3617,7 @@ } else { for (int dx = 0; dx < bandWidth; ++dx, dp += 4) { for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) { - final int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits; + int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits; int temp = val + thresh; if (temp > 0xffffff) bitmapData[dptr] = -1; else bitmapData[dptr] = cast(byte)((temp >>> 16) & mask);