Source Code Cross Referenced for ColorCube.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » javax » media » jai » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » javax.media.jai 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: ColorCube.java,v $
003:         *
004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * Use is subject to license terms.
007:         *
008:         * $Revision: 1.1 $
009:         * $Date: 2005/02/11 04:57:06 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.image.DataBuffer;
015:        import javax.media.jai.LookupTableJAI;
016:
017:        /**
018:         * A subclass of <code>LookupTableJAI</code> which represents a lookup
019:         * table which is a color cube.  A color cube provides a fixed,
020:         * invertible mapping between table indices and sample values.
021:         * This allows the <code>findNearestEntry</code> method to be implemented
022:         * more efficiently than in the general case.
023:         *
024:         * <p> All constructors are protected. The correct way to create a
025:         * <code>ColorCube</code> is to use one of the static
026:         * <code>create</code> methods defined in this class.
027:         *
028:         * @see javax.media.jai.LookupTableJAI
029:         *
030:         */
031:        public class ColorCube extends LookupTableJAI {
032:            /**
033:             * A <code>ColorCube</code> for dithering RGB byte data into 216 colors.
034:             * The offset of this <code>ColorCube</code> is 38.
035:             */
036:            public static final ColorCube BYTE_496 = ColorCube.createColorCube(
037:                    DataBuffer.TYPE_BYTE, 38, new int[] { 4, 9, 6 });
038:
039:            /**
040:             * A <code>ColorCube</code> for dithering YCC byte data into 200 colors.
041:             * The offset of this <code>ColorCube</code> is 54.
042:             */
043:            public static final ColorCube BYTE_855 = ColorCube.createColorCube(
044:                    DataBuffer.TYPE_BYTE, 54, new int[] { 8, 5, 5 });
045:
046:            /** The signed array of sizes used to create the <code>ColorCube</code>. */
047:            private int[] dimension;
048:
049:            /**
050:             * An array of positive values each of whose elements is one less than the
051:             * absolute value of the corresponding element of the dimension array.
052:             */
053:            private int[] dimsLessOne;
054:
055:            /**
056:             * An array of multipliers.
057:             *
058:             * <p> The magnitudes of the elements of the multiplier array are
059:             * defined as <code>multipliers[0] = 1</code> and
060:             * <code>multipliers[i] =
061:             * multipliers[i-1]*Math.abs(dimension[i-1])</code> where <code>i
062:             * > 0</code>. The elements are subsequently assigned the same
063:             * sign (positive or negative) as the corresponding elements of
064:             * the dimension array.
065:             */
066:            private int[] multipliers;
067:
068:            /**
069:             * An offset into the lookup table, accounting for negative dimensions.
070:             */
071:            private int adjustedOffset;
072:
073:            /**
074:             * The data type cached to accelerate findNearestEntry().
075:             */
076:            private int dataType;
077:
078:            /**
079:             * The number of bands cached to accelerate findNearestEntry().
080:             */
081:            private int numBands;
082:
083:            /**
084:             * Returns a multi-banded <code>ColorCube</code> of a specified data type.
085:             *
086:             * @param dataType The data type of the <code>ColorCube</code>,
087:             *        one of <code>DataBuffer.TYPE_BYTE</code>,
088:             *        <code>TYPE_SHORT</code>,
089:             *        <code>TYPE_USHORT</code>,
090:             *        <code>TYPE_INT</code>,
091:             *        <code>TYPE_FLOAT</code>,
092:             *        or <code>TYPE_DOUBLE</code>.
093:             * @param offset The common offset for all bands.
094:             * @param dimension The signed dimension of each band.
095:             *
096:             * @throws RuntimeExceptions for unsupported data types
097:             * @return An appropriate <code>ColorCube</code>.
098:             */
099:            public static ColorCube createColorCube(int dataType, int offset,
100:                    int dimension[]) {
101:                ColorCube colorCube;
102:
103:                switch (dataType) {
104:                case DataBuffer.TYPE_BYTE:
105:                    colorCube = createColorCubeByte(offset, dimension);
106:                    break;
107:                case DataBuffer.TYPE_SHORT:
108:                    colorCube = createColorCubeShort(offset, dimension);
109:                    break;
110:                case DataBuffer.TYPE_USHORT:
111:                    colorCube = createColorCubeUShort(offset, dimension);
112:                    break;
113:                case DataBuffer.TYPE_INT:
114:                    colorCube = createColorCubeInt(offset, dimension);
115:                    break;
116:                case DataBuffer.TYPE_FLOAT:
117:                    colorCube = createColorCubeFloat(offset, dimension);
118:                    break;
119:                case DataBuffer.TYPE_DOUBLE:
120:                    colorCube = createColorCubeDouble(offset, dimension);
121:                    break;
122:                default:
123:                    throw new RuntimeException(JaiI18N.getString("ColorCube0"));
124:                }
125:
126:                return colorCube;
127:            }
128:
129:            /**
130:             * Returns a multi-banded <code>ColorCube</code> of a specified
131:             * data type with zero offset for all bands.
132:             *
133:             * @param dataType The data type of the <code>ColorCube</code>.
134:             * @param dimension The signed dimension of each band.
135:             *
136:             * @throws IllegalArgumentException if dimension is null.
137:             * @return An appropriate <code>ColorCube</code>.
138:             */
139:            public static ColorCube createColorCube(int dataType,
140:                    int dimension[]) {
141:
142:                if (dimension == null) {
143:                    throw new IllegalArgumentException(JaiI18N
144:                            .getString("Generic0"));
145:                }
146:
147:                return createColorCube(dataType, 0, dimension);
148:            }
149:
150:            /**
151:             * Returns a multi-banded byte <code>ColorCube</code> with an index
152:             * offset common to all bands.
153:             *
154:             * @param offset The common offset for all bands.
155:             * @param dimension An array of signed sizes of each side of the color
156:             * cube. The color ramp in each dimension will be increasing or decreasing
157:             * according to whether the sign of the corresponding element of the
158:             * <code>dimension</code> array is positive or negative, respectively.
159:             *
160:             * @return A multi-banded byte <code>ColorCube</code> with offset.
161:             */
162:            private static ColorCube createColorCubeByte(int offset,
163:                    int dimension[]) {
164:                ColorCube colorCube = new ColorCube(createDataArrayByte(offset,
165:                        dimension), offset);
166:                colorCube.initFields(offset, dimension);
167:                return colorCube;
168:            }
169:
170:            /**
171:             * Returns a multi-banded short <code>ColorCube</code> with an index
172:             * offset common to all bands.
173:             *
174:             * @param offset The common offset for all bands.
175:             * @param dimension An array of signed sizes of each side of the color
176:             * cube. The color ramp in each dimension will be increasing or decreasing
177:             * according to whether the sign of the corresponding element of the
178:             * <code>dimension</code> array is positive or negative, respectively.
179:             *
180:             * @return A multi-banded short <code>ColorCube</code> with offset.
181:             */
182:            private static ColorCube createColorCubeShort(int offset,
183:                    int dimension[]) {
184:                ColorCube colorCube = new ColorCube(createDataArrayShort(
185:                        offset, dimension), offset, false);
186:                colorCube.initFields(offset, dimension);
187:                return colorCube;
188:            }
189:
190:            /**
191:             * Returns a multi-banded unsigned short <code>ColorCube</code> with an
192:             * index offset common to all bands.
193:             *
194:             * @param offset The common offset for all bands.
195:             * @param dimension An array of signed sizes of each side of the color
196:             * cube. The color ramp in each dimension will be increasing or decreasing
197:             * according to whether the sign of the corresponding element of the
198:             * <code>dimension</code> array is positive or negative, respectively.
199:             *
200:             * @return A multi-banded unsigned short <code>ColorCube</code> with
201:             * offset.
202:             */
203:            private static ColorCube createColorCubeUShort(int offset,
204:                    int dimension[]) {
205:                ColorCube colorCube = new ColorCube(createDataArrayUShort(
206:                        offset, dimension), offset, true);
207:                colorCube.initFields(offset, dimension);
208:                return colorCube;
209:            }
210:
211:            /**
212:             * Returns a multi-banded int <code>ColorCube</code> with an index
213:             * offset common to all bands.
214:             *
215:             * @param offset The common offset for all bands.
216:             * @param dimension An array of signed sizes of each side of the color
217:             * cube. The color ramp in each dimension will be increasing or decreasing
218:             * according to whether the sign of the corresponding element of the
219:             * <code>dimension</code> array is positive or negative, respectively.
220:             *
221:             * @return A multi-banded int <code>ColorCube</code> with offset.
222:             */
223:            private static ColorCube createColorCubeInt(int offset,
224:                    int dimension[]) {
225:                ColorCube colorCube = new ColorCube(createDataArrayInt(offset,
226:                        dimension), offset);
227:                colorCube.initFields(offset, dimension);
228:                return colorCube;
229:            }
230:
231:            /**
232:             * Returns a multi-banded float <code>ColorCube</code> with an index
233:             * offset common to all bands.
234:             *
235:             * @param offset The common offset for all bands.
236:             * @param dimension An array of signed sizes of each side of the color
237:             * cube. The color ramp in each dimension will be increasing or decreasing
238:             * according to whether the sign of the corresponding element of the
239:             * <code>dimension</code> array is positive or negative, respectively.
240:             *
241:             * @return A multi-banded float <code>ColorCube</code> with offset.
242:             */
243:            private static ColorCube createColorCubeFloat(int offset,
244:                    int dimension[]) {
245:                ColorCube colorCube = new ColorCube(createDataArrayFloat(
246:                        offset, dimension), offset);
247:                colorCube.initFields(offset, dimension);
248:                return colorCube;
249:            }
250:
251:            /**
252:             * Returns a multi-banded double <code>ColorCube</code> with an index
253:             * offset common to all bands.
254:             *
255:             * @param offset The common offset for all bands.
256:             * @param dimension An array of signed sizes of each side of the color
257:             * cube. The color ramp in each dimension will be increasing or decreasing
258:             * according to whether the sign of the corresponding element of the
259:             * <code>dimension</code> array is positive or negative, respectively.
260:             *
261:             * @return A multi-banded double <code>ColorCube</code>.
262:             */
263:            private static ColorCube createColorCubeDouble(int offset,
264:                    int dimension[]) {
265:                ColorCube colorCube = new ColorCube(createDataArrayDouble(
266:                        offset, dimension), offset);
267:                colorCube.initFields(offset, dimension);
268:                return colorCube;
269:            }
270:
271:            /**
272:             * Constructs a two-dimensional array of the requested data type which
273:             * represents the contents of a color cube.
274:             *
275:             * @param dataType The data type as defined by the static TYPE fields of
276:             * <code>DataBuffer</code>, e.g., <code>DataBuffer.TYPE_BYTE</code>.
277:             * @param offset The initial offset into the data array.
278:             * @param dimension An array of signed sizes of each side of the color
279:             * cube. The color ramp in each dimension will be increasing or decreasing
280:             * according to whether the sign of the corresponding element of the
281:             * <code>dimension</code> array is positive or negative, respectively.
282:             *
283:             * @return A two-dimensional array of the requested data type laid
284:             * out in color cube format.
285:             * 
286:             * @throws RuntimeException for data types other than
287:             *     DataBuffer.TYPE_BYTE DataBuffer.TYPE_USHORT
288:             *     DataBuffer.TYPE_SHORT DataBuffer.TYPE_INT
289:             *     DataBuffer.TYPE_FLOAT DataBuffer.TYPE_DOUBLE
290:             * @see java.awt.image.DataBuffer
291:             */
292:            private static Object createDataArray(int dataType, int offset,
293:                    int dimension[]) {
294:                // Make sure that the dimension array has non-zero length.
295:                int nbands = dimension.length;
296:                if (nbands == 0) {
297:                    throw new RuntimeException(JaiI18N.getString("ColorCube1"));
298:                }
299:
300:                // Ascertain that all dimension are non-zero.
301:                for (int band = 0; band < nbands; band++) {
302:                    if (dimension[band] == 0) {
303:                        throw new RuntimeException(JaiI18N
304:                                .getString("ColorCube2"));
305:                    }
306:                }
307:
308:                // Copy the dimension into an array of dimension magnitudes.
309:                int[] dimensionAbs = new int[nbands];
310:                for (int band = 0; band < nbands; band++) {
311:                    dimensionAbs[band] = Math.abs(dimension[band]);
312:                }
313:
314:                // Check that the color cube is not too large for the machine.
315:                double floatSize = dimensionAbs[0];
316:                for (int band = 1; band < nbands; band++) {
317:                    floatSize *= (double) dimensionAbs[band];
318:                }
319:                if (floatSize > (double) Integer.MAX_VALUE) {
320:                    //
321:                    //  Color cube is too large for 32 bit addressability
322:                    //
323:                    throw new RuntimeException(JaiI18N.getString("ColorCube3"));
324:                }
325:                int size = (int) floatSize;
326:
327:                // Initialize the data array and extrema for this data type.
328:                double dataMin;
329:                double dataMax;
330:                Object dataArray;
331:                switch (dataType) {
332:                case DataBuffer.TYPE_BYTE:
333:                    dataMin = 0.0;
334:                    dataMax = 255.0;
335:                    dataArray = (Object) new byte[nbands][size];
336:                    break;
337:                case DataBuffer.TYPE_SHORT:
338:                    dataMin = Short.MIN_VALUE;
339:                    dataMax = Short.MAX_VALUE;
340:                    dataArray = (Object) new short[nbands][size];
341:                    break;
342:                case DataBuffer.TYPE_USHORT:
343:                    dataMin = 0;
344:                    dataMax = 65535;
345:                    dataArray = (Object) new short[nbands][size];
346:                    break;
347:                case DataBuffer.TYPE_INT:
348:                    dataMin = Integer.MIN_VALUE;
349:                    dataMax = Integer.MAX_VALUE;
350:                    dataArray = (Object) new int[nbands][size];
351:                    break;
352:                case DataBuffer.TYPE_FLOAT:
353:                    dataMin = -Float.MAX_VALUE;
354:                    dataMax = Float.MAX_VALUE;
355:                    dataArray = (Object) new float[nbands][size];
356:                    break;
357:                case DataBuffer.TYPE_DOUBLE:
358:                    dataMin = -Double.MAX_VALUE;
359:                    dataMax = Double.MAX_VALUE;
360:                    dataArray = (Object) new double[nbands][size];
361:                    break;
362:                default:
363:                    throw new RuntimeException(JaiI18N.getString("ColorCube7"));
364:                }
365:
366:                // Ensure that the parameters don't go out of range.
367:                if ((double) (size + offset) > dataMax) {
368:                    throw new RuntimeException(JaiI18N.getString("ColorCube4"));
369:                }
370:
371:                // Initialize the multipliers
372:                int[] multipliers = new int[nbands];
373:                multipliers[0] = 1;
374:                for (int band = 1; band < nbands; band++) {
375:                    multipliers[band] = multipliers[band - 1]
376:                            * dimensionAbs[band - 1];
377:                }
378:
379:                // Populate each band of the lookup table data.
380:                for (int band = 0; band < nbands; band++) {
381:                    // Determine the step size for this band.
382:                    int idimension = dimensionAbs[band];
383:                    double delta;
384:                    if (idimension == 1) {
385:                        // A dimension of one means all entries will be the same
386:                        delta = 0.0;
387:                    } else if (dataType == DataBuffer.TYPE_FLOAT
388:                            || dataType == DataBuffer.TYPE_DOUBLE) {
389:                        delta = 1.0 / (idimension - 1);
390:                    } else {
391:                        delta = (dataMax - dataMin) / (idimension - 1);
392:                    }
393:
394:                    // Set the starting value and index step.
395:                    double start;
396:                    if (dimension[band] < 0) {
397:                        delta = -delta;
398:                        start = dataMax;
399:                    } else {
400:                        start = dataMin;
401:                    }
402:                    int repeatCount = multipliers[band];
403:
404:                    // Load the actual lookup table values for this band
405:                    int index;
406:                    switch (dataType) {
407:                    case DataBuffer.TYPE_BYTE:
408:                        byte[][] byteData = (byte[][]) dataArray;
409:                        index = 0;
410:                        while (index < size) {
411:                            double val = start;
412:                            for (int i = 0; i < idimension; i++) {
413:                                for (int j = 0; j < repeatCount; j++) {
414:                                    byteData[band][index] = (byte) ((int) (val + 0.5) & 0x000000ff);
415:                                    index++;
416:                                }
417:                                val += delta;
418:                            }
419:                        }
420:                        break;
421:
422:                    case DataBuffer.TYPE_SHORT:
423:                    case DataBuffer.TYPE_USHORT:
424:                        short[][] shortData = (short[][]) dataArray;
425:                        index = 0;
426:                        while (index < size) {
427:                            double val = start;
428:                            for (int i = 0; i < idimension; i++) {
429:                                for (int j = 0; j < repeatCount; j++) {
430:                                    shortData[band][index] = (short) (val + 0.5);
431:                                    index++;
432:                                }
433:                                val += delta;
434:                            }
435:                        }
436:                        break;
437:
438:                    case DataBuffer.TYPE_INT:
439:                        int[][] intData = (int[][]) dataArray;
440:                        index = 0;
441:                        while (index < size) {
442:                            double val = start;
443:                            for (int i = 0; i < idimension; i++) {
444:                                for (int j = 0; j < repeatCount; j++) {
445:                                    intData[band][index] = (int) (val + 0.5);
446:                                    index++;
447:                                }
448:                                val += delta;
449:                            }
450:                        }
451:                        break;
452:
453:                    case DataBuffer.TYPE_FLOAT:
454:                        float[][] floatData = (float[][]) dataArray;
455:                        index = 0;
456:                        while (index < size) {
457:                            double val = start;
458:                            for (int i = 0; i < idimension; i++) {
459:                                for (int j = 0; j < repeatCount; j++) {
460:                                    floatData[band][index] = (float) val;
461:                                    index++;
462:                                }
463:                                val += delta;
464:                            }
465:                        }
466:                        break;
467:
468:                    case DataBuffer.TYPE_DOUBLE:
469:                        double[][] doubleData = (double[][]) dataArray;
470:                        index = 0;
471:                        while (index < size) {
472:                            double val = start;
473:                            for (int i = 0; i < idimension; i++) {
474:                                for (int j = 0; j < repeatCount; j++) {
475:                                    doubleData[band][index] = val;
476:                                    index++;
477:                                }
478:                                val += delta;
479:                            }
480:                        }
481:                        break;
482:                    default:
483:                        throw new RuntimeException(JaiI18N
484:                                .getString("ColorCube5"));
485:                    }
486:                }
487:
488:                return dataArray;
489:            }
490:
491:            /**
492:             * Constructs a two-dimensional array of byte data which represent the
493:             * contents of a color cube.
494:             *
495:             * @param offset The initial offset into the data array.
496:             * @param dimension An array of signed sizes of each side of the color
497:             * cube. The color ramp in each dimension will be increasing or decreasing
498:             * according to whether the sign of the corresponding element of the
499:             * <code>dimension</code> array is positive or negative, respectively.
500:             *
501:             * @return A two-dimensional byte array of color cube data.
502:             */
503:            private static byte[][] createDataArrayByte(int offset,
504:                    int dimension[]) {
505:                return (byte[][]) createDataArray(DataBuffer.TYPE_BYTE, offset,
506:                        dimension);
507:            }
508:
509:            /**
510:             * Constructs a two-dimensional array of short data which represent the
511:             * contents of a color cube.
512:             *
513:             * @param offset The initial offset into the data array.
514:             * @param dimension an array of signed sizes of each side of the color
515:             * cube. The color ramp in each dimension will be increasing or decreasing
516:             * according to whether the sign of the corresponding element of the
517:             * <code>dimension</code> array is positive or negative, respectively.
518:             *
519:             * @return A two-dimensional short array of color cube data.
520:             */
521:            private static short[][] createDataArrayShort(int offset,
522:                    int dimension[]) {
523:                return (short[][]) createDataArray(DataBuffer.TYPE_SHORT,
524:                        offset, dimension);
525:            }
526:
527:            /**
528:             * Constructs a two-dimensional array of unsigned short data which
529:             * represent the contents of a color cube.
530:             *
531:             * @param offset The initial offset into the data array.
532:             * @param dimension an array of signed sizes of each side of the color
533:             * cube. The color ramp in each dimension will be increasing or decreasing
534:             * according to whether the sign of the corresponding element of the
535:             * <code>dimension</code> array is positive or negative, respectively.
536:             *
537:             * @return A two-dimensional short array of color cube data.
538:             */
539:            private static short[][] createDataArrayUShort(int offset,
540:                    int dimension[]) {
541:                return (short[][]) createDataArray(DataBuffer.TYPE_USHORT,
542:                        offset, dimension);
543:            }
544:
545:            /**
546:             * Constructs a two-dimensional array of int data which represent the
547:             * contents of a color cube.
548:             *
549:             * @param offset The initial offset into the data array.
550:             * @param dimension an array of signed sizes of each side of the color
551:             * cube. The color ramp in each dimension will be increasing or decreasing
552:             * according to whether the sign of the corresponding element of the
553:             * <code>dimension</code> array is positive or negative, respectively.
554:             *
555:             * @return A two-dimensional int array of color cube data.
556:             */
557:            private static int[][] createDataArrayInt(int offset,
558:                    int dimension[]) {
559:                return (int[][]) createDataArray(DataBuffer.TYPE_INT, offset,
560:                        dimension);
561:            }
562:
563:            /**
564:             * Constructs a two-dimensional array of float data which represent the
565:             * contents of a color cube.
566:             *
567:             * @param offset The initial offset into the data array.
568:             * @param dimension an array of signed sizes of each side of the color
569:             * cube. The color ramp in each dimension will be increasing or decreasing
570:             * according to whether the sign of the corresponding element of the
571:             * <code>dimension</code> array is positive or negative, respectively.
572:             *
573:             * @return A two-dimensional float array of color cube data.
574:             */
575:            private static float[][] createDataArrayFloat(int offset,
576:                    int dimension[]) {
577:                return (float[][]) createDataArray(DataBuffer.TYPE_FLOAT,
578:                        offset, dimension);
579:            }
580:
581:            /**
582:             * Constructs a two-dimensional array of double data which represent the
583:             * contents of a color cube.
584:             *
585:             * @param offset The initial offset into the data array.
586:             * @param dimension an array of signed sizes of each side of the color
587:             * cube. The color ramp in each dimension will be increasing or decreasing
588:             * according to whether the sign of the corresponding element of the
589:             * <code>dimension</code> array is positive or negative, respectively.
590:             *
591:             * @return A two-dimensional double array of color cube data.
592:             */
593:            private static double[][] createDataArrayDouble(int offset,
594:                    int dimension[]) {
595:                return (double[][]) createDataArray(DataBuffer.TYPE_DOUBLE,
596:                        offset, dimension);
597:            }
598:
599:            /**
600:             * Returns a multi-banded byte <code>ColorCube</code> with an index
601:             * offset common to all bands.
602:             *
603:             * @param data The multi-banded byte data in [band][index] format.
604:             * @param offset The common offset for all bands.
605:             *
606:             * @throws IllegalArgumentException if data is null.
607:             */
608:            protected ColorCube(byte data[][], int offset) {
609:                super (data, offset);
610:            }
611:
612:            /**
613:             * Returns a multi-banded short or unsigned short <code>ColorCube</code>
614:             * with an index offset common to all bands.
615:             *
616:             * @param data The multi-banded short data in [band][index] format.
617:             * @param offset The common offset for all bands.
618:             * @param isUShort  True if data type is DataBuffer.TYPE_USHORT;
619:             *                  false if data type is DataBuffer.TYPE_SHORT.
620:             *
621:             * @throws IllegalArgumentException if data is null.
622:             */
623:            protected ColorCube(short data[][], int offset, boolean isUShort) {
624:                super (data, offset, isUShort);
625:            }
626:
627:            /**
628:             * Returns a multi-banded int <code>ColorCube</code> with an index
629:             * offset common to all bands.
630:             *
631:             * @param data The multi-banded int data in [band][index] format.
632:             * @param offset The common offset for all bands.
633:             *
634:             * @throws IllegalArgumentException if data is null.
635:             */
636:            protected ColorCube(int data[][], int offset) {
637:                super (data, offset);
638:            }
639:
640:            /**
641:             * Returns a multi-banded float <code>ColorCube</code> with an index
642:             * offset common to all bands.
643:             *
644:             * @param data The multi-banded float data in [band][index] format.
645:             * @param offset The common offset for all bands.
646:             *
647:             * @throws IllegalArgumentException if data is null.
648:             */
649:            protected ColorCube(float data[][], int offset) {
650:                super (data, offset);
651:            }
652:
653:            /**
654:             * Returns a multi-banded double <code>ColorCube</code> with an index
655:             * offset common to all bands.
656:             *
657:             * @param data The multi-banded double data in [band][index] format.
658:             * @param offset The common offset for all bands.
659:             *
660:             * @throws IllegalArgumentException if data is null.
661:             */
662:            protected ColorCube(double data[][], int offset) {
663:                super (data, offset);
664:            }
665:
666:            /**
667:             * Initialize the fields of a <code>ColorCube</code>.
668:             *
669:             * @param offset The common offset for all bands.
670:             * @param dimension The signed dimension for each band.
671:             */
672:            private void initFields(int offset, int[] dimension) {
673:                // Save a reference to the dimension array.
674:                this .dimension = dimension;
675:
676:                // Allocate memory
677:                multipliers = new int[dimension.length];
678:                dimsLessOne = new int[dimension.length];
679:
680:                // Calculate multiplier magnitudes.
681:                multipliers[0] = 1;
682:                for (int i = 1; i < multipliers.length; i++) {
683:                    multipliers[i] = multipliers[i - 1]
684:                            * Math.abs(dimension[i - 1]);
685:                }
686:
687:                // Set multiplier signs and initialize dimsLessOne.
688:                for (int i = 0; i < multipliers.length; i++) {
689:                    if (dimension[i] < 0) {
690:                        multipliers[i] = -multipliers[i];
691:                    }
692:                    dimsLessOne[i] = Math.abs(dimension[i]) - 1;
693:                }
694:
695:                // Calculate adjusted offset.
696:                adjustedOffset = offset;
697:                for (int i = 0; i < dimension.length; i++) {
698:                    if (dimension[i] > 1 && multipliers[i] < 0) {
699:                        adjustedOffset += Math.abs(multipliers[i])
700:                                * dimsLessOne[i];
701:                    }
702:                }
703:
704:                // Cache the data type and number of bands to avoid repetitive calls
705:                // in findNearestEntry().
706:                dataType = getDataType();
707:                numBands = getNumBands();
708:            }
709:
710:            /**
711:             * Returns the array of signed dimensions used to construct the
712:             * <code>ColorCube</code>.
713:             *
714:             */
715:            public int[] getDimension() {
716:                return dimension;
717:            }
718:
719:            /**
720:             * Returns an array containing the signed dimensions, less one.
721:             *
722:             */
723:            public int[] getDimsLessOne() {
724:                return dimsLessOne;
725:            }
726:
727:            /**
728:             * Returns the multipliers as an array.
729:             *
730:             */
731:            public int[] getMultipliers() {
732:                return multipliers;
733:            }
734:
735:            /**
736:             * Returns the adjusted offset into the lookup table, accounting for
737:             * negative dimensions.
738:             *
739:             */
740:            public int getAdjustedOffset() {
741:                return adjustedOffset;
742:            }
743:
744:            /**
745:             * Finds the index of the nearest color in the color map to the
746:             * pixel value argument.
747:             *
748:             * @param pixel a float array of all samples of a pixel.
749:             * @return the index of the nearest color.
750:             *
751:             * @throws RuntimeException for dataTypes other than
752:             *     DataBuffer.TYPE_BYTE DataBuffer.TYPE_USHORT
753:             *     DataBuffer.TYPE_SHORT DataBuffer.TYPE_INT
754:             *     DataBuffer.TYPE_FLOAT DataBuffer.TYPE_DOUBLE
755:             */
756:            public int findNearestEntry(float[] pixel) {
757:                int index = -1;
758:
759:                index = adjustedOffset;
760:
761:                switch (dataType) {
762:                case DataBuffer.TYPE_BYTE:
763:                    for (int band = 0; band < numBands; band++) {
764:                        int tmp = (int) (pixel[band] * dimsLessOne[band]);
765:
766:                        if ((tmp & 0xFF) > 127) {
767:                            tmp += (int) 0x100;
768:                        }
769:
770:                        index += (tmp >> 8) * multipliers[band];
771:                    }
772:                    break;
773:                case DataBuffer.TYPE_SHORT:
774:                    for (int band = 0; band < numBands; band++) {
775:                        int tmp = (int) (pixel[band] - Short.MIN_VALUE)
776:                                * dimsLessOne[band];
777:
778:                        if ((tmp & 0xFFFF) > Short.MAX_VALUE) {
779:                            tmp += (int) 0x10000;
780:                        }
781:
782:                        index += (tmp >> 16) * multipliers[band];
783:                    }
784:                    break;
785:                case DataBuffer.TYPE_USHORT:
786:                    for (int band = 0; band < numBands; band++) {
787:                        int tmp = (int) (pixel[band] * dimsLessOne[band]);
788:
789:                        if ((tmp & 0xFFFF) > Short.MAX_VALUE) {
790:                            tmp += (int) 0x10000;
791:                        }
792:
793:                        index += (tmp >> 16) * multipliers[band];
794:                    }
795:                    break;
796:                case DataBuffer.TYPE_INT:
797:                    for (int band = 0; band < numBands; band++) {
798:                        long tmp = (long) ((pixel[band] - Integer.MIN_VALUE) * dimsLessOne[band]);
799:
800:                        if (tmp > Integer.MAX_VALUE) {
801:                            tmp += ((long) 0xffffffff + 1L);
802:                        }
803:
804:                        index += ((int) (tmp >> 32)) * multipliers[band];
805:                    }
806:                    break;
807:                case DataBuffer.TYPE_FLOAT:
808:                    for (int band = 0; band < numBands; band++) {
809:                        float ftmp = pixel[band] * dimsLessOne[band];
810:                        int itmp = (int) ftmp;
811:
812:                        if ((ftmp - itmp) >= 0.5F) {
813:                            itmp++;
814:                        }
815:
816:                        index += itmp * multipliers[band];
817:                    }
818:                    break;
819:                case DataBuffer.TYPE_DOUBLE:
820:                    for (int band = 0; band < numBands; band++) {
821:                        double ftmp = pixel[band] * dimsLessOne[band];
822:                        int itmp = (int) ftmp;
823:
824:                        if ((ftmp - itmp) >= 0.5) {
825:                            itmp++;
826:                        }
827:
828:                        index += itmp * multipliers[band];
829:                    }
830:                    break;
831:                default:
832:                    throw new RuntimeException(JaiI18N.getString("ColorCube6"));
833:                }
834:
835:                return index;
836:            }
837:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.