Source Code Cross Referenced for MediaLibAccessor.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » jai » mlib » 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 » com.sun.media.jai.mlib 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: MediaLibAccessor.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/23 21:08:28 $
0010:         * $State: Exp $
0011:         */
0012:        package com.sun.media.jai.mlib;
0013:
0014:        import java.awt.Rectangle;
0015:        import java.awt.image.ColorModel;
0016:        import java.awt.image.ComponentSampleModel;
0017:        import java.awt.image.ComponentColorModel;
0018:        import java.awt.image.DataBuffer;
0019:        import java.awt.image.DataBufferByte;
0020:        import java.awt.image.DataBufferShort;
0021:        import java.awt.image.DataBufferInt;
0022:        import java.awt.image.DataBufferUShort;
0023:        import java.awt.image.Raster;
0024:        import java.awt.image.SampleModel;
0025:        import java.awt.image.WritableRaster;
0026:        import java.awt.image.RenderedImage;
0027:        import java.awt.image.renderable.ParameterBlock;
0028:        import java.io.FileNotFoundException;
0029:        import java.io.FilePermission;
0030:        import java.io.InputStream;
0031:        import java.io.IOException;
0032:        import java.lang.NoClassDefFoundError;
0033:        import java.security.AccessControlException;
0034:        import java.security.AccessController;
0035:        import java.security.PrivilegedAction;
0036:        import javax.media.jai.ImageLayout;
0037:        import javax.media.jai.JAI;
0038:        import javax.media.jai.RasterAccessor;
0039:        import javax.media.jai.util.ImagingListener;
0040:        import com.sun.media.jai.util.DataBufferUtils;
0041:        import com.sun.media.jai.util.ImageUtil;
0042:        import com.sun.media.jai.util.PropertyUtil;
0043:        import com.sun.medialib.mlib.*;
0044:
0045:        /**
0046:         *  An adapter class for presenting image data in a mediaLibImage
0047:         *  format, even if the data isn't stored that way.  MediaLibAccessor
0048:         *  is meant to make the common case (ComponentRasters) and allow
0049:         *  them to be accelerated via medialib.  Note that unlike RasterAccessor,
0050:         *  MediaLibAccessor does not work with all cases.  In the event that
0051:         *  MediaLibAccessor can not deal with a give collection of Rasters,
0052:         *  findCompatibleTag will return the value MediaLibAccessor.TAG_INCOMPATIBLE.
0053:         *  OpImages that use MediaLibAccessor should be paired with RIF's
0054:         *  which check that findCompatibleTag returns a valid tag before
0055:         *  actually constructing the Mlib OpImage.
0056:         *
0057:         */
0058:
0059:        public class MediaLibAccessor {
0060:            /**
0061:             *  Value indicating how far COPY_MASK info is shifted to avoid
0062:             *  interfering with the data type info
0063:             */
0064:            private static final int COPY_MASK_SHIFT = 7;
0065:
0066:            /* Value indicating how many bits the COPY_MASK is */
0067:            private static final int COPY_MASK_SIZE = 1;
0068:
0069:            /** The bits of a FormatTag associated with how dataArrays are obtained. */
0070:            public static final int COPY_MASK = 0x1 << COPY_MASK_SHIFT;
0071:
0072:            /** Flag indicating data is raster's data. */
0073:            public static final int UNCOPIED = 0x0 << COPY_MASK_SHIFT;
0074:
0075:            /** Flag indicating data is a copy of the raster's data. */
0076:            public static final int COPIED = 0x01 << COPY_MASK_SHIFT;
0077:
0078:            /** The bits of a FormatTag associated with pixel datatype. */
0079:            public static final int DATATYPE_MASK = (0x1 << COPY_MASK_SHIFT) - 1;
0080:
0081:            /**
0082:             * Value indicating how far BINARY_MASK info is shifted to avoid
0083:             * interfering with the data type and copying info.
0084:             */
0085:            private static final int BINARY_MASK_SHIFT = COPY_MASK_SHIFT
0086:                    + COPY_MASK_SIZE;
0087:
0088:            /** Value indicating how many bits the BINARY_MASK is */
0089:            private static final int BINARY_MASK_SIZE = 1;
0090:
0091:            /** The bits of a FormatTag associated with binary data. */
0092:            public static final int BINARY_MASK = ((1 << BINARY_MASK_SIZE) - 1) << BINARY_MASK_SHIFT;
0093:
0094:            /** Flag indicating data are not binary. */
0095:            public static final int NONBINARY = 0x0 << BINARY_MASK_SHIFT;
0096:
0097:            /** Flag indicating data are binary. */
0098:            public static final int BINARY = 0x1 << BINARY_MASK_SHIFT;
0099:
0100:            /** FormatTag indicating data in byte arrays and uncopied. */
0101:            public static final int TAG_BYTE_UNCOPIED = DataBuffer.TYPE_BYTE
0102:                    | UNCOPIED;
0103:
0104:            /** FormatTag indicating data in unsigned short arrays and uncopied. */
0105:            public static final int TAG_USHORT_UNCOPIED = DataBuffer.TYPE_USHORT
0106:                    | UNCOPIED;
0107:
0108:            /** FormatTag indicating data in short arrays and uncopied. */
0109:            public static final int TAG_SHORT_UNCOPIED = DataBuffer.TYPE_SHORT
0110:                    | UNCOPIED;
0111:
0112:            /** FormatTag indicating data in integer arrays and uncopied. */
0113:            public static final int TAG_INT_UNCOPIED = DataBuffer.TYPE_INT
0114:                    | UNCOPIED;
0115:
0116:            /** FormatTag indicating data in float arrays and uncopied. */
0117:            public static final int TAG_FLOAT_UNCOPIED = DataBuffer.TYPE_FLOAT
0118:                    | UNCOPIED;
0119:
0120:            /** FormatTag indicating data in double arrays and uncopied. */
0121:            public static final int TAG_DOUBLE_UNCOPIED = DataBuffer.TYPE_DOUBLE
0122:                    | UNCOPIED;
0123:
0124:            /** FormatTag indicating data in byte arrays and uncopied. */
0125:            public static final int TAG_BYTE_COPIED = DataBuffer.TYPE_BYTE
0126:                    | COPIED;
0127:
0128:            /** FormatTag indicating data in unsigned short arrays and copied. */
0129:            public static final int TAG_USHORT_COPIED = DataBuffer.TYPE_USHORT
0130:                    | COPIED;
0131:
0132:            /** FormatTag indicating data in short arrays and copied. */
0133:            public static final int TAG_SHORT_COPIED = DataBuffer.TYPE_SHORT
0134:                    | COPIED;
0135:
0136:            /** FormatTag indicating data in short arrays and copied. */
0137:            public static final int TAG_INT_COPIED = DataBuffer.TYPE_INT
0138:                    | COPIED;
0139:
0140:            /** FormatTag indicating data in float arrays and copied. */
0141:            public static final int TAG_FLOAT_COPIED = DataBuffer.TYPE_FLOAT
0142:                    | COPIED;
0143:
0144:            /** FormatTag indicating data in double arrays and copied. */
0145:            public static final int TAG_DOUBLE_COPIED = DataBuffer.TYPE_DOUBLE
0146:                    | COPIED;
0147:
0148:            /** The raster that is the source of pixel data. */
0149:            protected Raster raster;
0150:
0151:            /** The rectangle of the raster that MediaLibAccessor addresses. */
0152:            protected Rectangle rect;
0153:
0154:            /** The number of bands per pixel in the data array. */
0155:            protected int numBands;
0156:
0157:            /** The offsets of each band in the src image */
0158:            protected int bandOffsets[];
0159:
0160:            /** Tag indicating the data type of the data and whether its copied */
0161:            protected int formatTag;
0162:
0163:            /** Area of mediaLib images that represent image data */
0164:            protected mediaLibImage mlimages[] = null;
0165:
0166:            /**
0167:             * Whether packed data are preferred when processing binary images.
0168:             * This tag is ignored if the data are not binary.
0169:             */
0170:            private boolean areBinaryDataPacked = false;
0171:
0172:            private static boolean useMlibVar = false;
0173:            private static boolean useMlibVarSet = false;
0174:
0175:            private static synchronized boolean useMlib() {
0176:                if (!useMlibVarSet) {
0177:                    setUseMlib();
0178:                    useMlibVarSet = true;
0179:                }
0180:
0181:                return useMlibVar;
0182:            }
0183:
0184:            private static void setUseMlib() {
0185:
0186:                // Fix of 4726600: Disable medialib before the searching of 
0187:                // medialib library if the property is set.
0188:                boolean disableMediaLib = false;
0189:                try {
0190:                    disableMediaLib = Boolean
0191:                            .getBoolean("com.sun.media.jai.disableMediaLib");
0192:                } catch (java.security.AccessControlException e) {
0193:                    // Because the property com.sun.media.jai.disableMediaLib isn't
0194:                    // defined as public, the users shouldn't know it.  In most of
0195:                    // the cases, it isn't defined, and thus no access permission
0196:                    // is granted to it in the policy file.  When JAI is utilized in
0197:                    // a security environment, AccessControlException will be thrown.
0198:                    // In this case, we suppose that the users would like to use
0199:                    // medialib accelaration.  So, the medialib won't be disabled.
0200:
0201:                    // The fix of 4531501
0202:                }
0203:
0204:                // If mediaLib usage has been explicity disabled.
0205:                if (disableMediaLib) {
0206:                    useMlibVar = false;
0207:                    return;
0208:                }
0209:
0210:                try {
0211:
0212:                    SecurityManager securityManager = System
0213:                            .getSecurityManager();
0214:
0215:                    if (securityManager != null
0216:                            && MediaLibAccessor.class.getClassLoader() != null) {
0217:
0218:                        // a non-null security manager means we're in an applet
0219:                        // if this.classLoader == null, we're an installed extension
0220:                        // and the doPrivleged block should be ok.
0221:
0222:                        // native code doesn't currently load on Wintel regardless
0223:                        // of where the dll's are even if this code is removed.
0224:                        // At some point we'll need to come up with a better
0225:                        // solution.  For now this is a good work around because
0226:                        // on Sparc it will cause
0227:                        // a SecurityException to be thrown instead of an
0228:                        // ExceptionInInitializerError in the doPriviliged block
0229:                        // which can't be caught.
0230:                        // If MediaLib is rewritten so that the Exception is thrown
0231:                        // after the class is loaded this chunk of code can be
0232:                        // removed.
0233:                        String osName = System.getProperty("os.name");
0234:                        String osArch = System.getProperty("os.arch");
0235:
0236:                        // The fix of 4531469
0237:                        if ((osName.equals("Solaris") || osName.equals("SunOS"))
0238:                                && osArch.equals("sparc")) {
0239:                            FilePermission fp = new FilePermission(
0240:                                    "/usr/bin/uname", "execute");
0241:                            securityManager.checkPermission(fp);
0242:                        }
0243:                    }
0244:
0245:                    Boolean result = (Boolean) AccessController
0246:                            .doPrivileged(new PrivilegedAction() {
0247:                                public Object run() {
0248:                                    return new Boolean(Image.isAvailable());
0249:                                }
0250:                            });
0251:                    useMlibVar = result.booleanValue();
0252:                    if (!useMlibVar) {
0253:                        forwardToListener(JaiI18N
0254:                                .getString("MediaLibAccessor2"),
0255:                                new MediaLibLoadException());
0256:                    }
0257:                } catch (NoClassDefFoundError ncdfe) {
0258:                    // If mediaLib jar file is not found, fall back to Java code.
0259:                    useMlibVar = false;
0260:                    forwardToListener(JaiI18N.getString("MediaLibAccessor3"),
0261:                            ncdfe);
0262:                } catch (ClassFormatError cfe) {
0263:                    // If mediaLib jar file is not found, fall back to Java code.
0264:                    useMlibVar = false;
0265:                    forwardToListener(JaiI18N.getString("MediaLibAccessor3"),
0266:                            cfe);
0267:                } catch (SecurityException se) {
0268:                    // If mediaLib jar file is not found, fall back to Java code.
0269:                    useMlibVar = false;
0270:                    forwardToListener(JaiI18N.getString("MediaLibAccessor4"),
0271:                            se);
0272:                }
0273:
0274:                if (useMlibVar == false)
0275:                    return;
0276:            }
0277:
0278:            /**
0279:             * Forwards the supplied message and exception to the
0280:             * <code>ImagingListener</code> set on the default JAI instance.
0281:             * If none is set (which should not happen) the message is simply
0282:             * printed to <code>System.err</code>.
0283:             */
0284:            private static void forwardToListener(String message,
0285:                    Throwable thrown) {
0286:                ImagingListener listener = JAI.getDefaultInstance()
0287:                        .getImagingListener();
0288:
0289:                if (listener != null) {
0290:                    listener.errorOccurred(message, thrown,
0291:                            MediaLibAccessor.class, false);
0292:                } else {
0293:                    System.err.println(message);
0294:                }
0295:            }
0296:
0297:            /**
0298:             * Returns <code>true</code> if mediaLib is able to handle the
0299:             * source(s) and destination image format.  Currently, all of the
0300:             * following conditions must be met in order for this method to
0301:             * return <code>true</code>.
0302:             * <ul>
0303:             * <li>MediaLib is available.</li>
0304:             * <li>All sources must be <code>RenderedImage</code>.</li>
0305:             * <li>All sources and destination must have
0306:             *     <code>ComponentSampleModel</code> and
0307:             *     <code>ComponentColorModel</code>.</li>
0308:             * <li>All sources and destination must have less than or equal
0309:             *     to 4 bands of pixel data.</li>
0310:             * </ul>
0311:             * Additional checks for each individual <code>OpImage</code>
0312:             * should be done in its corresponding <code>RIF</code>.
0313:             *
0314:             * @param args  Input arguments that include sources.
0315:             * @param layout  Destination image layout; may be <code>null</code>.
0316:             */
0317:            public static boolean isMediaLibCompatible(ParameterBlock args,
0318:                    ImageLayout layout) {
0319:                if (!isMediaLibCompatible(args)) {
0320:                    // sources not supported
0321:                    return false;
0322:                }
0323:
0324:                if (layout != null) { // validate destination
0325:                    SampleModel sm = layout.getSampleModel(null);
0326:                    if (sm != null) {
0327:                        if (!(sm instanceof  ComponentSampleModel)
0328:                                || sm.getNumBands() > 4) {
0329:                            return false;
0330:                        }
0331:                    }
0332:
0333:                    ColorModel cm = layout.getColorModel(null);
0334:                    if (cm != null && (!(cm instanceof  ComponentColorModel))) {
0335:                        return false;
0336:                    }
0337:                }
0338:
0339:                return true;
0340:            }
0341:
0342:            /**
0343:             * Returns <code>true</code> if mediaLib is able to handle the
0344:             * source(s) image format.  Currently, all of the following
0345:             * conditions must be met in order for this method to return
0346:             * <code>true</code>.
0347:             * <ul>
0348:             * <li>MediaLib is available.</li>
0349:             * <li>All sources must be <code>RenderedImage</code>.</li>
0350:             * <li>All sources must have <code>ComponentSampleModel</code> and
0351:             *     <code>ComponentColorModel</code>.</li>
0352:             * <li>All sources must have less than or equal to 4 bands of pixel
0353:             *     data.</li>
0354:             * </ul>
0355:             * Additional checks for each individual <code>OpImage</code>
0356:             * should be done in its corresponding <code>RIF</code>.
0357:             *
0358:             * @param args  Input arguments that include sources.
0359:             */
0360:            public static boolean isMediaLibCompatible(ParameterBlock args) {
0361:                if (!useMlib()) { // mediaLib is not available
0362:                    return false;
0363:                }
0364:
0365:                int numSrcs = args.getNumSources();
0366:                for (int i = 0; i < numSrcs; i++) {
0367:                    Object src = args.getSource(i);
0368:                    if (!(src instanceof  RenderedImage)
0369:                            || !isMediaLibCompatible((RenderedImage) src)) {
0370:                        return false;
0371:                    }
0372:                }
0373:
0374:                return true;
0375:            }
0376:
0377:            /**
0378:             * Returns <code>true</code> if mediaLib is able to handle the
0379:             * image.  Currently, all of the following conditions must be
0380:             * met in order for this method to return <code>true</code>.
0381:             * <ul>
0382:             * <li>MediaLib is available.</li>
0383:             * <li>The image must have <code>ComponentSampleModel</code> and
0384:             *     <code>ComponentColorModel</code>.</li>
0385:             * <li>The image must have less than or equal to 4 bands of pixel
0386:             *     data.</li>
0387:             * </ul>
0388:             * Additional checks for each individual <code>OpImage</code>
0389:             * should be done in its corresponding <code>RIF</code>.
0390:             *
0391:             * @param image The image the compatibility of which is to be checked.
0392:             */
0393:            public static boolean isMediaLibCompatible(RenderedImage image) {
0394:                if (!useMlib()) { // mediaLib is not available
0395:                    return false;
0396:                }
0397:
0398:                SampleModel sm = image.getSampleModel();
0399:                ColorModel cm = image.getColorModel();
0400:
0401:                return (sm instanceof  ComponentSampleModel
0402:                        && sm.getNumBands() <= 4 && (cm == null || cm instanceof  ComponentColorModel));
0403:            }
0404:
0405:            /**
0406:             * Returns <code>true</code> if mediaLib is able to handle
0407:             * an image having the supplied <code>SampleModel</code> and
0408:             * <code>ColorModel</code>.  Currently, all of the following conditions
0409:             * must be met in order for this method to return <code>true</code>:
0410:             * <ul>
0411:             * <li>mediaLib is available.</li>
0412:             * <li>The <code>SampleModel</code> is an instance of
0413:             * <code>ComponentSampleModel</code> or one of its subclasses.</li>
0414:             * <li>The <code>ColorModel</code> is <code>null</code> or an
0415:             * instance of <code>ComponentColorModel</code> or a subclass thereof.</li>
0416:             * <li>The image must have no more than 4 bands of pixel data.</li>
0417:             * </ul>
0418:             *
0419:             * @param sm The image <code>SampleModel</code>.
0420:             * @param cm The image <code>ColorModel</code>.
0421:             *
0422:             * @throws NullPointerException if <code>sm</code> is <code>null</code>.
0423:             */
0424:            public static boolean isMediaLibCompatible(SampleModel sm,
0425:                    ColorModel cm) {
0426:                if (!useMlib()) { // mediaLib is not available
0427:                    return false;
0428:                }
0429:
0430:                return (sm instanceof  ComponentSampleModel
0431:                        && sm.getNumBands() <= 4 && (cm == null || cm instanceof  ComponentColorModel));
0432:            }
0433:
0434:            /**
0435:             * Returns <code>true</code> if mediaLib is able to handle the
0436:             * source(s) and destination image format as binary (also known
0437:             * as bit or bilevel) image data.  Currently, all of the
0438:             * following conditions must be met in order for this method to
0439:             * return <code>true</code>.
0440:             * <ul>
0441:             * <li>MediaLib is available.</li>
0442:             * <li>All sources must be <code>RenderedImage</code>s.</li>
0443:             * <li>All sources and destination must have a
0444:             *     <code>MultiPixelPackedSampleModel</code>.</li>
0445:             * <li>All sources and destination must have represent
0446:             *     single-bit data.</li>
0447:             * <li>All sources and destination must have
0448:             *     a single band of pixel data.</li>
0449:             * </ul>
0450:             * Additional checks for each individual <code>OpImage</code>
0451:             * should be done in its corresponding <code>RIF</code>.
0452:             *
0453:             * @param args  Input arguments that include sources.
0454:             * @param layout  Destination image layout; may be <code>null</code>.
0455:             */
0456:            public static boolean isMediaLibBinaryCompatible(
0457:                    ParameterBlock args, ImageLayout layout) {
0458:                if (!useMlib()) { // mediaLib is not available
0459:                    return false;
0460:                }
0461:
0462:                SampleModel sm = null;
0463:
0464:                int numSrcs = args.getNumSources();
0465:                for (int i = 0; i < numSrcs; i++) { // sources not supported
0466:                    Object src = args.getSource(i);
0467:                    if (!(src instanceof  RenderedImage)
0468:                            || (sm = ((RenderedImage) src).getSampleModel()) == null
0469:                            || !ImageUtil.isBinary(sm)) {
0470:                        return false;
0471:                    }
0472:                }
0473:
0474:                if (layout != null) { // validate destination
0475:                    if ((sm = layout.getSampleModel(null)) != null
0476:                            && !ImageUtil.isBinary(sm)) {
0477:                        return false;
0478:                    }
0479:                }
0480:
0481:                return true;
0482:            }
0483:
0484:            /**
0485:             * Returns <code>true</code> if the number of bands of all the
0486:             * <code>RenderedImage</code> sources and destination are the same.
0487:             *
0488:             * @throws ClassCastException  if any source is not
0489:             *         <code>RenderedImage</code>.
0490:             */
0491:            public static boolean hasSameNumBands(ParameterBlock args,
0492:                    ImageLayout layout) {
0493:                int numSrcs = args.getNumSources();
0494:
0495:                if (numSrcs > 0) {
0496:                    RenderedImage src = args.getRenderedSource(0);
0497:                    int numBands = src.getSampleModel().getNumBands();
0498:
0499:                    for (int i = 1; i < numSrcs; i++) {
0500:                        src = args.getRenderedSource(i);
0501:                        if (src.getSampleModel().getNumBands() != numBands) {
0502:                            return false;
0503:                        }
0504:                    }
0505:
0506:                    if (layout != null) {
0507:                        SampleModel sm = layout.getSampleModel(null);
0508:                        if (sm != null && sm.getNumBands() != numBands) {
0509:                            return false;
0510:                        }
0511:                    }
0512:                }
0513:
0514:                return true;
0515:            }
0516:
0517:            /**
0518:             *  Returns the most efficient FormatTag that is compatible with
0519:             *  the destination raster and all source rasters.
0520:             *
0521:             *  @param srcs the source <code>Raster</code>; may be <code>null</code>.
0522:             *  @param dst  the destination <code>Raster</code>.
0523:             */
0524:            public static int findCompatibleTag(Raster srcs[], Raster dst) {
0525:                SampleModel dstSM = dst.getSampleModel();
0526:                int dstDT = dstSM.getDataType();
0527:
0528:                int defaultDataType = dstSM.getDataType();
0529:
0530:                boolean allComponentSampleModel = dstSM instanceof  ComponentSampleModel;
0531:                boolean allBinary = ImageUtil.isBinary(dstSM);
0532:
0533:                // use highest precision datatype of all srcs & dst
0534:                if (srcs != null) {
0535:                    int numSources = srcs.length;
0536:                    int i;
0537:                    for (i = 0; i < numSources; i++) {
0538:                        SampleModel srcSampleModel = srcs[i].getSampleModel();
0539:                        if (!(srcSampleModel instanceof  ComponentSampleModel)) {
0540:                            allComponentSampleModel = false;
0541:                        }
0542:                        if (!ImageUtil.isBinary(srcSampleModel)) {
0543:                            allBinary = false;
0544:                        }
0545:                        int srcDataType = srcSampleModel.getTransferType();
0546:                        if (srcDataType > defaultDataType) {
0547:                            defaultDataType = srcDataType;
0548:                        }
0549:                    }
0550:                }
0551:
0552:                if (allBinary) {
0553:                    // The copy flag is not set until the mediaLibImage is
0554:                    // created as knowing this information requires too much
0555:                    // processing to determine here.
0556:                    return DataBuffer.TYPE_BYTE | BINARY;
0557:                }
0558:
0559:                if (!allComponentSampleModel) {
0560:                    if ((defaultDataType == DataBuffer.TYPE_BYTE)
0561:                            || (defaultDataType == DataBuffer.TYPE_USHORT)
0562:                            || (defaultDataType == DataBuffer.TYPE_SHORT)) {
0563:                        defaultDataType = DataBuffer.TYPE_INT;
0564:                    }
0565:                }
0566:
0567:                int tag = defaultDataType | COPIED;
0568:
0569:                if (!allComponentSampleModel) {
0570:                    return tag;
0571:                }
0572:
0573:                //  see if they all have same DT and are pixelSequential
0574:
0575:                SampleModel srcSM[];
0576:                if (srcs == null) {
0577:                    srcSM = new SampleModel[0];
0578:                } else {
0579:                    srcSM = new SampleModel[srcs.length];
0580:                }
0581:                for (int i = 0; i < srcSM.length; i++) {
0582:                    srcSM[i] = srcs[i].getSampleModel();
0583:                    if (dstDT != srcSM[i].getDataType()) {
0584:                        return tag;
0585:                    }
0586:                }
0587:                if (isPixelSequential(dstSM)) {
0588:                    for (int i = 0; i < srcSM.length; i++) {
0589:                        if (!isPixelSequential(srcSM[i])) {
0590:                            return tag;
0591:                        }
0592:                    }
0593:                    for (int i = 0; i < srcSM.length; i++) {
0594:                        if (!hasMatchingBandOffsets(
0595:                                (ComponentSampleModel) dstSM,
0596:                                (ComponentSampleModel) srcSM[i])) {
0597:                            return tag;
0598:                        }
0599:                    }
0600:                    return dstDT | UNCOPIED;
0601:                }
0602:                return tag;
0603:            }
0604:
0605:            /**
0606:             *  Determines if the SampleModel stores data in a way that can
0607:             *  be represented by a mediaLibImage without copying
0608:             */
0609:            public static boolean isPixelSequential(SampleModel sm) {
0610:                ComponentSampleModel csm = null;
0611:                if (sm instanceof  ComponentSampleModel) {
0612:                    csm = (ComponentSampleModel) sm;
0613:                } else {
0614:                    return false;
0615:                }
0616:                int pixelStride = csm.getPixelStride();
0617:                int bandOffsets[] = csm.getBandOffsets();
0618:                int bankIndices[] = csm.getBankIndices();
0619:                if (pixelStride != bandOffsets.length) {
0620:                    return false;
0621:                }
0622:                for (int i = 0; i < bandOffsets.length; i++) {
0623:                    if (bandOffsets[i] >= pixelStride
0624:                            || bankIndices[i] != bankIndices[0]) {
0625:                        return false;
0626:                    }
0627:                    for (int j = i + 1; j < bandOffsets.length; j++) {
0628:                        if (bandOffsets[i] == bandOffsets[j]) {
0629:                            return false;
0630:                        }
0631:                    }
0632:                }
0633:                return true;
0634:            }
0635:
0636:            /**
0637:             *  Determines if the src ComponentSampleModel and dst
0638:             *  ComponentSampleModel have matching band offsets.  If they
0639:             *  don't mediaLib can't deal with the image without a copy.
0640:             */
0641:            public static boolean hasMatchingBandOffsets(
0642:                    ComponentSampleModel dst, ComponentSampleModel src) {
0643:                int srcBandOffsets[] = dst.getBandOffsets();
0644:                int dstBandOffsets[] = src.getBandOffsets();
0645:                if (srcBandOffsets.length != dstBandOffsets.length) {
0646:                    return false;
0647:                }
0648:                for (int i = 0; i < srcBandOffsets.length; i++) {
0649:                    if (srcBandOffsets[i] != dstBandOffsets[i]) {
0650:                        return false;
0651:                    }
0652:                }
0653:                return true;
0654:            }
0655:
0656:            public static int getMediaLibDataType(int formatTag) {
0657:                int dataType = formatTag & DATATYPE_MASK;
0658:                switch (dataType) {
0659:                case DataBuffer.TYPE_BYTE:
0660:                    return Constants.MLIB_BYTE;
0661:                case DataBuffer.TYPE_USHORT:
0662:                    return Constants.MLIB_USHORT;
0663:                case DataBuffer.TYPE_SHORT:
0664:                    return Constants.MLIB_SHORT;
0665:                case DataBuffer.TYPE_INT:
0666:                    return Constants.MLIB_INT;
0667:                case DataBuffer.TYPE_DOUBLE:
0668:                    return Constants.MLIB_DOUBLE;
0669:                case DataBuffer.TYPE_FLOAT:
0670:                    return Constants.MLIB_FLOAT;
0671:                }
0672:                return -1;
0673:            }
0674:
0675:            /**
0676:             *  Constructs a MediaLibAccessor object out of a Raster, Rectangle
0677:             *  and formatTag returned from MediaLibAccessor.findCompatibleTag().
0678:             *
0679:             *  In the case of binary data the copy mask bits of the formatTag
0680:             *  will be reset within the constructor according to whether the
0681:             *  data are in fact copied. This cannot be easily determined before
0682:             *  the data are actually copied.
0683:             */
0684:            public MediaLibAccessor(Raster raster, Rectangle rect,
0685:                    int formatTag, boolean preferPacked) {
0686:                areBinaryDataPacked = preferPacked;
0687:
0688:                this .raster = raster;
0689:                this .rect = new Rectangle(rect);
0690:                this .formatTag = formatTag;
0691:
0692:                if (isBinary()) {
0693:                    // Set binary-specific fields and return.
0694:                    numBands = 1;
0695:                    bandOffsets = new int[] { 0 };
0696:
0697:                    int mlibType;
0698:                    int scanlineStride;
0699:                    byte[] bdata;
0700:                    mlimages = new mediaLibImage[1];
0701:
0702:                    if (areBinaryDataPacked) {
0703:                        mlibType = Constants.MLIB_BIT;
0704:                        scanlineStride = (rect.width + 7) / 8;
0705:                        bdata = ImageUtil.getPackedBinaryData(raster, rect);
0706:
0707:                        // Update format tag depending on whether the data were copied.
0708:                        if (bdata == ((DataBufferByte) raster.getDataBuffer())
0709:                                .getData()) {
0710:                            this .formatTag |= UNCOPIED;
0711:                        } else {
0712:                            this .formatTag |= COPIED;
0713:                        }
0714:                    } else { // unpacked
0715:                        mlibType = Constants.MLIB_BYTE;
0716:                        scanlineStride = rect.width;
0717:                        bdata = ImageUtil.getUnpackedBinaryData(raster, rect);
0718:                        this .formatTag |= COPIED;
0719:                    }
0720:
0721:                    mlimages[0] = new mediaLibImage(mlibType, 1, rect.width,
0722:                            rect.height, scanlineStride, 0, bdata);
0723:
0724:                    return;
0725:                }
0726:
0727:                if ((formatTag & COPY_MASK) == UNCOPIED) {
0728:                    ComponentSampleModel csm = (ComponentSampleModel) raster
0729:                            .getSampleModel();
0730:
0731:                    numBands = csm.getNumBands();
0732:                    bandOffsets = csm.getBandOffsets();
0733:                    int dataOffset = raster.getDataBuffer().getOffset();
0734:                    dataOffset += (rect.y - raster.getSampleModelTranslateY())
0735:                            * csm.getScanlineStride()
0736:                            + (rect.x - raster.getSampleModelTranslateX())
0737:                            * csm.getPixelStride();
0738:
0739:                    // dataoffset should and is in terms of dataElements
0740:
0741:                    // scanline stride should be in terms of dataElements
0742:                    int scanlineStride = csm.getScanlineStride();
0743:
0744:                    switch (formatTag & DATATYPE_MASK) {
0745:                    case DataBuffer.TYPE_BYTE:
0746:                        DataBufferByte dbb = (DataBufferByte) raster
0747:                                .getDataBuffer();
0748:                        mlimages = new mediaLibImage[1];
0749:                        mlimages[0] = new mediaLibImage(Constants.MLIB_BYTE,
0750:                                numBands, rect.width, rect.height,
0751:                                scanlineStride, dataOffset, dbb.getData());
0752:                        break;
0753:
0754:                    case DataBuffer.TYPE_USHORT:
0755:                        DataBufferUShort dbus = (DataBufferUShort) raster
0756:                                .getDataBuffer();
0757:                        mlimages = new mediaLibImage[1];
0758:                        mlimages[0] = new mediaLibImage(Constants.MLIB_USHORT,
0759:                                numBands, rect.width, rect.height,
0760:                                scanlineStride, dataOffset, dbus.getData());
0761:                        break;
0762:                    case DataBuffer.TYPE_SHORT:
0763:                        DataBufferShort dbs = (DataBufferShort) raster
0764:                                .getDataBuffer();
0765:                        mlimages = new mediaLibImage[1];
0766:                        mlimages[0] = new mediaLibImage(Constants.MLIB_SHORT,
0767:                                numBands, rect.width, rect.height,
0768:                                scanlineStride, dataOffset, dbs.getData());
0769:                        break;
0770:                    case DataBuffer.TYPE_INT:
0771:                        DataBufferInt dbi = (DataBufferInt) raster
0772:                                .getDataBuffer();
0773:                        mlimages = new mediaLibImage[1];
0774:                        mlimages[0] = new mediaLibImage(Constants.MLIB_INT,
0775:                                numBands, rect.width, rect.height,
0776:                                scanlineStride, dataOffset, dbi.getData());
0777:                        break;
0778:                    case DataBuffer.TYPE_FLOAT:
0779:                        DataBuffer dbf = raster.getDataBuffer();
0780:                        mlimages = new mediaLibImage[1];
0781:                        mlimages[0] = new mediaLibImage(Constants.MLIB_FLOAT,
0782:                                numBands, rect.width, rect.height,
0783:                                scanlineStride, dataOffset, DataBufferUtils
0784:                                        .getDataFloat(dbf));
0785:                        break;
0786:                    case DataBuffer.TYPE_DOUBLE:
0787:                        DataBuffer dbd = raster.getDataBuffer();
0788:                        mlimages = new mediaLibImage[1];
0789:                        mlimages[0] = new mediaLibImage(Constants.MLIB_DOUBLE,
0790:                                numBands, rect.width, rect.height,
0791:                                scanlineStride, dataOffset, DataBufferUtils
0792:                                        .getDataDouble(dbd));
0793:                        break;
0794:                    default:
0795:                        throw new IllegalArgumentException(
0796:                                (formatTag & DATATYPE_MASK)
0797:                                        + JaiI18N
0798:                                                .getString("MediaLibAccessor1"));
0799:                    }
0800:                } else {
0801:                    // Copying the data because we can't deal with it
0802:                    numBands = raster.getNumBands();
0803:                    bandOffsets = new int[numBands];
0804:                    for (int i = 0; i < numBands; i++) {
0805:                        bandOffsets[i] = i;
0806:                    }
0807:                    int scanlineStride = rect.width * numBands;
0808:
0809:                    switch (formatTag & DATATYPE_MASK) {
0810:                    case DataBuffer.TYPE_BYTE:
0811:                        byte bdata[] = new byte[rect.width * rect.height
0812:                                * numBands];
0813:                        mlimages = new mediaLibImage[1];
0814:                        mlimages[0] = new mediaLibImage(Constants.MLIB_BYTE,
0815:                                numBands, rect.width, rect.height,
0816:                                scanlineStride, 0, bdata);
0817:                        break;
0818:                    case DataBuffer.TYPE_USHORT:
0819:                        short usdata[] = new short[rect.width * rect.height
0820:                                * numBands];
0821:                        mlimages = new mediaLibImage[1];
0822:                        mlimages[0] = new mediaLibImage(Constants.MLIB_USHORT,
0823:                                numBands, rect.width, rect.height,
0824:                                scanlineStride, 0, usdata);
0825:                        break;
0826:                    case DataBuffer.TYPE_SHORT:
0827:                        short sdata[] = new short[rect.width * rect.height
0828:                                * numBands];
0829:                        mlimages = new mediaLibImage[1];
0830:                        mlimages[0] = new mediaLibImage(Constants.MLIB_SHORT,
0831:                                numBands, rect.width, rect.height,
0832:                                scanlineStride, 0, sdata);
0833:                        break;
0834:                    case DataBuffer.TYPE_INT:
0835:                        int idata[] = new int[rect.width * rect.height
0836:                                * numBands];
0837:                        mlimages = new mediaLibImage[1];
0838:                        mlimages[0] = new mediaLibImage(Constants.MLIB_INT,
0839:                                numBands, rect.width, rect.height,
0840:                                scanlineStride, 0, idata);
0841:                        break;
0842:                    case DataBuffer.TYPE_FLOAT:
0843:                        float fdata[] = new float[rect.width * rect.height
0844:                                * numBands];
0845:                        mlimages = new mediaLibImage[1];
0846:                        mlimages[0] = new mediaLibImage(Constants.MLIB_FLOAT,
0847:                                numBands, rect.width, rect.height,
0848:                                scanlineStride, 0, fdata);
0849:                        break;
0850:                    case DataBuffer.TYPE_DOUBLE:
0851:                        double ddata[] = new double[rect.width * rect.height
0852:                                * numBands];
0853:                        mlimages = new mediaLibImage[1];
0854:                        mlimages[0] = new mediaLibImage(Constants.MLIB_DOUBLE,
0855:                                numBands, rect.width, rect.height,
0856:                                scanlineStride, 0, ddata);
0857:                        break;
0858:                    default:
0859:                        throw new IllegalArgumentException(
0860:                                (formatTag & DATATYPE_MASK)
0861:                                        + JaiI18N
0862:                                                .getString("MediaLibAccessor1"));
0863:                    }
0864:                    copyDataFromRaster();
0865:                }
0866:            }
0867:
0868:            /**
0869:             *  Constructs a MediaLibAccessor object out of a Raster, Rectangle
0870:             *  and formatTag returned from MediaLibAccessor.findCompatibleTag().
0871:             */
0872:            public MediaLibAccessor(Raster raster, Rectangle rect, int formatTag) {
0873:                this (raster, rect, formatTag, false);
0874:            }
0875:
0876:            /**
0877:             * Returns <code>true</code> if the <code>MediaLibAccessor</code>
0878:             * represents binary data.
0879:             */
0880:            public boolean isBinary() {
0881:                return ((formatTag & BINARY_MASK) == BINARY);
0882:            }
0883:
0884:            /**
0885:             *  Returns an array of mediaLibImages which represents the input raster.
0886:             *  An array is returned instead of a single mediaLibImage because
0887:             *  in some cases, an input Raster can't be represented by one
0888:             *  mediaLibImage (unless copying is done) but can be represented
0889:             *  by several mediaLibImages without copying.
0890:             */
0891:            public mediaLibImage[] getMediaLibImages() {
0892:                return mlimages;
0893:            }
0894:
0895:            /**
0896:             *  Returns the data type of the RasterAccessor object. Note that
0897:             *  this datatype is not necessarily the same data type as the
0898:             *  underlying raster.
0899:             */
0900:            public int getDataType() {
0901:                return formatTag & DATATYPE_MASK;
0902:            }
0903:
0904:            /**
0905:             *  Returns true if the MediaLibAccessors's data is copied from it's
0906:             *  raster.
0907:             */
0908:            public boolean isDataCopy() {
0909:                return ((formatTag & COPY_MASK) == COPIED);
0910:            }
0911:
0912:            /** Returns the bandOffsets. */
0913:            public int[] getBandOffsets() {
0914:                return bandOffsets;
0915:            }
0916:
0917:            /**
0918:             *  Returns parameters in the appropriate order if MediaLibAccessor
0919:             *  has reordered the bands or is attempting to make a
0920:             *  BandSequential image look like multiple PixelSequentialImages
0921:             */
0922:            public int[] getIntParameters(int band, int params[]) {
0923:                int returnParams[] = new int[numBands];
0924:                for (int i = 0; i < numBands; i++) {
0925:                    returnParams[i] = params[bandOffsets[i + band]];
0926:                }
0927:                return returnParams;
0928:            }
0929:
0930:            /**
0931:             *  Returns parameters in the appropriate order if MediaLibAccessor
0932:             *  has reordered the bands or is attempting to make a
0933:             *  BandSequential image look like multiple PixelSequentialImages
0934:             */
0935:            public int[][] getIntArrayParameters(int band, int[][] params) {
0936:                int returnParams[][] = new int[numBands][];
0937:                for (int i = 0; i < numBands; i++) {
0938:                    returnParams[i] = params[bandOffsets[i + band]];
0939:                }
0940:                return returnParams;
0941:            }
0942:
0943:            /**
0944:             *  Returns parameters in the appropriate order if MediaLibAccessor
0945:             *  has reordered the bands or is attempting to make a
0946:             *  BandSequential image look like multiple PixelSequentialImages
0947:             */
0948:            public double[] getDoubleParameters(int band, double params[]) {
0949:                double returnParams[] = new double[numBands];
0950:                for (int i = 0; i < numBands; i++) {
0951:                    returnParams[i] = params[bandOffsets[i + band]];
0952:                }
0953:                return returnParams;
0954:            }
0955:
0956:            /**
0957:             *  Copy data from Raster to MediaLib image
0958:             */
0959:            private void copyDataFromRaster() {
0960:                // Writeback should only be necessary on destRasters which
0961:                // should be writable so this cast should succeed.
0962:
0963:                if (raster.getSampleModel() instanceof  ComponentSampleModel) {
0964:                    ComponentSampleModel csm = (ComponentSampleModel) raster
0965:                            .getSampleModel();
0966:                    int rasScanlineStride = csm.getScanlineStride();
0967:                    int rasPixelStride = csm.getPixelStride();
0968:
0969:                    int subRasterOffset = (rect.y - raster
0970:                            .getSampleModelTranslateY())
0971:                            * rasScanlineStride
0972:                            + (rect.x - raster.getSampleModelTranslateX())
0973:                            * rasPixelStride;
0974:
0975:                    int rasBankIndices[] = csm.getBankIndices();
0976:                    int rasBandOffsets[] = csm.getBandOffsets();
0977:                    int rasDataOffsets[] = raster.getDataBuffer().getOffsets();
0978:
0979:                    if (rasDataOffsets.length == 1) {
0980:                        for (int i = 0; i < numBands; i++) {
0981:                            rasBandOffsets[i] += rasDataOffsets[0]
0982:                                    + subRasterOffset;
0983:                        }
0984:                    } else if (rasDataOffsets.length == rasBandOffsets.length) {
0985:                        for (int i = 0; i < numBands; i++) {
0986:                            rasBandOffsets[i] += rasDataOffsets[i]
0987:                                    + subRasterOffset;
0988:                        }
0989:                    }
0990:
0991:                    Object mlibDataArray = null;
0992:                    switch (getDataType()) {
0993:                    case DataBuffer.TYPE_BYTE:
0994:                        byte bArray[][] = new byte[numBands][];
0995:                        for (int i = 0; i < numBands; i++) {
0996:                            bArray[i] = mlimages[0].getByteData();
0997:                        }
0998:                        mlibDataArray = bArray;
0999:                        break;
1000:                    case DataBuffer.TYPE_USHORT:
1001:                        short usArray[][] = new short[numBands][];
1002:                        for (int i = 0; i < numBands; i++) {
1003:                            usArray[i] = mlimages[0].getUShortData();
1004:                        }
1005:                        mlibDataArray = usArray;
1006:                        break;
1007:                    case DataBuffer.TYPE_SHORT:
1008:                        short sArray[][] = new short[numBands][];
1009:                        for (int i = 0; i < numBands; i++) {
1010:                            sArray[i] = mlimages[0].getShortData();
1011:                        }
1012:                        mlibDataArray = sArray;
1013:                        break;
1014:                    case DataBuffer.TYPE_INT:
1015:                        int iArray[][] = new int[numBands][];
1016:                        for (int i = 0; i < numBands; i++) {
1017:                            iArray[i] = mlimages[0].getIntData();
1018:                        }
1019:                        mlibDataArray = iArray;
1020:                        break;
1021:                    case DataBuffer.TYPE_FLOAT:
1022:                        float fArray[][] = new float[numBands][];
1023:                        for (int i = 0; i < numBands; i++) {
1024:                            fArray[i] = mlimages[0].getFloatData();
1025:                        }
1026:                        mlibDataArray = fArray;
1027:                        break;
1028:                    case DataBuffer.TYPE_DOUBLE:
1029:                        double dArray[][] = new double[numBands][];
1030:                        for (int i = 0; i < numBands; i++) {
1031:                            dArray[i] = mlimages[0].getDoubleData();
1032:                        }
1033:                        mlibDataArray = dArray;
1034:                        break;
1035:                    }
1036:
1037:                    Object rasDataArray = null;
1038:                    switch (csm.getDataType()) {
1039:                    case DataBuffer.TYPE_BYTE: {
1040:                        DataBufferByte dbb = (DataBufferByte) raster
1041:                                .getDataBuffer();
1042:                        byte rasByteDataArray[][] = new byte[numBands][];
1043:                        for (int i = 0; i < numBands; i++) {
1044:                            rasByteDataArray[i] = dbb
1045:                                    .getData(rasBankIndices[i]);
1046:                        }
1047:                        rasDataArray = rasByteDataArray;
1048:                    }
1049:                        break;
1050:                    case DataBuffer.TYPE_USHORT: {
1051:                        DataBufferUShort dbus = (DataBufferUShort) raster
1052:                                .getDataBuffer();
1053:                        short rasUShortDataArray[][] = new short[numBands][];
1054:                        for (int i = 0; i < numBands; i++) {
1055:                            rasUShortDataArray[i] = dbus
1056:                                    .getData(rasBankIndices[i]);
1057:                        }
1058:                        rasDataArray = rasUShortDataArray;
1059:                    }
1060:                        break;
1061:                    case DataBuffer.TYPE_SHORT: {
1062:                        DataBufferShort dbs = (DataBufferShort) raster
1063:                                .getDataBuffer();
1064:                        short rasShortDataArray[][] = new short[numBands][];
1065:                        for (int i = 0; i < numBands; i++) {
1066:                            rasShortDataArray[i] = dbs
1067:                                    .getData(rasBankIndices[i]);
1068:                        }
1069:                        rasDataArray = rasShortDataArray;
1070:                    }
1071:                        break;
1072:                    case DataBuffer.TYPE_INT: {
1073:                        DataBufferInt dbi = (DataBufferInt) raster
1074:                                .getDataBuffer();
1075:                        int rasIntDataArray[][] = new int[numBands][];
1076:                        for (int i = 0; i < numBands; i++) {
1077:                            rasIntDataArray[i] = dbi.getData(rasBankIndices[i]);
1078:                        }
1079:                        rasDataArray = rasIntDataArray;
1080:                    }
1081:                        break;
1082:                    case DataBuffer.TYPE_FLOAT: {
1083:                        DataBuffer dbf = raster.getDataBuffer();
1084:                        float rasFloatDataArray[][] = new float[numBands][];
1085:                        for (int i = 0; i < numBands; i++) {
1086:                            rasFloatDataArray[i] = DataBufferUtils
1087:                                    .getDataFloat(dbf, rasBankIndices[i]);
1088:                        }
1089:                        rasDataArray = rasFloatDataArray;
1090:                    }
1091:                        break;
1092:                    case DataBuffer.TYPE_DOUBLE: {
1093:                        DataBuffer dbd = raster.getDataBuffer();
1094:                        double rasDoubleDataArray[][] = new double[numBands][];
1095:                        for (int i = 0; i < numBands; i++) {
1096:                            rasDoubleDataArray[i] = DataBufferUtils
1097:                                    .getDataDouble(dbd, rasBankIndices[i]);
1098:                        }
1099:                        rasDataArray = rasDoubleDataArray;
1100:                    }
1101:                        break;
1102:                    }
1103:
1104:                    // dst = mlib && src = ras
1105:                    Image.Reformat(mlibDataArray, rasDataArray, numBands,
1106:                            rect.width, rect.height, getMediaLibDataType(this 
1107:                                    .getDataType()), bandOffsets, rect.width
1108:                                    * numBands, numBands,
1109:                            getMediaLibDataType(csm.getDataType()),
1110:                            rasBandOffsets, rasScanlineStride, rasPixelStride);
1111:                } else {
1112:                    // If COPIED and the raster doesn't have ComponentSampleModel
1113:                    // data is moved with getPixel/setPixel (even byte/short)
1114:                    switch (getDataType()) {
1115:                    case DataBuffer.TYPE_INT:
1116:                        raster.getPixels(rect.x, rect.y, rect.width,
1117:                                rect.height, mlimages[0].getIntData());
1118:                        break;
1119:                    case DataBuffer.TYPE_FLOAT:
1120:                        raster.getPixels(rect.x, rect.y, rect.width,
1121:                                rect.height, mlimages[0].getFloatData());
1122:                        break;
1123:                    case DataBuffer.TYPE_DOUBLE:
1124:                        raster.getPixels(rect.x, rect.y, rect.width,
1125:                                rect.height, mlimages[0].getDoubleData());
1126:                        break;
1127:                    }
1128:                }
1129:            }
1130:
1131:            /**
1132:             *  Copies data back into the MediaLibAccessor's raster.  Note that
1133:             *  the data is casted from the intermediate data format to
1134:             *  the raster's format.  If clamping is needed, the call
1135:             *  clampDataArrays() method needs to be called before
1136:             *  calling the copyDataToRaster() method.
1137:             */
1138:            public void copyDataToRaster() {
1139:                if (isDataCopy()) {
1140:
1141:                    if (isBinary()) {
1142:                        if (areBinaryDataPacked) {
1143:                            ImageUtil.setPackedBinaryData(mlimages[0]
1144:                                    .getBitData(), (WritableRaster) raster,
1145:                                    rect);
1146:                        } else { // unpacked
1147:                            ImageUtil.setUnpackedBinaryData(mlimages[0]
1148:                                    .getByteData(), (WritableRaster) raster,
1149:                                    rect);
1150:                        }
1151:                        return;
1152:                    }
1153:
1154:                    // Writeback should only be necessary on destRasters which
1155:                    // should be writable so this cast should succeed.
1156:                    WritableRaster wr = (WritableRaster) raster;
1157:
1158:                    if (wr.getSampleModel() instanceof  ComponentSampleModel) {
1159:                        ComponentSampleModel csm = (ComponentSampleModel) wr
1160:                                .getSampleModel();
1161:                        int rasScanlineStride = csm.getScanlineStride();
1162:                        int rasPixelStride = csm.getPixelStride();
1163:
1164:                        int subRasterOffset = (rect.y - raster
1165:                                .getSampleModelTranslateY())
1166:                                * rasScanlineStride
1167:                                + (rect.x - raster.getSampleModelTranslateX())
1168:                                * rasPixelStride;
1169:
1170:                        int rasBankIndices[] = csm.getBankIndices();
1171:                        int rasBandOffsets[] = csm.getBandOffsets();
1172:                        int rasDataOffsets[] = raster.getDataBuffer()
1173:                                .getOffsets();
1174:
1175:                        if (rasDataOffsets.length == 1) {
1176:                            for (int i = 0; i < numBands; i++) {
1177:                                rasBandOffsets[i] += rasDataOffsets[0]
1178:                                        + subRasterOffset;
1179:                            }
1180:                        } else if (rasDataOffsets.length == rasBandOffsets.length) {
1181:                            for (int i = 0; i < numBands; i++) {
1182:                                rasBandOffsets[i] += rasDataOffsets[i]
1183:                                        + subRasterOffset;
1184:                            }
1185:                        }
1186:
1187:                        Object mlibDataArray = null;
1188:                        switch (getDataType()) {
1189:                        case DataBuffer.TYPE_BYTE:
1190:                            byte bArray[][] = new byte[numBands][];
1191:                            for (int i = 0; i < numBands; i++) {
1192:                                bArray[i] = mlimages[0].getByteData();
1193:                            }
1194:                            mlibDataArray = bArray;
1195:                            break;
1196:                        case DataBuffer.TYPE_USHORT:
1197:                            short usArray[][] = new short[numBands][];
1198:                            for (int i = 0; i < numBands; i++) {
1199:                                usArray[i] = mlimages[0].getUShortData();
1200:                            }
1201:                            mlibDataArray = usArray;
1202:                            break;
1203:                        case DataBuffer.TYPE_SHORT:
1204:                            short sArray[][] = new short[numBands][];
1205:                            for (int i = 0; i < numBands; i++) {
1206:                                sArray[i] = mlimages[0].getShortData();
1207:                            }
1208:                            mlibDataArray = sArray;
1209:                            break;
1210:                        case DataBuffer.TYPE_INT:
1211:                            int iArray[][] = new int[numBands][];
1212:                            for (int i = 0; i < numBands; i++) {
1213:                                iArray[i] = mlimages[0].getIntData();
1214:                            }
1215:                            mlibDataArray = iArray;
1216:                            break;
1217:                        case DataBuffer.TYPE_FLOAT:
1218:                            float fArray[][] = new float[numBands][];
1219:                            for (int i = 0; i < numBands; i++) {
1220:                                fArray[i] = mlimages[0].getFloatData();
1221:                            }
1222:                            mlibDataArray = fArray;
1223:                            break;
1224:                        case DataBuffer.TYPE_DOUBLE:
1225:                            double dArray[][] = new double[numBands][];
1226:                            for (int i = 0; i < numBands; i++) {
1227:                                dArray[i] = mlimages[0].getDoubleData();
1228:                            }
1229:                            mlibDataArray = dArray;
1230:                            break;
1231:                        }
1232:
1233:                        byte tmpDataArray[] = null;
1234:                        Object rasDataArray = null;
1235:                        switch (csm.getDataType()) {
1236:                        case DataBuffer.TYPE_BYTE: {
1237:                            DataBufferByte dbb = (DataBufferByte) raster
1238:                                    .getDataBuffer();
1239:                            byte rasByteDataArray[][] = new byte[numBands][];
1240:                            for (int i = 0; i < numBands; i++) {
1241:                                rasByteDataArray[i] = dbb
1242:                                        .getData(rasBankIndices[i]);
1243:                            }
1244:                            tmpDataArray = rasByteDataArray[0];
1245:                            rasDataArray = rasByteDataArray;
1246:                        }
1247:                            break;
1248:                        case DataBuffer.TYPE_USHORT: {
1249:                            DataBufferUShort dbus = (DataBufferUShort) raster
1250:                                    .getDataBuffer();
1251:                            short rasUShortDataArray[][] = new short[numBands][];
1252:                            for (int i = 0; i < numBands; i++) {
1253:                                rasUShortDataArray[i] = dbus
1254:                                        .getData(rasBankIndices[i]);
1255:                            }
1256:                            rasDataArray = rasUShortDataArray;
1257:                        }
1258:                            break;
1259:                        case DataBuffer.TYPE_SHORT: {
1260:                            DataBufferShort dbs = (DataBufferShort) raster
1261:                                    .getDataBuffer();
1262:                            short rasShortDataArray[][] = new short[numBands][];
1263:                            for (int i = 0; i < numBands; i++) {
1264:                                rasShortDataArray[i] = dbs
1265:                                        .getData(rasBankIndices[i]);
1266:                            }
1267:                            rasDataArray = rasShortDataArray;
1268:                        }
1269:                            break;
1270:                        case DataBuffer.TYPE_INT: {
1271:                            DataBufferInt dbi = (DataBufferInt) raster
1272:                                    .getDataBuffer();
1273:                            int rasIntDataArray[][] = new int[numBands][];
1274:                            for (int i = 0; i < numBands; i++) {
1275:                                rasIntDataArray[i] = dbi
1276:                                        .getData(rasBankIndices[i]);
1277:                            }
1278:                            rasDataArray = rasIntDataArray;
1279:                        }
1280:                            break;
1281:                        case DataBuffer.TYPE_FLOAT: {
1282:                            DataBuffer dbf = raster.getDataBuffer();
1283:                            float rasFloatDataArray[][] = new float[numBands][];
1284:                            for (int i = 0; i < numBands; i++) {
1285:                                rasFloatDataArray[i] = DataBufferUtils
1286:                                        .getDataFloat(dbf, rasBankIndices[i]);
1287:                            }
1288:                            rasDataArray = rasFloatDataArray;
1289:                        }
1290:                            break;
1291:                        case DataBuffer.TYPE_DOUBLE: {
1292:                            DataBuffer dbd = raster.getDataBuffer();
1293:                            double rasDoubleDataArray[][] = new double[numBands][];
1294:                            for (int i = 0; i < numBands; i++) {
1295:                                rasDoubleDataArray[i] = DataBufferUtils
1296:                                        .getDataDouble(dbd, rasBankIndices[i]);
1297:                            }
1298:                            rasDataArray = rasDoubleDataArray;
1299:                        }
1300:                            break;
1301:                        }
1302:
1303:                        // src = mlib && dst = ras
1304:                        Image.Reformat(rasDataArray, mlibDataArray, numBands,
1305:                                rect.width, rect.height,
1306:                                getMediaLibDataType(csm.getDataType()),
1307:                                rasBandOffsets, rasScanlineStride,
1308:                                rasPixelStride, getMediaLibDataType(this 
1309:                                        .getDataType()), bandOffsets,
1310:                                rect.width * numBands, numBands);
1311:                    } else {
1312:                        // If COPIED and the raster doesn't have ComponentSampleModel
1313:                        // data is moved with getPixel/setPixel (even byte/short)
1314:                        switch (getDataType()) {
1315:                        case DataBuffer.TYPE_INT:
1316:                            wr.setPixels(rect.x, rect.y, rect.width,
1317:                                    rect.height, mlimages[0].getIntData());
1318:                            break;
1319:                        case DataBuffer.TYPE_FLOAT:
1320:                            wr.setPixels(rect.x, rect.y, rect.width,
1321:                                    rect.height, mlimages[0].getFloatData());
1322:                            break;
1323:                        case DataBuffer.TYPE_DOUBLE:
1324:                            wr.setPixels(rect.x, rect.y, rect.width,
1325:                                    rect.height, mlimages[0].getDoubleData());
1326:                            break;
1327:                        }
1328:                    }
1329:                }
1330:            }
1331:
1332:            /**
1333:             * Clamps data array values to a range that the underlying raster
1334:             * can deal with.  For example, if the underlying raster stores
1335:             * data as bytes, but the samples ares unpacked into integer arrays by
1336:             * the RasterAccessor object for an operation, the operation will
1337:             * need to call clampDataArrays() so that the data in the int
1338:             * arrays is restricted to the range 0..255 before a setPixels()
1339:             * call is made on the underlying raster.  Note that some
1340:             * operations (for example, lookup) can guarantee that their
1341:             * results don't need clamping so they can call
1342:             * RasterAccessor.copyDataToRaster() without first calling this
1343:             * function.
1344:             */
1345:            public void clampDataArrays() {
1346:                if (!isDataCopy()) {
1347:                    return;
1348:                }
1349:
1350:                // additonal medialib check:  If it's a componentSampleModel
1351:                // we get a free cast when we call medialibWrapper.Reformat
1352:                // to copy the data to the source.  So we don't need to cast
1353:                // here.
1354:                if (raster.getSampleModel() instanceof  ComponentSampleModel) {
1355:                    return;
1356:                }
1357:
1358:                int bits[] = raster.getSampleModel().getSampleSize();
1359:
1360:                // Do we even need a clamp?  We do if there's any band
1361:                // of the source image stored in that's less than 32 bits
1362:                // and is stored in a byte, short or int format.  (The automatic
1363:                // cast's between floats/doubles and 32-bit ints in setPixel()
1364:                // generall do what we want.)
1365:
1366:                boolean needClamp = false;
1367:                boolean uniformBitSize = true;
1368:                for (int i = 0; i < bits.length; i++) {
1369:                    int bitSize = bits[0];
1370:                    if (bits[i] < 32) {
1371:                        needClamp = true;
1372:                    }
1373:                    if (bits[i] != bitSize) {
1374:                        uniformBitSize = false;
1375:                    }
1376:                }
1377:
1378:                if (!needClamp) {
1379:                    return;
1380:                }
1381:
1382:                int dataType = raster.getDataBuffer().getDataType();
1383:                double hiVals[] = new double[bits.length];
1384:                double loVals[] = new double[bits.length];
1385:
1386:                if (dataType == DataBuffer.TYPE_USHORT && uniformBitSize
1387:                        && bits[0] == 16) {
1388:                    for (int i = 0; i < bits.length; i++) {
1389:                        hiVals[i] = (double) 0xFFFF;
1390:                        loVals[i] = (double) 0;
1391:                    }
1392:                } else if (dataType == DataBuffer.TYPE_SHORT && uniformBitSize
1393:                        && bits[0] == 16) {
1394:                    for (int i = 0; i < bits.length; i++) {
1395:                        hiVals[i] = (double) Short.MAX_VALUE;
1396:                        loVals[i] = (double) Short.MIN_VALUE;
1397:                    }
1398:                } else if (dataType == DataBuffer.TYPE_INT && uniformBitSize
1399:                        && bits[0] == 32) {
1400:                    for (int i = 0; i < bits.length; i++) {
1401:                        hiVals[i] = (double) Integer.MAX_VALUE;
1402:                        loVals[i] = (double) Integer.MIN_VALUE;
1403:                    }
1404:                } else {
1405:                    for (int i = 0; i < bits.length; i++) {
1406:                        hiVals[i] = (double) ((1 << bits[i]) - 1);
1407:                        loVals[i] = (double) 0;
1408:                    }
1409:                }
1410:                clampDataArray(hiVals, loVals);
1411:            }
1412:
1413:            private void clampDataArray(double hiVals[], double loVals[]) {
1414:                switch (getDataType()) {
1415:                case DataBuffer.TYPE_INT:
1416:                    clampIntArrays(toIntArray(hiVals), toIntArray(loVals));
1417:                    break;
1418:                case DataBuffer.TYPE_FLOAT:
1419:                    clampFloatArrays(toFloatArray(hiVals), toFloatArray(loVals));
1420:                    break;
1421:                case DataBuffer.TYPE_DOUBLE:
1422:                    clampDoubleArrays(hiVals, loVals);
1423:                    break;
1424:                }
1425:            }
1426:
1427:            private int[] toIntArray(double vals[]) {
1428:                int returnVals[] = new int[vals.length];
1429:                for (int i = 0; i < vals.length; i++) {
1430:                    returnVals[i] = (int) vals[i];
1431:                }
1432:                return returnVals;
1433:            }
1434:
1435:            private float[] toFloatArray(double vals[]) {
1436:                float returnVals[] = new float[vals.length];
1437:                for (int i = 0; i < vals.length; i++) {
1438:                    returnVals[i] = (float) vals[i];
1439:                }
1440:                return returnVals;
1441:            }
1442:
1443:            private void clampIntArrays(int hiVals[], int loVals[]) {
1444:                int width = rect.width;
1445:                int height = rect.height;
1446:                int scanlineStride = numBands * width;
1447:                for (int k = 0; k < numBands; k++) {
1448:                    int data[] = mlimages[0].getIntData();
1449:                    int scanlineOffset = k;
1450:                    int hiVal = hiVals[k];
1451:                    int loVal = loVals[k];
1452:                    for (int j = 0; j < height; j++) {
1453:                        int pixelOffset = scanlineOffset;
1454:                        for (int i = 0; i < width; i++) {
1455:                            int tmp = data[pixelOffset];
1456:                            if (tmp < loVal) {
1457:                                data[pixelOffset] = loVal;
1458:                            } else if (tmp > hiVal) {
1459:                                data[pixelOffset] = hiVal;
1460:                            }
1461:                            pixelOffset += numBands;
1462:                        }
1463:                        scanlineOffset += scanlineStride;
1464:                    }
1465:                }
1466:            }
1467:
1468:            private void clampFloatArrays(float hiVals[], float loVals[]) {
1469:                int width = rect.width;
1470:                int height = rect.height;
1471:                int scanlineStride = numBands * width;
1472:                for (int k = 0; k < numBands; k++) {
1473:                    float data[] = mlimages[0].getFloatData();
1474:                    int scanlineOffset = k;
1475:                    float hiVal = hiVals[k];
1476:                    float loVal = loVals[k];
1477:                    for (int j = 0; j < height; j++) {
1478:                        int pixelOffset = scanlineOffset;
1479:                        for (int i = 0; i < width; i++) {
1480:                            float tmp = data[pixelOffset];
1481:                            if (tmp < loVal) {
1482:                                data[pixelOffset] = loVal;
1483:                            } else if (tmp > hiVal) {
1484:                                data[pixelOffset] = hiVal;
1485:                            }
1486:                            pixelOffset += numBands;
1487:                        }
1488:                        scanlineOffset += scanlineStride;
1489:                    }
1490:                }
1491:            }
1492:
1493:            private void clampDoubleArrays(double hiVals[], double loVals[]) {
1494:                int width = rect.width;
1495:                int height = rect.height;
1496:                int scanlineStride = numBands * width;
1497:                for (int k = 0; k < numBands; k++) {
1498:                    double data[] = mlimages[0].getDoubleData();
1499:                    int scanlineOffset = k;
1500:                    double hiVal = hiVals[k];
1501:                    double loVal = loVals[k];
1502:                    for (int j = 0; j < height; j++) {
1503:                        int pixelOffset = scanlineOffset;
1504:                        for (int i = 0; i < width; i++) {
1505:                            double tmp = data[pixelOffset];
1506:                            if (tmp < loVal) {
1507:                                data[pixelOffset] = loVal;
1508:                            } else if (tmp > hiVal) {
1509:                                data[pixelOffset] = hiVal;
1510:                            }
1511:                            pixelOffset += numBands;
1512:                        }
1513:                        scanlineOffset += scanlineStride;
1514:                    }
1515:                }
1516:            }
1517:        }
1518:
1519:        class MediaLibLoadException extends Exception {
1520:            MediaLibLoadException() {
1521:                super ();
1522:            }
1523:
1524:            public synchronized Throwable fillInStackTrace() {
1525:                return this;
1526:            }
1527:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.