Source Code Cross Referenced for FloatDoubleColorModel.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) 


0001:        /*
0002:         * $RCSfile: FloatDoubleColorModel.java,v $
0003:         *
0004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Use is subject to license terms.
0007:         *
0008:         * $Revision: 1.2 $
0009:         * $Date: 2005/11/16 00:26:52 $
0010:         * $State: Exp $
0011:         */
0012:        package javax.media.jai;
0013:
0014:        import java.awt.Point;
0015:        import java.awt.Transparency;
0016:        import java.awt.color.ColorSpace;
0017:        import java.awt.image.ColorModel;
0018:        import java.awt.image.ComponentColorModel;
0019:        import java.awt.image.ComponentSampleModel;
0020:        import java.awt.image.DataBuffer;
0021:        import java.awt.image.Raster;
0022:        import java.awt.image.SampleModel;
0023:        import java.awt.image.WritableRaster;
0024:
0025:        /**
0026:         * A <code>ColorModel</code> class that works with pixel values that
0027:         * represent color and alpha information as separate samples, using
0028:         * float or double elements.  This class can be used with an arbitrary
0029:         * <code>ColorSpace</code>.  The number of color samples in the pixel
0030:         * values must be same as the number of color components in the
0031:         * <code>ColorSpace</code>.  There may be a single alpha sample.
0032:         *
0033:         * <p> Sample values are taken as ranging from 0.0 to 1.0; that is,
0034:         * when converting to 8-bit RGB, a multiplication by 255 is performed
0035:         * and values outside of the range 0-255 are clamped at the closest
0036:         * endpoint.
0037:         *
0038:         * <p> For maximum efficiency, pixel data being interpreted by this
0039:         * class should be in the sRGB color space.  This will result in 
0040:         * only the trivial conversion (scaling by 255 and dividing by any
0041:         * premultiplied alpha) to be performed.  Other color spaces require
0042:         * more general conversions.
0043:         *
0044:         * <p> For those methods that use a primitive array pixel
0045:         * representation of type <code>transferType</code>, the array length
0046:         * is the same as the number of color and alpha samples.  Color
0047:         * samples are stored first in the array followed by the alpha sample,
0048:         * if present.  The order of the color samples is specified by the
0049:         * <code>ColorSpace</code>.  Typically, this order reflects the name
0050:         * of the color space type. For example, for <code>TYPE_RGB</code>,
0051:         * index 0 corresponds to red, index 1 to green, and index 2 to blue.
0052:         * The transfer types supported are
0053:         * <code>DataBuffer.TYPE_FLOAT</code>,
0054:         * <code>DataBuffer.TYPE_DOUBLE</code>.
0055:         *
0056:         * <p> The translation from pixel values to color/alpha components for
0057:         * display or processing purposes is a one-to-one correspondence of
0058:         * samples to components.
0059:         *
0060:         * <p> Methods that use a single int pixel representation throw an
0061:         * <code>IllegalArgumentException</code>.
0062:         *
0063:         * <p> A <code>FloatDoubleColorModel</code> can be used in
0064:         * conjunction with a <code>ComponentSampleModelJAI</code>.
0065:         *
0066:         * @see java.awt.image.ColorModel
0067:         * @see java.awt.color.ColorSpace
0068:         * @see java.awt.image.ComponentSampleModel
0069:         * @see ComponentSampleModelJAI
0070:         */
0071:        public class FloatDoubleColorModel extends ComponentColorModel {
0072:
0073:            /**
0074:             * The associated <code>ColorSpace</code>.
0075:             *
0076:             * @since JAI 1.1
0077:             */
0078:            protected ColorSpace colorSpace;
0079:
0080:            /**
0081:             * The type or family of the associated <code>ColorSpace</code>.
0082:             *
0083:             * @since JAI 1.1
0084:             */
0085:            protected int colorSpaceType;
0086:
0087:            /**
0088:             * The number of components of the associated <code>ColorSpace</code>.
0089:             *
0090:             * @since JAI 1.1
0091:             */
0092:            protected int numColorComponents;
0093:
0094:            /**
0095:             * The number of components represented by this <code>ColorModel</code>.
0096:             * This will differ from the number of components of the associated
0097:             * <code>ColorSpace</code> if there is an alpha channel.
0098:             *
0099:             * @since JAI 1.1
0100:             */
0101:            protected int numComponents;
0102:
0103:            /**
0104:             * Specifies what alpha values can be represented by this
0105:             * <code>ColorModel</code>.
0106:             *
0107:             * @since JAI 1.1
0108:             */
0109:            protected int transparency;
0110:
0111:            /**
0112:             * Whether this <code>ColorModel</code> supports alpha.
0113:             *
0114:             * @since JAI 1.1
0115:             */
0116:            protected boolean hasAlpha;
0117:
0118:            /**
0119:             * Whether alpha is premultiplied.
0120:             *
0121:             * @since JAI 1.1
0122:             */
0123:            protected boolean isAlphaPremultiplied;
0124:
0125:            private static int[] bitsHelper(int transferType,
0126:                    ColorSpace colorSpace, boolean hasAlpha) {
0127:                int numBits = (transferType == DataBuffer.TYPE_FLOAT) ? 32 : 64;
0128:                int numComponents = colorSpace.getNumComponents();
0129:                if (hasAlpha) {
0130:                    ++numComponents;
0131:                }
0132:                int[] bits = new int[numComponents];
0133:                for (int i = 0; i < numComponents; i++) {
0134:                    bits[i] = numBits;
0135:                }
0136:
0137:                return bits;
0138:            }
0139:
0140:            /**
0141:             * Constructs a <code>ComponentColorModel</code> from the
0142:             * specified parameters. Color components will be in the specified
0143:             * <code>ColorSpace</code>.  <code>hasAlpha</code> indicates
0144:             * whether alpha information is present.  If <code>hasAlpha</code>
0145:             * is true, then the boolean <code>isAlphaPremultiplied</code>
0146:             * specifies how to interpret color and alpha samples in pixel
0147:             * values.  If the boolean is <code>true</code>, color samples are
0148:             * assumed to have been multiplied by the alpha sample. The
0149:             * <code>transparency</code> specifies what alpha values can be
0150:             * represented by this color model.  The <code>transferType</code>
0151:             * is the type of primitive array used to represent pixel values.
0152:             *
0153:             * @param colorSpace       The <code>ColorSpace</code> associated with
0154:             *                         this color model.
0155:             * @param hasAlpha         If true, this color model supports alpha.
0156:             * @param isAlphaPremultiplied If true, alpha is premultiplied.
0157:             * @param transparency     Specifies what alpha values can be represented
0158:             *                         by this color model.
0159:             * @param transferType     Specifies the type of primitive array used to
0160:             *                         represent pixel values, one of
0161:             *                         DataBuffer.TYPE_FLOAT or TYPE_DOUBLE.
0162:             * @throws IllegalArgumentException If the transfer type is not
0163:             *         DataBuffer.TYPE_FLOAT or TYPE_DOUBLE.
0164:             *
0165:             * @see java.awt.color.ColorSpace
0166:             * @see java.awt.Transparency
0167:             */
0168:            public FloatDoubleColorModel(ColorSpace colorSpace,
0169:                    boolean hasAlpha, boolean isAlphaPremultiplied,
0170:                    int transparency, int transferType) {
0171:                super (colorSpace,
0172:                        bitsHelper(transferType, colorSpace, hasAlpha),
0173:                        hasAlpha, isAlphaPremultiplied, transparency,
0174:                        transferType);
0175:
0176:                if (transferType != DataBuffer.TYPE_FLOAT
0177:                        && transferType != DataBuffer.TYPE_DOUBLE) {
0178:                    throw new IllegalArgumentException(JaiI18N
0179:                            .getString("FloatDoubleColorModel0"));
0180:                }
0181:
0182:                this .colorSpace = colorSpace;
0183:                this .colorSpaceType = colorSpace.getType();
0184:                this .numComponents = this .numColorComponents = colorSpace
0185:                        .getNumComponents();
0186:                if (hasAlpha) {
0187:                    ++numComponents;
0188:                }
0189:                this .transparency = transparency;
0190:                this .hasAlpha = hasAlpha;
0191:                this .isAlphaPremultiplied = isAlphaPremultiplied;
0192:            }
0193:
0194:            /**
0195:             * Throws an <code>IllegalArgumentException</code>, since pixel
0196:             * values for this <code>ColorModel</code> are not conveniently
0197:             * representable as a single <code>int</code>.
0198:             */
0199:            public int getRed(int pixel) {
0200:                throw new IllegalArgumentException(JaiI18N
0201:                        .getString("FloatDoubleColorModel1"));
0202:            }
0203:
0204:            /**
0205:             * Throws an <code>IllegalArgumentException</code>, since pixel
0206:             * values for this <code>ColorModel</code> are not conveniently
0207:             * representable as a single <code>int</code>.
0208:             */
0209:            public int getGreen(int pixel) {
0210:                throw new IllegalArgumentException(JaiI18N
0211:                        .getString("FloatDoubleColorModel2"));
0212:            }
0213:
0214:            /**
0215:             * Throws an <code>IllegalArgumentException</code>, since pixel
0216:             * values for this <code>ColorModel</code> are not conveniently
0217:             * representable as a single <code>int</code>.
0218:             */
0219:            public int getBlue(int pixel) {
0220:                throw new IllegalArgumentException(JaiI18N
0221:                        .getString("FloatDoubleColorModel3"));
0222:            }
0223:
0224:            /**
0225:             * Throws an <code>IllegalArgumentException</code>, since pixel
0226:             * values for this <code>ColorModel</code> are not conveniently
0227:             * representable as a single <code>int</code>.
0228:             */
0229:            public int getAlpha(int pixel) {
0230:                throw new IllegalArgumentException(JaiI18N
0231:                        .getString("FloatDoubleColorModel4"));
0232:            }
0233:
0234:            /**
0235:             * Throws an <code>IllegalArgumentException</code>, since pixel
0236:             * values for this <code>ColorModel</code> are not conveniently
0237:             * representable as a single <code>int</code>.
0238:             */
0239:            public int getRGB(int pixel) {
0240:                throw new IllegalArgumentException(JaiI18N
0241:                        .getString("FloatDoubleColorModel5"));
0242:            }
0243:
0244:            private final int clamp(float value) {
0245:                // Ensure NaN maps to 0
0246:                return (value >= 0.0F) ? ((value > 255.0F) ? 255 : (int) value)
0247:                        : 0;
0248:            }
0249:
0250:            private final int clamp(double value) {
0251:                // Ensure NaN maps to 0
0252:                return (value >= 0.0) ? ((value > 255.0) ? 255 : (int) value)
0253:                        : 0;
0254:            }
0255:
0256:            private int getSample(Object inData, int sample) {
0257:                boolean needAlpha = (hasAlpha && isAlphaPremultiplied);
0258:                int type = colorSpaceType;
0259:
0260:                boolean is_sRGB = colorSpace.isCS_sRGB();
0261:
0262:                if (type == ColorSpace.TYPE_GRAY) {
0263:                    sample = 0;
0264:                    is_sRGB = true;
0265:                }
0266:
0267:                if (is_sRGB) {
0268:                    if (transferType == DataBuffer.TYPE_FLOAT) {
0269:                        float[] fdata = (float[]) inData;
0270:                        float fsample = fdata[sample] * 255;
0271:                        if (needAlpha) {
0272:                            float falp = fdata[numColorComponents];
0273:                            if (falp == 0.0)
0274:                                return 0;
0275:                            else
0276:                                return clamp(fsample / falp);
0277:                        } else {
0278:                            return clamp(fsample);
0279:                        }
0280:                    } else {
0281:                        double[] ddata = (double[]) inData;
0282:                        double dsample = ddata[sample] * 255.0;
0283:                        if (needAlpha) {
0284:                            double dalp = ddata[numColorComponents];
0285:                            if (dalp == 0.0)
0286:                                return 0;
0287:                            else
0288:                                return clamp(dsample / dalp);
0289:                        } else {
0290:                            return clamp(dsample);
0291:                        }
0292:                    }
0293:                }
0294:
0295:                // Not TYPE_GRAY or TYPE_RGB ColorSpace
0296:                float[] norm;
0297:                float[] rgb;
0298:                if (transferType == DataBuffer.TYPE_FLOAT) {
0299:                    float[] fdata = (float[]) inData;
0300:                    if (needAlpha) {
0301:                        float falp = fdata[numColorComponents];
0302:                        if (falp == 0.0)
0303:                            return 0;
0304:                        norm = new float[numColorComponents];
0305:                        for (int i = 0; i < numColorComponents; i++) {
0306:                            norm[i] = fdata[i] / falp;
0307:                        }
0308:                        rgb = colorSpace.toRGB(norm);
0309:                    } else {
0310:                        rgb = colorSpace.toRGB(fdata);
0311:                    }
0312:                    return (int) (rgb[sample] * 255 + 0.5F);
0313:                } else {
0314:                    double[] ddata = (double[]) inData;
0315:                    norm = new float[numColorComponents];
0316:                    if (needAlpha) {
0317:                        double dalp = ddata[numColorComponents];
0318:                        if (dalp == 0.0)
0319:                            return 0;
0320:                        for (int i = 0; i < numColorComponents; i++) {
0321:                            norm[i] = (float) (ddata[i] / dalp);
0322:                        }
0323:                        rgb = colorSpace.toRGB(norm);
0324:                    } else {
0325:                        for (int i = 0; i < numColorComponents; i++) {
0326:                            norm[i] = (float) ddata[i];
0327:                        }
0328:                        rgb = colorSpace.toRGB(norm);
0329:                    }
0330:                    return (int) (rgb[sample] * 255 + 0.5);
0331:                }
0332:            }
0333:
0334:            /**
0335:             * Returns the red color component for the specified pixel, scaled
0336:             * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A color
0337:             * conversion is done if necessary.  The <code>pixel</code> value
0338:             * is specified by an array of data elements of type
0339:             * <code>transferType</code> passed in as an object reference. The
0340:             * returned value will be a non pre-multiplied value. If the alpha
0341:             * is premultiplied, this method divides it out before returning
0342:             * the value (if the alpha value is 0, the red value will be 0).
0343:             *
0344:             * @param inData The pixel from which to get the red
0345:             * color component, specified by an array of data elements of type
0346:             * <code>transferType</code>.
0347:             *
0348:             * @return The red color component for the specified pixel, as an
0349:             * int.
0350:             *
0351:             * @throws ClassCastException If <code>inData</code> is not a
0352:             * primitive array of type <code>transferType</code>.
0353:             * @throws ArrayIndexOutOfBoundsException if <code>inData</code>
0354:             * is not large enough to hold a pixel value for this
0355:             * <code>ColorModel</code>.
0356:             */
0357:            public int getRed(Object inData) {
0358:                return getSample(inData, 0);
0359:            }
0360:
0361:            /**
0362:             * Returns the green color component for the specified pixel, scaled
0363:             * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A color
0364:             * conversion is done if necessary.  The <code>pixel</code> value
0365:             * is specified by an array of data elements of type
0366:             * <code>transferType</code> passed in as an object reference. The
0367:             * returned value will be a non pre-multiplied value. If the alpha
0368:             * is premultiplied, this method divides it out before returning
0369:             * the value (if the alpha value is 0, the green value will be 0).
0370:             *
0371:             * @param inData The pixel from which to get the green
0372:             * color component, specified by an array of data elements of type
0373:             * <code>transferType</code>.
0374:             *
0375:             * @return The green color component for the specified pixel, as an
0376:             * int.
0377:             *
0378:             * @throws ClassCastException If <code>inData</code> is not a
0379:             * primitive array of type <code>transferType</code>.
0380:             * @throws ArrayIndexOutOfBoundsException if <code>inData</code>
0381:             * is not large enough to hold a pixel value for this
0382:             * <code>ColorModel</code>.
0383:             */
0384:            public int getGreen(Object inData) {
0385:                return getSample(inData, 1);
0386:            }
0387:
0388:            /**
0389:             * Returns the blue color component for the specified pixel, scaled
0390:             * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A color
0391:             * conversion is done if necessary.  The <code>pixel</code> value
0392:             * is specified by an array of data elements of type
0393:             * <code>transferType</code> passed in as an object reference. The
0394:             * returned value will be a non pre-multiplied value. If the alpha
0395:             * is premultiplied, this method divides it out before returning
0396:             * the value (if the alpha value is 0, the blue value will be 0).
0397:             *
0398:             * @param inData The pixel from which to get the blue
0399:             * color component, specified by an array of data elements of type
0400:             * <code>transferType</code>.
0401:             *
0402:             * @return The blue color component for the specified pixel, as an
0403:             * int.
0404:             *
0405:             * @throws ClassCastException If <code>inData</code> is not a
0406:             * primitive array of type <code>transferType</code>.
0407:             * @throws ArrayIndexOutOfBoundsException if <code>inData</code>
0408:             * is not large enough to hold a pixel value for this
0409:             * <code>ColorModel</code>.
0410:             */
0411:            public int getBlue(Object inData) {
0412:                return getSample(inData, 2);
0413:            }
0414:
0415:            /**
0416:             * Returns the alpha component for the specified pixel, scaled
0417:             * from 0 to 255.  The pixel value is specified by an array of
0418:             * data elements of type <code>transferType</code> passed in as an
0419:             * object reference.  If the <code>ColorModel</code> does not have
0420:             * alpha, 255 is returned.
0421:             *
0422:             * @param inData The pixel from which to get the alpha
0423:             * component, specified by an array of data elements of type
0424:             * <code>transferType</code>.
0425:             *
0426:             * @return The alpha component for the specified pixel, as an int.
0427:             *
0428:             * @throws IllegalArgumentException if <code>inData</code> is
0429:             * <code>null</code> and the <code>colorModel</code> has alpha.
0430:             * @throws ClassCastException If <code>inData</code> is not a
0431:             * primitive array of type <code>transferType</code> and the
0432:             * <code>ColorModel</code> has alpha.
0433:             * @throws ArrayIndexOutOfBoundsException if <code>inData</code>
0434:             * is not large enough to hold a pixel value for this
0435:             * <code>ColorModel</code> and the <code>ColorModel</code> has
0436:             * alpha.
0437:             */
0438:            public int getAlpha(Object inData) {
0439:                if (inData == null) {
0440:                    throw new IllegalArgumentException(JaiI18N
0441:                            .getString("Generic0"));
0442:                }
0443:
0444:                if (hasAlpha == false) {
0445:                    return 255;
0446:                }
0447:
0448:                if (transferType == DataBuffer.TYPE_FLOAT) {
0449:                    float[] fdata = (float[]) inData;
0450:                    return (int) (fdata[numColorComponents] * 255.0F + 0.5F);
0451:                } else {
0452:                    double[] ddata = (double[]) inData;
0453:                    return (int) (ddata[numColorComponents] * 255.0 + 0.5);
0454:                }
0455:            }
0456:
0457:            /**
0458:             * Returns the color/alpha components for the specified pixel in
0459:             * the default RGB color model format.  A color conversion is done
0460:             * if necessary.  The pixel value is specified by an array of data
0461:             * elements of type <code>transferType</code> passed in as an
0462:             * object reference.  The returned value is in a non
0463:             * pre-multiplied format. If the alpha is premultiplied, this
0464:             * method divides it out of the color components (if the alpha
0465:             * value is 0, the color values will be 0).
0466:             *
0467:             * @param inData The pixel from which to get the
0468:             * color/alpha components, specified by an array of data elements
0469:             * of type <code>transferType</code>.
0470:             *
0471:             * @return The color/alpha components for the specified pixel, as an int.
0472:             *
0473:             * @throws ClassCastException If <code>inData</code> is not a
0474:             * primitive array of type <code>transferType</code>.
0475:             * @throws ArrayIndexOutOfBoundsException if <code>inData</code>
0476:             * is not large enough to hold a pixel value for this
0477:             * <code>ColorModel</code>.
0478:             */
0479:            public int getRGB(Object inData) {
0480:                boolean needAlpha = (hasAlpha && isAlphaPremultiplied);
0481:                int alpha = 255;
0482:                int red, green, blue;
0483:
0484:                if (colorSpace.isCS_sRGB()) {
0485:                    if (transferType == DataBuffer.TYPE_FLOAT) {
0486:                        float[] fdata = (float[]) inData;
0487:                        float fred = fdata[0];
0488:                        float fgreen = fdata[1];
0489:                        float fblue = fdata[2];
0490:                        float fscale = 255.0F;
0491:                        if (needAlpha) {
0492:                            float falpha = fdata[3];
0493:                            fscale /= falpha;
0494:                            alpha = clamp(255.0F * falpha);
0495:                        }
0496:
0497:                        red = clamp(fred * fscale);
0498:                        green = clamp(fgreen * fscale);
0499:                        blue = clamp(fblue * fscale);
0500:                    } else {
0501:                        double[] ddata = (double[]) inData;
0502:                        double dred = ddata[0];
0503:                        double dgreen = ddata[1];
0504:                        double dblue = ddata[2];
0505:                        double dscale = 255.0;
0506:                        if (needAlpha) {
0507:                            double dalpha = ddata[3];
0508:                            dscale /= dalpha;
0509:                            alpha = clamp(255.0 * dalpha);
0510:                        }
0511:
0512:                        red = clamp(dred * dscale);
0513:                        green = clamp(dgreen * dscale);
0514:                        blue = clamp(dblue * dscale);
0515:                    }
0516:                } else if (colorSpaceType == ColorSpace.TYPE_GRAY) {
0517:                    if (transferType == DataBuffer.TYPE_FLOAT) {
0518:                        float[] fdata = (float[]) inData;
0519:                        float fgray = fdata[0];
0520:                        if (needAlpha) {
0521:                            float falp = fdata[1];
0522:                            red = green = blue = clamp(fgray * 255.0F / falp);
0523:                            alpha = clamp(255.0F * falp);
0524:                        } else {
0525:                            red = green = blue = clamp(fgray * 255.0F);
0526:                        }
0527:                    } else {
0528:                        double[] ddata = (double[]) inData;
0529:                        double dgray = ddata[0];
0530:                        if (needAlpha) {
0531:                            double dalp = ddata[1];
0532:                            red = green = blue = clamp(dgray * 255.0 / dalp);
0533:                            alpha = clamp(255.0 * dalp);
0534:                        } else {
0535:                            red = green = blue = clamp(dgray * 255.0);
0536:                        }
0537:                    }
0538:                } else {
0539:                    // Not Gray or sRGB
0540:                    float[] norm;
0541:                    float[] rgb;
0542:                    if (transferType == DataBuffer.TYPE_FLOAT) {
0543:                        float[] fdata = (float[]) inData;
0544:                        if (needAlpha) {
0545:                            float falp = fdata[numColorComponents];
0546:                            float invfalp = 1.0F / falp;
0547:                            norm = new float[numColorComponents];
0548:                            for (int i = 0; i < numColorComponents; i++) {
0549:                                norm[i] = fdata[i] * invfalp;
0550:                            }
0551:                            alpha = clamp(255.0F * falp);
0552:                        } else {
0553:                            norm = fdata;
0554:                        }
0555:                    } else {
0556:                        double[] ddata = (double[]) inData;
0557:                        norm = new float[numColorComponents];
0558:                        if (needAlpha) {
0559:                            double dalp = ddata[numColorComponents];
0560:                            double invdalp = 1.0 / dalp;
0561:                            for (int i = 0; i < numColorComponents; i++) {
0562:                                norm[i] = (float) (ddata[i] * invdalp);
0563:                            }
0564:                            alpha = clamp(255.0 * dalp);
0565:                        } else {
0566:                            for (int i = 0; i < numColorComponents; i++) {
0567:                                norm[i] = (float) ddata[i];
0568:                            }
0569:                        }
0570:                    }
0571:
0572:                    // Perform color conversion
0573:                    rgb = colorSpace.toRGB(norm);
0574:
0575:                    red = clamp(rgb[0] * 255.0F);
0576:                    green = clamp(rgb[1] * 255.0F);
0577:                    blue = clamp(rgb[2] * 255.0F);
0578:                }
0579:
0580:                return (alpha << 24) | (red << 16) | (green << 8) | blue;
0581:            }
0582:
0583:            /**
0584:             * Returns a data element array representation of a pixel in this
0585:             * <code>ColorModel</code>, given an integer pixel representation
0586:             * in the default RGB color model.  This array can then be passed
0587:             * to the <code>setDataElements</code> method of a
0588:             * <code>WritableRaster</code> object.  If the <code>pixel</code>
0589:             * parameter is null, a new array is allocated.
0590:             * If the colorSpaceType is of TYPE_GRAY then the rgb components
0591:             * are converted to gray using appropriate weights
0592:             *
0593:             * @param rgb An ARGB value packed into an int.
0594:             * @param pixel The float or double array representation of the pixel.
0595:             *
0596:             * @throws ClassCastException If <code>pixel</code> is not null and 
0597:             * is not a primitive array of type <code>transferType</code>.  
0598:             *
0599:             * @throws ArrayIndexOutOfBoundsException If <code>pixel</code> is 
0600:             * not large enough to hold a pixel value for this
0601:             * <code>ColorModel</code>. 
0602:             */
0603:            public Object getDataElements(int rgb, Object pixel) {
0604:                if (transferType == DataBuffer.TYPE_FLOAT) {
0605:                    float[] floatPixel;
0606:
0607:                    if (pixel == null) {
0608:                        floatPixel = new float[numComponents];
0609:                    } else {
0610:                        if (!(pixel instanceof  float[])) {
0611:                            throw new ClassCastException(JaiI18N
0612:                                    .getString("FloatDoubleColorModel7"));
0613:                        }
0614:                        floatPixel = (float[]) pixel;
0615:                        if (floatPixel.length < numComponents) {
0616:                            throw new ArrayIndexOutOfBoundsException(JaiI18N
0617:                                    .getString("FloatDoubleColorModel8"));
0618:                        }
0619:                    }
0620:
0621:                    float inv255 = 1.0F / 255.0F;
0622:                    if (colorSpace.isCS_sRGB()) {
0623:                        int alp = (rgb >> 24) & 0xff;
0624:                        int red = (rgb >> 16) & 0xff;
0625:                        int grn = (rgb >> 8) & 0xff;
0626:                        int blu = (rgb) & 0xff;
0627:                        float norm = inv255;
0628:                        if (isAlphaPremultiplied) {
0629:                            norm *= alp;
0630:                        }
0631:                        floatPixel[0] = red * norm;
0632:                        floatPixel[1] = grn * norm;
0633:                        floatPixel[2] = blu * norm;
0634:                        if (hasAlpha) {
0635:                            floatPixel[3] = alp * inv255;
0636:                        }
0637:                    } else if (colorSpaceType == ColorSpace.TYPE_GRAY) {
0638:                        float gray = ((((rgb >> 16) & 0xff) * (.299F * inv255))
0639:                                + (((rgb >> 8) & 0xff) * (.587F * inv255)) + (((rgb) & 0xff) * (.114F * inv255)));
0640:
0641:                        floatPixel[0] = gray;
0642:
0643:                        if (hasAlpha) {
0644:                            int alpha = (rgb >> 24) & 0xff;
0645:                            floatPixel[1] = alpha * inv255;
0646:                        }
0647:                    } else {
0648:                        // Need to convert the color
0649:                        float[] norm = new float[3];
0650:                        norm[0] = ((rgb >> 16) & 0xff) * inv255;
0651:                        norm[1] = ((rgb >> 8) & 0xff) * inv255;
0652:                        norm[2] = ((rgb) & 0xff) * inv255;
0653:
0654:                        norm = colorSpace.fromRGB(norm);
0655:                        for (int i = 0; i < numColorComponents; i++) {
0656:                            floatPixel[i] = norm[i];
0657:                        }
0658:                        if (hasAlpha) {
0659:                            int alpha = (rgb >> 24) & 0xff;
0660:                            floatPixel[numColorComponents] = alpha * inv255;
0661:                        }
0662:                    }
0663:
0664:                    return floatPixel;
0665:                } else { // transferType == DataBuffer.TYPE_DOUBLE
0666:                    double[] doublePixel;
0667:
0668:                    if (pixel == null) {
0669:                        doublePixel = new double[numComponents];
0670:                    } else {
0671:                        if (!(pixel instanceof  double[])) {
0672:                            throw new ClassCastException(JaiI18N
0673:                                    .getString("FloatDoubleColorModel7"));
0674:                        }
0675:                        doublePixel = (double[]) pixel;
0676:                        if (doublePixel.length < numComponents) {
0677:                            throw new ArrayIndexOutOfBoundsException(JaiI18N
0678:                                    .getString("FloatDoubleColorModel8"));
0679:                        }
0680:                    }
0681:
0682:                    double inv255 = 1.0 / 255.0;
0683:                    if (colorSpace.isCS_sRGB()) {
0684:                        int alp = (rgb >> 24) & 0xff;
0685:                        int red = (rgb >> 16) & 0xff;
0686:                        int grn = (rgb >> 8) & 0xff;
0687:                        int blu = (rgb) & 0xff;
0688:                        double norm = inv255;
0689:                        if (isAlphaPremultiplied) {
0690:                            norm *= alp;
0691:                        }
0692:                        doublePixel[0] = red * norm;
0693:                        doublePixel[1] = grn * norm;
0694:                        doublePixel[2] = blu * norm;
0695:                        if (hasAlpha) {
0696:                            doublePixel[3] = alp * inv255;
0697:                        }
0698:                    } else if (colorSpaceType == ColorSpace.TYPE_GRAY) {
0699:                        double gray = ((((rgb >> 16) & 0xff) * (.299 * inv255))
0700:                                + (((rgb >> 8) & 0xff) * (.587 * inv255)) + (((rgb) & 0xff) * (.114 * inv255)));
0701:
0702:                        doublePixel[0] = gray;
0703:
0704:                        if (hasAlpha) {
0705:                            int alpha = (rgb >> 24) & 0xff;
0706:                            doublePixel[1] = alpha * inv255;
0707:                        }
0708:                    } else {
0709:                        float inv255F = 1.0F / 255.0F;
0710:
0711:                        // Need to convert the color, need data in float form
0712:                        float[] norm = new float[3];
0713:                        norm[0] = ((rgb >> 16) & 0xff) * inv255F;
0714:                        norm[1] = ((rgb >> 8) & 0xff) * inv255F;
0715:                        norm[2] = ((rgb) & 0xff) * inv255F;
0716:
0717:                        norm = colorSpace.fromRGB(norm);
0718:                        for (int i = 0; i < numColorComponents; i++) {
0719:                            doublePixel[i] = (double) norm[i];
0720:                        }
0721:                        if (hasAlpha) {
0722:                            int alpha = (rgb >> 24) & 0xff;
0723:                            doublePixel[numColorComponents] = alpha * inv255;
0724:                        }
0725:                    }
0726:
0727:                    return doublePixel;
0728:                }
0729:            }
0730:
0731:            /**
0732:             * Throws an <code>IllegalArgumentException</code>, since pixel
0733:             * values for this <code>ColorModel</code> are not conveniently
0734:             * representable as a single <code>int</code>.
0735:             */
0736:            public int[] getComponents(int pixel, int[] components, int offset) {
0737:                throw new IllegalArgumentException(JaiI18N
0738:                        .getString("FloatDoubleColorModel9"));
0739:            }
0740:
0741:            /**
0742:             * Throws an <code>IllegalArgumentException</code> since
0743:             * the pixel values cannot be placed into an <code>int</code> array.
0744:             */
0745:            public int[] getComponents(Object pixel, int[] components,
0746:                    int offset) {
0747:                throw new IllegalArgumentException(JaiI18N
0748:                        .getString("FloatDoubleColorModel9"));
0749:            }
0750:
0751:            /**
0752:             * Throws an <code>IllegalArgumentException</code>, since pixel
0753:             * values for this <code>ColorModel</code> are not conveniently
0754:             * representable as a single <code>int</code>.
0755:             */
0756:            public int getDataElement(int[] components, int offset) {
0757:                throw new IllegalArgumentException(JaiI18N
0758:                        .getString("FloatDoubleColorModel9"));
0759:            }
0760:
0761:            /**
0762:             * Returns a data element array representation of a pixel in this
0763:             * <code>ColorModel</code>, given an array of unnormalized
0764:             * color/alpha components. This array can then be passed to the
0765:             * <code>setDataElements</code> method of a
0766:             * <code>WritableRaster</code> object.
0767:             * 
0768:             * @param components An array of unnormalized color/alpha
0769:             * components.
0770:             * @param offset The integer offset into the
0771:             * <code>components</code> array.
0772:             * @param obj The object in which to store the data element array
0773:             * representation of the pixel. If <code>obj</code> variable is
0774:             * null, a new array is allocated.  If <code>obj</code> is not
0775:             * null, it must be a primitive array of type
0776:             * <code>transferType</code>. An
0777:             * <code>ArrayIndexOutOfBoundsException</code> is thrown if
0778:             * <code>obj</code> is not large enough to hold a pixel value for
0779:             * this <code>ColorModel</code>.
0780:             *
0781:             * @return The data element array representation of a pixel 
0782:             * in this <code>ColorModel</code>.
0783:             *
0784:             * @throws IllegalArgumentException If the components array
0785:             * is not large enough to hold all the color and alpha components
0786:             * (starting at offset).
0787:             * @throws ClassCastException If <code>obj</code> is not null and
0788:             * is not a primitive array of type <code>transferType</code>.
0789:             * @throws ArrayIndexOutOfBoundsException If <code>obj</code> is
0790:             * not large enough to hold a pixel value for this
0791:             * <code>ColorModel</code>.
0792:             */
0793:            public Object getDataElements(int[] components, int offset,
0794:                    Object obj) {
0795:                if ((components.length - offset) < numComponents) {
0796:                    throw new IllegalArgumentException(numComponents + " "
0797:                            + JaiI18N.getString("FloatDoubleColorModel10"));
0798:                }
0799:                if (transferType == DataBuffer.TYPE_FLOAT) {
0800:                    float[] pixel;
0801:                    if (obj == null) {
0802:                        pixel = new float[components.length];
0803:                    } else {
0804:                        pixel = (float[]) obj;
0805:                    }
0806:                    for (int i = 0; i < numComponents; i++) {
0807:                        pixel[i] = (float) (components[offset + i]);
0808:                    }
0809:
0810:                    return pixel;
0811:                } else {
0812:                    double[] pixel;
0813:                    if (obj == null) {
0814:                        pixel = new double[components.length];
0815:                    } else {
0816:                        pixel = (double[]) obj;
0817:                    }
0818:                    for (int i = 0; i < numComponents; i++) {
0819:                        pixel[i] = (double) (components[offset + i]);
0820:                    }
0821:
0822:                    return pixel;
0823:                }
0824:            }
0825:
0826:            /**
0827:             * Forces the <code>raster</code> data to match the state specified in the
0828:             * <code>isAlphaPremultiplied</code> variable, assuming the data 
0829:             * is currently correctly described by this <code>ColorModel</code>.  
0830:             * It may multiply or divide the color <code>raster</code> data by alpha, or 
0831:             * do nothing if the data is in the correct state.  If the data needs 
0832:             * to be coerced, this method also returns an instance of 
0833:             * <code>FloatDoubleColorModel</code> with
0834:             * the <code>isAlphaPremultiplied</code> flag set appropriately.
0835:             *
0836:             * @throws IllegalArgumentException if transfer type of
0837:             * <code>raster</code> is not the same as that of this
0838:             * <code>FloatDoubleColorModel</code>.
0839:             */
0840:            public ColorModel coerceData(WritableRaster raster,
0841:                    boolean isAlphaPremultiplied) {
0842:                if ((hasAlpha == false)
0843:                        || (this .isAlphaPremultiplied == isAlphaPremultiplied)) {
0844:                    // Nothing to do
0845:                    return this ;
0846:                }
0847:
0848:                int w = raster.getWidth();
0849:                int h = raster.getHeight();
0850:                int aIdx = raster.getNumBands() - 1;
0851:                int rminX = raster.getMinX();
0852:                int rY = raster.getMinY();
0853:                int rX;
0854:
0855:                if (raster.getTransferType() != transferType) {
0856:                    throw new IllegalArgumentException(JaiI18N
0857:                            .getString("FloatDoubleColorModel6"));
0858:                }
0859:
0860:                if (isAlphaPremultiplied) {
0861:                    switch (transferType) {
0862:                    case DataBuffer.TYPE_FLOAT: {
0863:                        float pixel[] = null;
0864:                        for (int y = 0; y < h; y++, rY++) {
0865:                            rX = rminX;
0866:                            for (int x = 0; x < w; x++, rX++) {
0867:                                pixel = (float[]) raster.getDataElements(rX,
0868:                                        rY, pixel);
0869:                                float fAlpha = pixel[aIdx];
0870:                                if (fAlpha != 0) {
0871:                                    for (int c = 0; c < aIdx; c++) {
0872:                                        pixel[c] *= fAlpha;
0873:                                    }
0874:                                    raster.setDataElements(rX, rY, pixel);
0875:                                }
0876:                            }
0877:                        }
0878:                    }
0879:                        break;
0880:
0881:                    case DataBuffer.TYPE_DOUBLE: {
0882:                        double pixel[] = null;
0883:                        for (int y = 0; y < h; y++, rY++) {
0884:                            rX = rminX;
0885:                            for (int x = 0; x < w; x++, rX++) {
0886:                                pixel = (double[]) raster.getDataElements(rX,
0887:                                        rY, pixel);
0888:                                double dAlpha = pixel[aIdx];
0889:                                if (dAlpha != 0) {
0890:                                    for (int c = 0; c < aIdx; c++) {
0891:                                        pixel[c] *= dAlpha;
0892:                                    }
0893:                                    raster.setDataElements(rX, rY, pixel);
0894:                                }
0895:                            }
0896:                        }
0897:                    }
0898:                        break;
0899:
0900:                    default:
0901:                        throw new RuntimeException(JaiI18N
0902:                                .getString("FloatDoubleColorModel0"));
0903:                    }
0904:
0905:                    if (isAlphaPremultiplied) {
0906:
0907:                    }
0908:                } else {
0909:                    // We are premultiplied and want to divide it out
0910:                    switch (transferType) {
0911:                    case DataBuffer.TYPE_FLOAT: {
0912:                        for (int y = 0; y < h; y++, rY++) {
0913:                            rX = rminX;
0914:                            for (int x = 0; x < w; x++, rX++) {
0915:                                float pixel[] = null;
0916:                                pixel = (float[]) raster.getDataElements(rX,
0917:                                        rY, pixel);
0918:                                float fAlpha = pixel[aIdx];
0919:                                if (fAlpha != 0) {
0920:                                    float invFAlpha = 1.0F / fAlpha;
0921:                                    for (int c = 0; c < aIdx; c++) {
0922:                                        pixel[c] *= invFAlpha;
0923:                                    }
0924:                                }
0925:                                raster.setDataElements(rX, rY, pixel);
0926:                            }
0927:                        }
0928:                    }
0929:                        break;
0930:
0931:                    case DataBuffer.TYPE_DOUBLE: {
0932:                        for (int y = 0; y < h; y++, rY++) {
0933:                            rX = rminX;
0934:                            for (int x = 0; x < w; x++, rX++) {
0935:                                double pixel[] = null;
0936:                                pixel = (double[]) raster.getDataElements(rX,
0937:                                        rY, pixel);
0938:                                double dAlpha = pixel[aIdx];
0939:                                if (dAlpha != 0) {
0940:                                    double invDAlpha = 1.0 / dAlpha;
0941:                                    for (int c = 0; c < aIdx; c++) {
0942:                                        pixel[c] *= invDAlpha;
0943:                                    }
0944:                                }
0945:                                raster.setDataElements(rX, rY, pixel);
0946:                            }
0947:                        }
0948:                    }
0949:                        break;
0950:
0951:                    default:
0952:                        throw new RuntimeException(JaiI18N
0953:                                .getString("FloatDoubleColorModel0"));
0954:                    }
0955:                }
0956:
0957:                // Return a new color model
0958:                return new FloatDoubleColorModel(colorSpace, hasAlpha,
0959:                        isAlphaPremultiplied, transparency, transferType);
0960:            }
0961:
0962:            /**
0963:             * Returns <code>true</code> if the supplied <code>Raster</code>'s
0964:             * <code>SampleModel</code> is compatible with this
0965:             * <code>FloatDoubleColorModel</code>.
0966:             *
0967:             * @param raster a <code>Raster</code>to be checked for compatibility.
0968:             */
0969:            public boolean isCompatibleRaster(Raster raster) {
0970:                SampleModel sm = raster.getSampleModel();
0971:                return isCompatibleSampleModel(sm);
0972:            }
0973:
0974:            /**
0975:             * Creates a <code>WritableRaster</code> with the specified width
0976:             * and height, that has a data layout (<code>SampleModel</code>)
0977:             * compatible with this <code>ColorModel</code>.  The returned
0978:             * <code>WritableRaster</code>'s <code>SampleModel</code> will be
0979:             * an instance of <code>ComponentSampleModel</code>.
0980:             *
0981:             * @param w The width of the <code>WritableRaster</code>
0982:             * @param h The height of the <code>WritableRaster</code> 
0983:             *
0984:             * @return A <code>WritableRaster</code> that is compatible with
0985:             * this <code>ColorModel</code>.
0986:             *
0987:             * @see java.awt.image.WritableRaster
0988:             * @see java.awt.image.SampleModel
0989:             */
0990:            public WritableRaster createCompatibleWritableRaster(int w, int h) {
0991:                SampleModel sm = createCompatibleSampleModel(w, h);
0992:                return RasterFactory.createWritableRaster(sm, new Point(0, 0));
0993:            }
0994:
0995:            /**
0996:             * Creates a <code>SampleModel</code> with the specified width and
0997:             * height that has a data layout compatible with this
0998:             * <code>ColorModel</code>.  The returned <code>SampleModel</code>
0999:             * will be an instance of <code>ComponentSampleModel</code>.
1000:             *
1001:             * @param w The width of the <code>SampleModel</code>.
1002:             * @param h The height of the <code>SampleModel</code>.
1003:             *
1004:             * @return A <code>SampleModel</code> that is compatible with this
1005:             * <code>ColorModel</code>.
1006:             *
1007:             * @see java.awt.image.SampleModel	 
1008:             * @see java.awt.image.ComponentSampleModel	 
1009:             */
1010:            public SampleModel createCompatibleSampleModel(int w, int h) {
1011:                int[] bandOffsets = new int[numComponents];
1012:                for (int i = 0; i < numComponents; i++) {
1013:                    bandOffsets[i] = i;
1014:                }
1015:                return new ComponentSampleModelJAI(transferType, w, h,
1016:                        numComponents, w * numComponents, bandOffsets);
1017:            }
1018:
1019:            /** 
1020:             * Checks whether or not the specified <code>SampleModel</code> is
1021:             * compatible with this <code>ColorModel</code>.  A
1022:             * <code>SampleModel</code> is compatible if it is an instance of
1023:             * <code>ComponentSampleModel</code>, has the sample number of
1024:             * bands as the total number of components (including alpha) in
1025:             * the <code>ColorSpace</code> used by this
1026:             * <code>ColorModel</code>, and has the same data type (float or
1027:             * double) as this <code>ColorModel</code>.
1028:             *
1029:             * @param sm The <code>SampleModel</code> to test for compatibility.
1030:             *
1031:             * @return <code>true</code> if the <code>SampleModel</code> is
1032:             * compatible with this <code>ColorModel</code>,
1033:             * <code>false</code> if it is not.
1034:             *
1035:             * @see java.awt.image.SampleModel
1036:             * @see java.awt.image.ComponentSampleModel
1037:             */
1038:            public boolean isCompatibleSampleModel(SampleModel sm) {
1039:                if (sm instanceof  ComponentSampleModel) {
1040:                    if (sm.getNumBands() != getNumComponents()) {
1041:                        return false;
1042:                    }
1043:                    if (sm.getDataType() != transferType) {
1044:                        return false;
1045:                    }
1046:                    return true;
1047:                } else {
1048:                    return false;
1049:                }
1050:            }
1051:
1052:            /** Returns a <code>String</code> containing the values of all valid fields. */
1053:            public String toString() {
1054:                return "FloatDoubleColorModel: " + super.toString();
1055:            }
1056:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.