001: /*******************************************************************************
002: * Copyright (c) 2000, 2003 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.opengl;
011:
012: import org.eclipse.swt.graphics.ImageData;
013: import org.eclipse.swt.graphics.PaletteData;
014:
015: public class ImageDataUtil {
016: /**
017: * Alpha mode, values 0 - 255 specify global alpha level
018: */
019: static final int ALPHA_OPAQUE = 255, // Fully opaque (ignores any alpha data)
020: ALPHA_TRANSPARENT = 0, // Fully transparent (ignores any alpha data)
021: ALPHA_CHANNEL_SEPARATE = -1, // Use alpha channel from separate alphaData
022: ALPHA_CHANNEL_SOURCE = -2, // Use alpha channel embedded in sourceData
023: ALPHA_MASK_UNPACKED = -3, // Use transparency mask formed by bytes in alphaData (non-zero is opaque)
024: ALPHA_MASK_PACKED = -4, // Use transparency mask formed by packed bits in alphaData
025: ALPHA_MASK_INDEX = -5, // Consider source palette indices transparent if in alphaData array
026: ALPHA_MASK_RGB = -6; // Consider source RGBs transparent if in RGB888 format alphaData array
027:
028: /**
029: * Data types (internal)
030: */
031: private static final int
032: // direct / true color formats with arbitrary masks & shifts
033: TYPE_GENERIC_8 = 0,
034: TYPE_GENERIC_16_MSB = 1,
035: TYPE_GENERIC_16_LSB = 2,
036: TYPE_GENERIC_24 = 3,
037: TYPE_GENERIC_32_MSB = 4,
038: TYPE_GENERIC_32_LSB = 5,
039: // palette indexed color formats
040: TYPE_INDEX_8 = 6, TYPE_INDEX_4 = 7,
041: TYPE_INDEX_2 = 8,
042: TYPE_INDEX_1_MSB = 9, TYPE_INDEX_1_LSB = 10;
043:
044: /**
045: * Byte and bit order constants.
046: */
047: static final int LSB_FIRST = 0;
048: static final int MSB_FIRST = 1;
049:
050: /**
051: * Blit operation bits to be OR'ed together to specify the desired operation.
052: */
053: static final int BLIT_SRC = 1, // copy source directly, else applies logic operations
054: BLIT_ALPHA = 2, // enable alpha blending
055: BLIT_DITHER = 4; // enable dithering in low color modes
056:
057: /**
058: * Arbitrary channel width data to 8-bit conversion table.
059: */
060: static final byte[][] ANY_TO_EIGHT = new byte[9][];
061: static {
062: for (int b = 0; b < 9; ++b) {
063: byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b];
064: if (b == 0)
065: continue;
066: int inc = 0;
067: for (int bit = 0x10000; (bit >>= b) != 0;)
068: inc |= bit;
069: for (int v = 0, p = 0; v < 0x10000; v += inc)
070: data[p++] = (byte) (v >> 8);
071: }
072: }
073:
074: /**
075: * Blits a direct palette image into a direct palette image.
076: * <p>
077: * Note: When the source and destination depth, order and masks
078: * are pairwise equal and the blitter operation is BLIT_SRC,
079: * the masks are ignored. Hence when not changing the image
080: * data format, 0 may be specified for the masks.
081: * </p>
082: *
083: * @param op the blitter operation: a combination of BLIT_xxx flags
084: * (see BLIT_xxx constants)
085: * @param srcData the source byte array containing image data
086: * @param srcDepth the source depth: one of 8, 16, 24, 32
087: * @param srcStride the source number of bytes per line
088: * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
089: * ignored if srcDepth is not 16 or 32
090: * @param srcX the top-left x-coord of the source blit region
091: * @param srcY the top-left y-coord of the source blit region
092: * @param srcWidth the width of the source blit region
093: * @param srcHeight the height of the source blit region
094: * @param srcRedMask the source red channel mask
095: * @param srcGreenMask the source green channel mask
096: * @param srcBlueMask the source blue channel mask
097: * @param alphaMode the alpha blending or mask mode, may be
098: * an integer 0-255 for global alpha; ignored if BLIT_ALPHA
099: * not specified in the blitter operations
100: * (see ALPHA_MODE_xxx constants)
101: * @param alphaData the alpha blending or mask data, varies depending
102: * on the value of alphaMode and sometimes ignored
103: * @param alphaStride the alpha data number of bytes per line
104: * @param alphaX the top-left x-coord of the alpha blit region
105: * @param alphaY the top-left y-coord of the alpha blit region
106: * @param destData the destination byte array containing image data
107: * @param destDepth the destination depth: one of 8, 16, 24, 32
108: * @param destStride the destination number of bytes per line
109: * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
110: * ignored if destDepth is not 16 or 32
111: * @param destX the top-left x-coord of the destination blit region
112: * @param destY the top-left y-coord of the destination blit region
113: * @param destWidth the width of the destination blit region
114: * @param destHeight the height of the destination blit region
115: * @param destRedMask the destination red channel mask
116: * @param destGreenMask the destination green channel mask
117: * @param destBlueMask the destination blue channel mask
118: * @param flipX if true the resulting image is flipped along the vertical axis
119: * @param flipY if true the resulting image is flipped along the horizontal axis
120: */
121: static void blit(int op, byte[] srcData, int srcDepth,
122: int srcStride, int srcOrder, int srcX, int srcY,
123: int srcWidth, int srcHeight, int srcRedMask,
124: int srcGreenMask, int srcBlueMask, int alphaMode,
125: byte[] alphaData, int alphaStride, int alphaX, int alphaY,
126: byte[] destData, int destDepth, int destStride,
127: int destOrder, int destX, int destY, int destWidth,
128: int destHeight, int destRedMask, int destGreenMask,
129: int destBlueMask, boolean flipX, boolean flipY) {
130: if ((destWidth <= 0) || (destHeight <= 0)
131: || (alphaMode == ALPHA_TRANSPARENT))
132: return;
133:
134: // these should be supplied as params later
135: final int srcAlphaMask = 0, destAlphaMask = 0;
136:
137: /*** Prepare scaling data ***/
138: final int dwm1 = destWidth - 1;
139: final int sfxi = (dwm1 != 0) ? (int) ((((long) srcWidth << 16) - 1) / dwm1)
140: : 0;
141: final int dhm1 = destHeight - 1;
142: final int sfyi = (dhm1 != 0) ? (int) ((((long) srcHeight << 16) - 1) / dhm1)
143: : 0;
144:
145: /*** Prepare source-related data ***/
146: final int sbpp, stype;
147: switch (srcDepth) {
148: case 8:
149: sbpp = 1;
150: stype = TYPE_GENERIC_8;
151: break;
152: case 16:
153: sbpp = 2;
154: stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB
155: : TYPE_GENERIC_16_LSB;
156: break;
157: case 24:
158: sbpp = 3;
159: stype = TYPE_GENERIC_24;
160: break;
161: case 32:
162: sbpp = 4;
163: stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB
164: : TYPE_GENERIC_32_LSB;
165: break;
166: default:
167: //throw new IllegalArgumentException("Invalid source type");
168: return;
169: }
170: int spr = srcY * srcStride + srcX * sbpp;
171:
172: /*** Prepare destination-related data ***/
173: final int dbpp, dtype;
174: switch (destDepth) {
175: case 8:
176: dbpp = 1;
177: dtype = TYPE_GENERIC_8;
178: break;
179: case 16:
180: dbpp = 2;
181: dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB
182: : TYPE_GENERIC_16_LSB;
183: break;
184: case 24:
185: dbpp = 3;
186: dtype = TYPE_GENERIC_24;
187: break;
188: case 32:
189: dbpp = 4;
190: dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB
191: : TYPE_GENERIC_32_LSB;
192: break;
193: default:
194: //throw new IllegalArgumentException("Invalid destination type");
195: return;
196: }
197: int dpr = ((flipY) ? destY + dhm1 : destY) * destStride
198: + ((flipX) ? destX + dwm1 : destX) * dbpp;
199: final int dprxi = (flipX) ? -dbpp : dbpp;
200: final int dpryi = (flipY) ? -destStride : destStride;
201:
202: /*** Prepare special processing data ***/
203: int apr;
204: if ((op & BLIT_ALPHA) != 0) {
205: switch (alphaMode) {
206: case ALPHA_MASK_UNPACKED:
207: case ALPHA_CHANNEL_SEPARATE:
208: if (alphaData == null)
209: alphaMode = 0x10000;
210: apr = alphaY * alphaStride + alphaX;
211: break;
212: case ALPHA_MASK_PACKED:
213: if (alphaData == null)
214: alphaMode = 0x10000;
215: alphaStride <<= 3;
216: apr = alphaY * alphaStride + alphaX;
217: break;
218: case ALPHA_MASK_INDEX:
219: //throw new IllegalArgumentException("Invalid alpha type");
220: return;
221: case ALPHA_MASK_RGB:
222: if (alphaData == null)
223: alphaMode = 0x10000;
224: apr = 0;
225: break;
226: default:
227: alphaMode = (alphaMode << 16) / 255; // prescale
228: case ALPHA_CHANNEL_SOURCE:
229: apr = 0;
230: break;
231: }
232: } else {
233: alphaMode = 0x10000;
234: apr = 0;
235: }
236:
237: /*** Blit ***/
238: int dp = dpr;
239: int sp = spr;
240: if ((alphaMode == 0x10000) && (stype == dtype)
241: && (srcRedMask == destRedMask)
242: && (srcGreenMask == destGreenMask)
243: && (srcBlueMask == destBlueMask)
244: && (srcAlphaMask == destAlphaMask)) {
245: /*** Fast blit (straight copy) ***/
246: switch (sbpp) {
247: case 1:
248: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16)
249: * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
250: for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff)
251: + sfxi) {
252: destData[dp] = srcData[sp];
253: sp += (sfx >>> 16);
254: }
255: }
256: break;
257: case 2:
258: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16)
259: * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
260: for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff)
261: + sfxi) {
262: destData[dp] = srcData[sp];
263: destData[dp + 1] = srcData[sp + 1];
264: sp += (sfx >>> 16) * 2;
265: }
266: }
267: break;
268: case 3:
269: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16)
270: * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
271: for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff)
272: + sfxi) {
273: destData[dp] = srcData[sp];
274: destData[dp + 1] = srcData[sp + 1];
275: destData[dp + 2] = srcData[sp + 2];
276: sp += (sfx >>> 16) * 3;
277: }
278: }
279: break;
280: case 4:
281: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16)
282: * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
283: for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff)
284: + sfxi) {
285: destData[dp] = srcData[sp];
286: destData[dp + 1] = srcData[sp + 1];
287: destData[dp + 2] = srcData[sp + 2];
288: destData[dp + 3] = srcData[sp + 3];
289: sp += (sfx >>> 16) * 4;
290: }
291: }
292: break;
293: }
294: return;
295: }
296: /*** Comprehensive blit (apply transformations) ***/
297: final int srcRedShift = getChannelShift(srcRedMask);
298: final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask,
299: srcRedShift)];
300: final int srcGreenShift = getChannelShift(srcGreenMask);
301: final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(
302: srcGreenMask, srcGreenShift)];
303: final int srcBlueShift = getChannelShift(srcBlueMask);
304: final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(
305: srcBlueMask, srcBlueShift)];
306: final int srcAlphaShift = getChannelShift(srcAlphaMask);
307: final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(
308: srcAlphaMask, srcAlphaShift)];
309:
310: final int destRedShift = getChannelShift(destRedMask);
311: final int destRedWidth = getChannelWidth(destRedMask,
312: destRedShift);
313: final byte[] destReds = ANY_TO_EIGHT[destRedWidth];
314: final int destRedPreShift = 8 - destRedWidth;
315: final int destGreenShift = getChannelShift(destGreenMask);
316: final int destGreenWidth = getChannelWidth(destGreenMask,
317: destGreenShift);
318: final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
319: final int destGreenPreShift = 8 - destGreenWidth;
320: final int destBlueShift = getChannelShift(destBlueMask);
321: final int destBlueWidth = getChannelWidth(destBlueMask,
322: destBlueShift);
323: final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
324: final int destBluePreShift = 8 - destBlueWidth;
325: final int destAlphaShift = getChannelShift(destAlphaMask);
326: final int destAlphaWidth = getChannelWidth(destAlphaMask,
327: destAlphaShift);
328: final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
329: final int destAlphaPreShift = 8 - destAlphaWidth;
330:
331: int ap = apr, alpha = alphaMode;
332: int r = 0, g = 0, b = 0, a = 0;
333: int rq = 0, gq = 0, bq = 0, aq = 0;
334: for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16)
335: * srcStride, ap = apr += (sfy >>> 16) * alphaStride, sfy = (sfy & 0xffff)
336: + sfyi, dp = dpr += dpryi) {
337: for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff)
338: + sfxi) {
339: /*** READ NEXT PIXEL ***/
340: switch (stype) {
341: case TYPE_GENERIC_8: {
342: final int data = srcData[sp] & 0xff;
343: sp += (sfx >>> 16);
344: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
345: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
346: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
347: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
348: }
349: break;
350: case TYPE_GENERIC_16_MSB: {
351: final int data = ((srcData[sp] & 0xff) << 8)
352: | (srcData[sp + 1] & 0xff);
353: sp += (sfx >>> 16) * 2;
354: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
355: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
356: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
357: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
358: }
359: break;
360: case TYPE_GENERIC_16_LSB: {
361: final int data = ((srcData[sp + 1] & 0xff) << 8)
362: | (srcData[sp] & 0xff);
363: sp += (sfx >>> 16) * 2;
364: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
365: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
366: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
367: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
368: }
369: break;
370: case TYPE_GENERIC_24: {
371: final int data = ((((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8)
372: | (srcData[sp + 2] & 0xff);
373: sp += (sfx >>> 16) * 3;
374: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
375: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
376: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
377: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
378: }
379: break;
380: case TYPE_GENERIC_32_MSB: {
381: final int data = ((((((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff)) << 8) | (srcData[sp + 2] & 0xff)) << 8)
382: | (srcData[sp + 3] & 0xff);
383: sp += (sfx >>> 16) * 4;
384: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
385: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
386: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
387: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
388: }
389: break;
390: case TYPE_GENERIC_32_LSB: {
391: final int data = ((((((srcData[sp + 3] & 0xff) << 8) | (srcData[sp + 2] & 0xff)) << 8) | (srcData[sp + 1] & 0xff)) << 8)
392: | (srcData[sp] & 0xff);
393: sp += (sfx >>> 16) * 4;
394: r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
395: g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
396: b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
397: a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
398: }
399: break;
400: }
401:
402: /*** DO SPECIAL PROCESSING IF REQUIRED ***/
403: switch (alphaMode) {
404: case ALPHA_CHANNEL_SEPARATE:
405: alpha = ((alphaData[ap] & 0xff) << 16) / 255;
406: ap += (sfx >> 16);
407: break;
408: case ALPHA_CHANNEL_SOURCE:
409: alpha = (a << 16) / 255;
410: break;
411: case ALPHA_MASK_UNPACKED:
412: alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
413: ap += (sfx >> 16);
414: break;
415: case ALPHA_MASK_PACKED:
416: alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
417: ap += (sfx >> 16);
418: break;
419: case ALPHA_MASK_RGB:
420: alpha = 0x10000;
421: for (int i = 0; i < alphaData.length; i += 3) {
422: if ((r == alphaData[i])
423: && (g == alphaData[i + 1])
424: && (b == alphaData[i + 2])) {
425: alpha = 0x0000;
426: break;
427: }
428: }
429: break;
430: }
431: if (alpha != 0x10000) {
432: if (alpha == 0x0000)
433: continue;
434: switch (dtype) {
435: case TYPE_GENERIC_8: {
436: final int data = destData[dp] & 0xff;
437: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
438: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
439: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
440: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
441: }
442: break;
443: case TYPE_GENERIC_16_MSB: {
444: final int data = ((destData[dp] & 0xff) << 8)
445: | (destData[dp + 1] & 0xff);
446: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
447: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
448: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
449: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
450: }
451: break;
452: case TYPE_GENERIC_16_LSB: {
453: final int data = ((destData[dp + 1] & 0xff) << 8)
454: | (destData[dp] & 0xff);
455: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
456: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
457: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
458: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
459: }
460: break;
461: case TYPE_GENERIC_24: {
462: final int data = ((((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8)
463: | (destData[dp + 2] & 0xff);
464: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
465: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
466: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
467: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
468: }
469: break;
470: case TYPE_GENERIC_32_MSB: {
471: final int data = ((((((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff)) << 8) | (destData[dp + 2] & 0xff)) << 8)
472: | (destData[dp + 3] & 0xff);
473: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
474: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
475: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
476: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
477: }
478: break;
479: case TYPE_GENERIC_32_LSB: {
480: final int data = ((((((destData[dp + 3] & 0xff) << 8) | (destData[dp + 2] & 0xff)) << 8) | (destData[dp + 1] & 0xff)) << 8)
481: | (destData[dp] & 0xff);
482: rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
483: gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
484: bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
485: aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
486: }
487: break;
488: }
489: // Perform alpha blending
490: a = aq + ((a - aq) * alpha >> 16);
491: r = rq + ((r - rq) * alpha >> 16);
492: g = gq + ((g - gq) * alpha >> 16);
493: b = bq + ((b - bq) * alpha >> 16);
494: }
495:
496: /*** WRITE NEXT PIXEL ***/
497: final int data = (r >>> destRedPreShift << destRedShift)
498: | (g >>> destGreenPreShift << destGreenShift)
499: | (b >>> destBluePreShift << destBlueShift)
500: | (a >>> destAlphaPreShift << destAlphaShift);
501: switch (dtype) {
502: case TYPE_GENERIC_8: {
503: destData[dp] = (byte) data;
504: }
505: break;
506: case TYPE_GENERIC_16_MSB: {
507: destData[dp] = (byte) (data >>> 8);
508: destData[dp + 1] = (byte) (data & 0xff);
509: }
510: break;
511: case TYPE_GENERIC_16_LSB: {
512: destData[dp] = (byte) (data & 0xff);
513: destData[dp + 1] = (byte) (data >>> 8);
514: }
515: break;
516: case TYPE_GENERIC_24: {
517: destData[dp] = (byte) (data >>> 16);
518: destData[dp + 1] = (byte) (data >>> 8);
519: destData[dp + 2] = (byte) (data & 0xff);
520: }
521: break;
522: case TYPE_GENERIC_32_MSB: {
523: destData[dp] = (byte) (data >>> 24);
524: destData[dp + 1] = (byte) (data >>> 16);
525: destData[dp + 2] = (byte) (data >>> 8);
526: destData[dp + 3] = (byte) (data & 0xff);
527: }
528: break;
529: case TYPE_GENERIC_32_LSB: {
530: destData[dp] = (byte) (data & 0xff);
531: destData[dp + 1] = (byte) (data >>> 8);
532: destData[dp + 2] = (byte) (data >>> 16);
533: destData[dp + 3] = (byte) (data >>> 24);
534: }
535: break;
536: }
537: }
538: }
539: }
540:
541: /**
542: * Computes the required channel shift from a mask.
543: */
544: static int getChannelShift(int mask) {
545: if (mask == 0)
546: return 0;
547: int i;
548: for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) {
549: mask >>>= 1;
550: }
551: return i;
552: }
553:
554: /**
555: * Computes the required channel width (depth) from a mask.
556: */
557: static int getChannelWidth(int mask, int shift) {
558: if (mask == 0)
559: return 0;
560: int i;
561: mask >>>= shift;
562: for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) {
563: mask >>>= 1;
564: }
565: return i - shift;
566: }
567:
568: public static ImageData convertImageData(ImageData source) {
569: PaletteData palette = new PaletteData(0xff0000, 0xff00, 0xff);
570: ImageData newSource = new ImageData(source.width,
571: source.height, 24, palette);
572:
573: ImageDataUtil.blit(1, source.data, source.depth,
574: source.bytesPerLine, (source.depth != 16) ? MSB_FIRST
575: : LSB_FIRST, 0, 0, source.width, source.height,
576: source.palette.redMask, source.palette.greenMask,
577: source.palette.blueMask, 255, null, 0, 0, 0,
578: newSource.data, newSource.depth,
579: newSource.bytesPerLine,
580: (newSource.depth != 16) ? MSB_FIRST : LSB_FIRST, 0, 0,
581: newSource.width, newSource.height,
582: newSource.palette.redMask, newSource.palette.greenMask,
583: newSource.palette.blueMask, false, true);
584:
585: return newSource;
586: }
587: }
|