diff options
Diffstat (limited to 'bundles/org.eclipse.swt.opengl/common/org/eclipse/swt/opengl/ImageDataUtil.java')
-rw-r--r-- | bundles/org.eclipse.swt.opengl/common/org/eclipse/swt/opengl/ImageDataUtil.java | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/bundles/org.eclipse.swt.opengl/common/org/eclipse/swt/opengl/ImageDataUtil.java b/bundles/org.eclipse.swt.opengl/common/org/eclipse/swt/opengl/ImageDataUtil.java deleted file mode 100644 index d9002851c4..0000000000 --- a/bundles/org.eclipse.swt.opengl/common/org/eclipse/swt/opengl/ImageDataUtil.java +++ /dev/null @@ -1,524 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.opengl; - - -public class ImageDataUtil { - /** - * Alpha mode, values 0 - 255 specify global alpha level - */ - static final 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 - ALPHA_CHANNEL_SOURCE = -2, // Use alpha channel embedded in sourceData - ALPHA_MASK_UNPACKED = -3, // Use transparency mask formed by bytes in alphaData (non-zero is opaque) - ALPHA_MASK_PACKED = -4, // Use transparency mask formed by packed bits in alphaData - ALPHA_MASK_INDEX = -5, // Consider source palette indices transparent if in alphaData array - ALPHA_MASK_RGB = -6; // Consider source RGBs transparent if in RGB888 format alphaData array - - /** - * Data types (internal) - */ - private static final int - // direct / true color formats with arbitrary masks & shifts - TYPE_GENERIC_8 = 0, - TYPE_GENERIC_16_MSB = 1, - TYPE_GENERIC_16_LSB = 2, - TYPE_GENERIC_24 = 3, - TYPE_GENERIC_32_MSB = 4, - TYPE_GENERIC_32_LSB = 5, - // palette indexed color formats - TYPE_INDEX_8 = 6, - TYPE_INDEX_4 = 7, - TYPE_INDEX_2 = 8, - TYPE_INDEX_1_MSB = 9, - TYPE_INDEX_1_LSB = 10; - - /** - * Byte and bit order constants. - */ - static final int LSB_FIRST = 0; - static final int MSB_FIRST = 1; - - /** - * Blit operation bits to be OR'ed together to specify the desired operation. - */ - static final 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 - - /** - * 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 == 0) continue; - int inc = 0; - for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit; - for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8); - } - } - - /** - * Blits a direct palette image into a direct palette image. - * <p> - * Note: When the source and destination depth, order and masks - * are pairwise equal and the blitter operation is BLIT_SRC, - * 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 - * @param srcDepth the source depth: one of 8, 16, 24, 32 - * @param srcStride the source number of bytes per line - * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST; - * ignored if srcDepth is not 16 or 32 - * @param srcX the top-left x-coord of the source blit region - * @param srcY the top-left y-coord of the source blit region - * @param srcWidth the width of the source blit region - * @param srcHeight the height of the source blit region - * @param srcRedMask the source red channel mask - * @param srcGreenMask the source green channel mask - * @param srcBlueMask the source blue channel mask - * @param alphaMode the alpha blending or mask mode, may be - * an integer 0-255 for global alpha; ignored if BLIT_ALPHA - * not specified in the blitter operations - * (see ALPHA_MODE_xxx constants) - * @param alphaData the alpha blending or mask data, varies depending - * on the value of alphaMode and sometimes ignored - * @param alphaStride the alpha data number of bytes per line - * @param alphaX the top-left x-coord of the alpha blit region - * @param alphaY the top-left y-coord of the alpha blit region - * @param destData the destination byte array containing image data - * @param destDepth the destination depth: one of 8, 16, 24, 32 - * @param destStride the destination number of bytes per line - * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST; - * ignored if destDepth is not 16 or 32 - * @param destX the top-left x-coord of the destination blit region - * @param destY the top-left y-coord of the destination blit region - * @param destWidth the width of the destination blit region - * @param destHeight the height of the destination blit region - * @param destRedMask the destination red channel mask - * @param destGreenMask the destination green channel mask - * @param destBlueMask the destination blue channel mask - * @param flipX if true the resulting image is flipped along the vertical axis - * @param flipY if true the resulting image is flipped along the horizontal axis - */ - static void blit(int op, - byte[] srcData, int srcDepth, int srcStride, int srcOrder, - int srcX, int srcY, int srcWidth, int srcHeight, - int srcRedMask, int srcGreenMask, int srcBlueMask, - int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, - byte[] destData, int destDepth, int destStride, int destOrder, - int destX, int destY, int destWidth, int destHeight, - int destRedMask, int destGreenMask, int destBlueMask, - boolean flipX, boolean flipY) { - if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; - - // these should be supplied as params later - final int srcAlphaMask = 0, destAlphaMask = 0; - - /*** Prepare scaling data ***/ - final int dwm1 = destWidth - 1; - final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; - final int dhm1 = destHeight - 1; - final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; - - /*** Prepare source-related data ***/ - final int sbpp, stype; - switch (srcDepth) { - case 8: - sbpp = 1; - stype = TYPE_GENERIC_8; - break; - case 16: - sbpp = 2; - stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; - break; - case 24: - sbpp = 3; - stype = TYPE_GENERIC_24; - break; - case 32: - sbpp = 4; - stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; - break; - default: - //throw new IllegalArgumentException("Invalid source type"); - return; - } - int spr = srcY * srcStride + srcX * sbpp; - - /*** Prepare destination-related data ***/ - final int dbpp, dtype; - switch (destDepth) { - case 8: - dbpp = 1; - dtype = TYPE_GENERIC_8; - break; - case 16: - dbpp = 2; - dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; - break; - case 24: - dbpp = 3; - dtype = TYPE_GENERIC_24; - break; - case 32: - dbpp = 4; - dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; - break; - 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; - - /*** Prepare special processing data ***/ - int apr; - if ((op & BLIT_ALPHA) != 0) { - switch (alphaMode) { - case ALPHA_MASK_UNPACKED: - case ALPHA_CHANNEL_SEPARATE: - if (alphaData == null) alphaMode = 0x10000; - apr = alphaY * alphaStride + alphaX; - break; - case ALPHA_MASK_PACKED: - if (alphaData == null) alphaMode = 0x10000; - alphaStride <<= 3; - apr = alphaY * alphaStride + alphaX; - break; - case ALPHA_MASK_INDEX: - //throw new IllegalArgumentException("Invalid alpha type"); - return; - case ALPHA_MASK_RGB: - if (alphaData == null) alphaMode = 0x10000; - apr = 0; - break; - default: - alphaMode = (alphaMode << 16) / 255; // prescale - case ALPHA_CHANNEL_SOURCE: - apr = 0; - break; - } - } else { - alphaMode = 0x10000; - apr = 0; - } - - /*** Blit ***/ - int dp = dpr; - int sp = spr; - if ((alphaMode == 0x10000) && (stype == dtype) && - (srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) && - (srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) { - /*** Fast blit (straight copy) ***/ - switch (sbpp) { - case 1: - 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) { - destData[dp] = srcData[sp]; - sp += (sfx >>> 16); - } - } - 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) { - destData[dp] = srcData[sp]; - destData[dp + 1] = srcData[sp + 1]; - sp += (sfx >>> 16) * 2; - } - } - break; - case 3: - 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) { - destData[dp] = srcData[sp]; - destData[dp + 1] = srcData[sp + 1]; - destData[dp + 2] = srcData[sp + 2]; - sp += (sfx >>> 16) * 3; - } - } - break; - case 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) { - destData[dp] = srcData[sp]; - destData[dp + 1] = srcData[sp + 1]; - destData[dp + 2] = srcData[sp + 2]; - destData[dp + 3] = srcData[sp + 3]; - sp += (sfx >>> 16) * 4; - } - } - break; - } - 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)]; - - 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 ap = apr, alpha = alphaMode; - int r = 0, g = 0, b = 0, a = 0; - int rq = 0, gq = 0, bq = 0, aq = 0; - for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, - sp = spr += (sfy >>> 16) * srcStride, - ap = apr += (sfy >>> 16) * alphaStride, - sfy = (sfy & 0xffff) + sfyi, - dp = dpr += dpryi) { - for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, - dp += dprxi, - sfx = (sfx & 0xffff) + sfxi) { - /*** READ NEXT PIXEL ***/ - switch (stype) { - case TYPE_GENERIC_8: { - final int data = srcData[sp] & 0xff; - sp += (sfx >>> 16); - r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; - g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - case TYPE_GENERIC_16_MSB: { - final 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; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - case TYPE_GENERIC_16_LSB: { - final 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; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - case TYPE_GENERIC_24: { - final int data = (( ((srcData[sp] & 0xff) << 8) | - (srcData[sp + 1] & 0xff)) << 8) | - (srcData[sp + 2] & 0xff); - sp += (sfx >>> 16) * 3; - r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; - g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - case TYPE_GENERIC_32_MSB: { - final int data = (( (( ((srcData[sp] & 0xff) << 8) | - (srcData[sp + 1] & 0xff)) << 8) | - (srcData[sp + 2] & 0xff)) << 8) | - (srcData[sp + 3] & 0xff); - sp += (sfx >>> 16) * 4; - r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; - g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - case TYPE_GENERIC_32_LSB: { - final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | - (srcData[sp + 2] & 0xff)) << 8) | - (srcData[sp + 1] & 0xff)) << 8) | - (srcData[sp] & 0xff); - sp += (sfx >>> 16) * 4; - r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; - g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; - b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; - a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; - } break; - } - - /*** DO SPECIAL PROCESSING IF REQUIRED ***/ - switch (alphaMode) { - case ALPHA_CHANNEL_SEPARATE: - alpha = ((alphaData[ap] & 0xff) << 16) / 255; - ap += (sfx >> 16); - break; - case ALPHA_CHANNEL_SOURCE: - alpha = (a << 16) / 255; - break; - case ALPHA_MASK_UNPACKED: - alpha = (alphaData[ap] != 0) ? 0x10000 : 0; - ap += (sfx >> 16); - break; - case ALPHA_MASK_PACKED: - alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; - ap += (sfx >> 16); - break; - case ALPHA_MASK_RGB: - alpha = 0x10000; - for (int i = 0; i < alphaData.length; i += 3) { - if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) { - alpha = 0x0000; - break; - } - } - break; - } - if (alpha != 0x10000) { - if (alpha == 0x0000) continue; - switch (dtype) { - case TYPE_GENERIC_8: { - final 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); - 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); - 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) | - (destData[dp + 1] & 0xff)) << 8) | - (destData[dp + 2] & 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_32_MSB: { - final int data = (( (( ((destData[dp] & 0xff) << 8) | - (destData[dp + 1] & 0xff)) << 8) | - (destData[dp + 2] & 0xff)) << 8) | - (destData[dp + 3] & 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_32_LSB: { - final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | - (destData[dp + 2] & 0xff)) << 8) | - (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; - } - // Perform alpha blending - a = aq + ((a - aq) * alpha >> 16); - r = rq + ((r - rq) * alpha >> 16); - g = gq + ((g - gq) * alpha >> 16); - b = bq + ((b - bq) * alpha >> 16); - } - - /*** WRITE NEXT PIXEL ***/ - final int data = - (r >>> destRedPreShift << destRedShift) | - (g >>> destGreenPreShift << destGreenShift) | - (b >>> destBluePreShift << destBlueShift) | - (a >>> destAlphaPreShift << destAlphaShift); - switch (dtype) { - case TYPE_GENERIC_8: { - destData[dp] = (byte) data; - } break; - case TYPE_GENERIC_16_MSB: { - destData[dp] = (byte) (data >>> 8); - destData[dp + 1] = (byte) (data & 0xff); - } break; - case TYPE_GENERIC_16_LSB: { - destData[dp] = (byte) (data & 0xff); - destData[dp + 1] = (byte) (data >>> 8); - } break; - case TYPE_GENERIC_24: { - destData[dp] = (byte) (data >>> 16); - destData[dp + 1] = (byte) (data >>> 8); - destData[dp + 2] = (byte) (data & 0xff); - } break; - case TYPE_GENERIC_32_MSB: { - destData[dp] = (byte) (data >>> 24); - destData[dp + 1] = (byte) (data >>> 16); - destData[dp + 2] = (byte) (data >>> 8); - destData[dp + 3] = (byte) (data & 0xff); - } break; - case TYPE_GENERIC_32_LSB: { - destData[dp] = (byte) (data & 0xff); - destData[dp + 1] = (byte) (data >>> 8); - destData[dp + 2] = (byte) (data >>> 16); - destData[dp + 3] = (byte) (data >>> 24); - } break; - } - } - } - } - - /** - * Computes the required channel shift from a mask. - */ - static int getChannelShift(int mask) { - if (mask == 0) return 0; - int i; - for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) { - mask >>>= 1; - } - return i; - } - - /** - * Computes the required channel width (depth) from a mask. - */ - static int getChannelWidth(int mask, int shift) { - if (mask == 0) return 0; - int i; - mask >>>= shift; - for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) { - mask >>>= 1; - } - return i - shift; - } -} |