Source Code Cross Referenced for RasterAccessor.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: RasterAccessor.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.1 $
0009:         * $Date: 2005/02/11 04:57:18 $
0010:         * $State: Exp $
0011:         */
0012:        package javax.media.jai;
0013:
0014:        import java.awt.image.SampleModel;
0015:        import java.awt.image.ComponentSampleModel;
0016:        import java.awt.image.DataBuffer;
0017:        import java.awt.image.DataBufferByte;
0018:        import java.awt.image.DataBufferUShort;
0019:        import java.awt.image.DataBufferShort;
0020:        import java.awt.image.DataBufferInt;
0021:        import java.awt.image.MultiPixelPackedSampleModel;
0022:        import java.awt.image.Raster;
0023:        import java.awt.image.WritableRaster;
0024:        import java.awt.Rectangle;
0025:        import java.awt.image.RenderedImage;
0026:        import java.awt.image.ColorModel;
0027:        import java.awt.image.IndexColorModel;
0028:        import java.awt.image.ComponentColorModel;
0029:        import com.sun.media.jai.util.DataBufferUtils;
0030:        import com.sun.media.jai.util.ImageUtil;
0031:
0032:        /**
0033:         * An adapter class for presenting non-binary image data in a
0034:         * <code>ComponentSampleModel</code> format and binary image data in
0035:         * a zero-offset byte array format even when the original data are not
0036:         * so stored.  <code>RasterAccessor</code> is meant to make the common
0037:         * (<code>ComponentSampleModel</code>) case fast and other formats
0038:         * possible without forcing the <code>OpImage</code> writer to cover more
0039:         * than one case per non-binary data type.
0040:         *
0041:         * <p>When constructing a <code>RasterAccessor</code> with a source(s) that 
0042:         * has an IndexColorModel and a destination that has a 
0043:         * non-<code>IndexColorModel</code>, <code>RasterAccessor</code> will 
0044:         * perform expansion of the source pixels. If the source(s) and the 
0045:         * destination have an IndexColorModel, then <code>RasterAccessor</code>
0046:         * will assume that the operation can correctly process an IndexColorModel
0047:         * source and will not expand the source pixels (colormap indices) into 
0048:         * color components. Refer to {@link JAI#KEY_REPLACE_INDEX_COLOR_MODEL} 
0049:         * for a mechanism by which the destination image's <code>ColorModel</code>
0050:         * is set to a non-<code>IndexColorModel</code> to cause 
0051:         * <code>RasterAccessor</code> to expand the source's 
0052:         * <code>IndexColorModel</code>. 
0053:         * 
0054:         * <p> Binary data are handled as a special case.  In general image data
0055:         * are considered to be binary when the image has a single-banded
0056:         * <code>MultiPixelPackedSampleModel</code> with one bit per pixel.  This
0057:         * may be verified by invoking the <code>isBinary()</code> method.  For this
0058:         * case the methods <code>getBinaryDataArray()</code> and
0059:         * <code>copyBinaryDataToRaster()</code> should be used to access and set,
0060:         * respectively, the binary data in packed form.  If the binary data are
0061:         * to be accessed in expanded form, i.e., as bytes, then the usual byte
0062:         * methods <code>getByteDataArray()</code>, <code>getByteDataArrays()</code>,
0063:         * and <code>copyDataToRaster()</code> should be used.
0064:         *
0065:         */
0066:        public class RasterAccessor {
0067:
0068:            /** 
0069:             * Value indicating how far COPY_MASK info is shifted to avoid 
0070:             * interfering with the data type info.
0071:             */
0072:            private static final int COPY_MASK_SHIFT = 7;
0073:
0074:            /* Value indicating how many bits the COPY_MASK is */
0075:            private static final int COPY_MASK_SIZE = 2;
0076:
0077:            /** The bits of a FormatTag associated with how dataArrays are obtained. */
0078:            public static final int COPY_MASK = ((1 << COPY_MASK_SIZE) - 1) << COPY_MASK_SHIFT;
0079:
0080:            /** Flag indicating data is raster's data. */
0081:            public static final int UNCOPIED = 0x0 << COPY_MASK_SHIFT;
0082:
0083:            /** Flag indicating data is a copy of the raster's data. */
0084:            public static final int COPIED = 0x1 << COPY_MASK_SHIFT;
0085:
0086:            /**
0087:             * Value indicating how far EXPANSION_MASK info is shifted to avoid
0088:             * interfering with the data type info.
0089:             */
0090:            private static final int EXPANSION_MASK_SHIFT = COPY_MASK_SHIFT
0091:                    + COPY_MASK_SIZE;
0092:
0093:            /** Value indicating how many bits the EXPANSION_MASK is */
0094:            private static final int EXPANSION_MASK_SIZE = 2;
0095:
0096:            /** The bits of a FormatTag associated with how ColorModels are used. */
0097:            public static final int EXPANSION_MASK = ((1 << EXPANSION_MASK_SIZE) - 1) << EXPANSION_MASK_SHIFT;
0098:
0099:            /** Flag indicating ColorModel data should be used only in copied case */
0100:            public static final int DEFAULTEXPANSION = 0x0 << EXPANSION_MASK_SHIFT;
0101:
0102:            /** Flag indicating ColorModel data should be interpreted. */
0103:            public static final int EXPANDED = 0x1 << EXPANSION_MASK_SHIFT;
0104:
0105:            /** Flag indicating ColorModel info should be ignored */
0106:            public static final int UNEXPANDED = 0x02 << EXPANSION_MASK_SHIFT;
0107:
0108:            /** The bits of a FormatTagID associated with pixel datatype. */
0109:            public static final int DATATYPE_MASK = (0x1 << COPY_MASK_SHIFT) - 1;
0110:
0111:            /** FormatTagID indicating data in byte arrays and uncopied. */
0112:            public static final int TAG_BYTE_UNCOPIED = DataBuffer.TYPE_BYTE
0113:                    | UNCOPIED;
0114:
0115:            /** FormatTagID indicating data in unsigned short arrays and uncopied. */
0116:            public static final int TAG_USHORT_UNCOPIED = DataBuffer.TYPE_USHORT
0117:                    | UNCOPIED;
0118:
0119:            /** FormatTagID indicating data in short arrays and uncopied. */
0120:            public static final int TAG_SHORT_UNCOPIED = DataBuffer.TYPE_SHORT
0121:                    | UNCOPIED;
0122:
0123:            /** FormatTagID indicating data in int arrays and uncopied. */
0124:            public static final int TAG_INT_UNCOPIED = DataBuffer.TYPE_INT
0125:                    | UNCOPIED;
0126:
0127:            /** FormatTagID indicating data in float arrays and uncopied. */
0128:            public static final int TAG_FLOAT_UNCOPIED = DataBuffer.TYPE_FLOAT
0129:                    | UNCOPIED;
0130:
0131:            /** FormatTagID indicating data in double arrays and uncopied. */
0132:            public static final int TAG_DOUBLE_UNCOPIED = DataBuffer.TYPE_DOUBLE
0133:                    | UNCOPIED;
0134:
0135:            /** FormatTagID indicating data in int arrays and copied. */
0136:            public static final int TAG_INT_COPIED = DataBuffer.TYPE_INT
0137:                    | COPIED;
0138:
0139:            /** FormatTagID indicating data in float arrays and copied. */
0140:            public static final int TAG_FLOAT_COPIED = DataBuffer.TYPE_FLOAT
0141:                    | COPIED;
0142:
0143:            /** FormatTagID indicating data in double arrays and copied. */
0144:            public static final int TAG_DOUBLE_COPIED = DataBuffer.TYPE_DOUBLE
0145:                    | COPIED;
0146:
0147:            /** FormatTagID indicating data in byte arrays and expanded. */
0148:            public static final int TAG_BYTE_EXPANDED = DataBuffer.TYPE_BYTE
0149:                    | EXPANDED;
0150:
0151:            /**
0152:             * FormatTagID corresponding to the binary case.  This occurs when
0153:             * the image has a <code>MultiPixelPackedSampleModel</code> with a
0154:             * single band and one bit per pixel.
0155:             */
0156:            private static final int TAG_BINARY = DataBuffer.TYPE_BYTE | COPIED
0157:                    | UNEXPANDED;
0158:
0159:            /** The raster that is the source of pixel data. */
0160:            protected Raster raster;
0161:
0162:            /** The width of the rectangle this RasterAccessor addresses. */
0163:            protected int rectWidth;
0164:
0165:            /** The height of the rectangle this RasterAccessor addresses. */
0166:            protected int rectHeight;
0167:
0168:            /** The x coordinate of upper-left corner of the rectangle this 
0169:             *  RasterAccessor addresses.
0170:             */
0171:            protected int rectX;
0172:
0173:            /** The y coordinate of upper-left corner of the rectangle this
0174:             *  RasterAccessor addresses.
0175:             */
0176:            protected int rectY;
0177:
0178:            /** Tag indicating the data type of the data and whether it's copied */
0179:            protected int formatTagID;
0180:
0181:            /**
0182:             * The image data for the binary case.  The data will be packed as
0183:             * eight bits per byte with no bit offset, i.e., the first bit in each
0184:             * image line will be the left-most bit of the first byte of the line.
0185:             * The line stride in bytes will be <code>(int)((rectWidth+7)/8)</code>.
0186:             * The length of the array will be <code>rectHeight</code> multiplied
0187:             * by the line stride.
0188:             *
0189:             * @since JAI 1.1
0190:             */
0191:            protected byte binaryDataArray[] = null;
0192:
0193:            /** 
0194:             *  The image data in a two-dimensional byte array.  This 
0195:             *  value will be non-null only if getDataType() returns 
0196:             *  DataBuffer.TYPE_BYTE.  byteDataArrays.length will equal
0197:             *  numBands.  Note that often the numBands subArrays will all
0198:             *  point to the same place in memory.
0199:             *
0200:             *  <p> For the case of binary data this variable will not be initialized
0201:             *  until <code>getByteDataArrays()</code> or
0202:             *  <code>getByteDataArray(int b)</code> is invoked.
0203:             */
0204:            protected byte byteDataArrays[][] = null;
0205:
0206:            /**
0207:             *  The image data in a two-dimensional short array.  This
0208:             *  value will be non-null only if getDataType() returns 
0209:             *  DataBuffer.TYPE_USHORT or DataBuffer.TYPE_SHORT.
0210:             *  shortDataArrays.length will equal
0211:             *  numBands.  Note that often the numBands subArrays will all
0212:             *  point to the same place in memory.
0213:             */
0214:            protected short shortDataArrays[][] = null;
0215:
0216:            /**
0217:             *  The image data in a two-dimensional int array.  This
0218:             *  value will be non-null only if getDataType() returns 
0219:             *  DataBuffer.TYPE_INT.  intDataArrays.length will equal
0220:             *  numBands.  Note that often the numBands subArrays will all
0221:             *  point to the same place in memory.
0222:             */
0223:            protected int intDataArrays[][] = null;
0224:
0225:            /**
0226:             *  The image data in a two-dimensional float array.  This
0227:             *  value will be non-null only if getDataType() returns 
0228:             *  DataBuffer.TYPE_FLOAT.  floatDataArrays.length will equal
0229:             *  numBands.  Note that often the numBand subArrays will all
0230:             *  point to the same place in memory.
0231:             */
0232:            protected float floatDataArrays[][] = null;
0233:
0234:            /**
0235:             *  The image data in a two-dimensional double array.  This
0236:             *  value will be non-null only if getDataType() returns 
0237:             *  DataBuffer.TYPE_DOUBLE.  doubleDataArrays.length will equal
0238:             *  numBands.  Note that often the numBand subArrays will all
0239:             *  point to the same place in memory.
0240:             */
0241:            protected double doubleDataArrays[][] = null;
0242:
0243:            /**
0244:             * The bandOffset + subRasterOffset + DataBufferOffset into each of
0245:             * the numBand data arrays
0246:             */
0247:            protected int bandDataOffsets[];
0248:
0249:            /** Offset from a pixel's offset to a band of that pixel */
0250:            protected int bandOffsets[];
0251:
0252:            /** The number of bands per pixel in the data array. */
0253:            protected int numBands;
0254:
0255:            /** The scanline stride of the image data in each data array */
0256:            protected int scanlineStride;
0257:
0258:            /** The pixel stride of the image data in each data array */
0259:            protected int pixelStride;
0260:
0261:            /**
0262:             * Finds the appropriate tags for the constructor, based on the
0263:             * SampleModel and ColorModel of all the source and destination.
0264:             *
0265:             * @param srcs The operations sources; may be <code>null</code> which
0266:             * is taken to be equivalent to zero sources.
0267:             * @param dst The operation destination.
0268:             * @return An array containing <code>RasterFormatTag</code>s for the
0269:             * sources in the first src.length elements and a
0270:             * <code>RasterFormatTag</code> for the destination in the last element.
0271:             * @throws NullPointerException if <code>dst</code> is <code>null</code>.
0272:             */
0273:            public static RasterFormatTag[] findCompatibleTags(
0274:                    RenderedImage srcs[], RenderedImage dst) {
0275:                int tagIDs[];
0276:                if (srcs != null) {
0277:                    tagIDs = new int[srcs.length + 1];
0278:                } else {
0279:                    tagIDs = new int[1];
0280:                }
0281:                SampleModel dstSampleModel = dst.getSampleModel();
0282:                int dstDataType = dstSampleModel.getTransferType();
0283:
0284:                int defaultDataType = dstDataType;
0285:                boolean binaryDst = ImageUtil.isBinary(dstSampleModel);
0286:                if (binaryDst) {
0287:                    defaultDataType = DataBuffer.TYPE_BYTE;
0288:                } else if ((dstDataType == DataBuffer.TYPE_BYTE)
0289:                        || (dstDataType == DataBuffer.TYPE_USHORT)
0290:                        || (dstDataType == DataBuffer.TYPE_SHORT)) {
0291:                    defaultDataType = DataBuffer.TYPE_INT;
0292:                }
0293:
0294:                // use highest precision datatype of all srcs & dst
0295:                if (srcs != null) {
0296:                    int numSources = srcs.length;
0297:                    int i;
0298:                    for (i = 0; i < numSources; i++) {
0299:                        SampleModel srcSampleModel = srcs[i].getSampleModel();
0300:                        int srcDataType = srcSampleModel.getTransferType();
0301:                        if (!(binaryDst && ImageUtil.isBinary(srcSampleModel))
0302:                                && srcDataType > defaultDataType) {
0303:                            defaultDataType = srcDataType;
0304:                        }
0305:                    }
0306:                }
0307:
0308:                // Set the tag. For binary data at this point this should
0309:                // equal DataBuffer.TYPE_BYTE | COPIED.
0310:                int tagID = defaultDataType | COPIED;
0311:
0312:                if (dstSampleModel instanceof  ComponentSampleModel) {
0313:                    if (srcs != null) {
0314:                        int numSources = srcs.length;
0315:                        int i;
0316:                        for (i = 0; i < numSources; i++) {
0317:                            SampleModel srcSampleModel = srcs[i]
0318:                                    .getSampleModel();
0319:                            int srcDataType = srcSampleModel.getTransferType();
0320:                            if (!(srcSampleModel instanceof  ComponentSampleModel)
0321:                                    || (srcDataType != dstDataType)) {
0322:                                break;
0323:                            }
0324:                        }
0325:                        if (i == numSources) {
0326:                            tagID = dstDataType | UNCOPIED;
0327:                        }
0328:                    } else {
0329:                        tagID = dstDataType | UNCOPIED;
0330:                    }
0331:                }
0332:
0333:                // If the source has an IndexColorModel but the dest does not,
0334:                // perform expansion of the source pixels.  If both have an
0335:                // IndexColorModel, assume the operation knows what it is doing.
0336:                RasterFormatTag rft[] = new RasterFormatTag[tagIDs.length];
0337:                if (srcs != null) {
0338:                    for (int i = 0; i < srcs.length; i++) {
0339:                        // dst can't be EXPANDED
0340:                        if ((srcs[i].getColorModel() instanceof  IndexColorModel)) {
0341:                            if (dst.getColorModel() instanceof  IndexColorModel) {
0342:                                tagIDs[i] = tagID | UNEXPANDED;
0343:                            } else {
0344:                                tagIDs[i] = tagID | EXPANDED;
0345:                            }
0346:                        } else if (srcs[i].getColorModel() instanceof  ComponentColorModel
0347:                                || (binaryDst && ImageUtil.isBinary(srcs[i]
0348:                                        .getSampleModel()))) {
0349:                            tagIDs[i] = tagID | UNEXPANDED;
0350:                        } else {
0351:                            tagIDs[i] = tagID | DEFAULTEXPANSION;
0352:                        }
0353:                    }
0354:                    tagIDs[srcs.length] = tagID | UNEXPANDED;
0355:
0356:                    for (int i = 0; i < srcs.length; i++) {
0357:                        rft[i] = new RasterFormatTag(srcs[i].getSampleModel(),
0358:                                tagIDs[i]);
0359:                    }
0360:                    // get the dest
0361:                    rft[srcs.length] = new RasterFormatTag(dstSampleModel,
0362:                            tagIDs[srcs.length]);
0363:                } else { // no sources, dest only
0364:                    rft[0] = new RasterFormatTag(dstSampleModel, tagID
0365:                            | UNEXPANDED);
0366:                }
0367:
0368:                return rft;
0369:            }
0370:
0371:            /**
0372:             * Returns the most efficient FormatTagID that is compatible with
0373:             * the destination SampleModel and all source SampleModels.
0374:             * Since there is no <code>ColorModel</code> associated with
0375:             * a <code>SampleModel</code>, this method does not expand the data
0376:             * buffer as it has no access to the Raster's ColorModel.
0377:             */
0378:            public static int findCompatibleTag(SampleModel[] srcSampleModels,
0379:                    SampleModel dstSampleModel) {
0380:                int dstDataType = dstSampleModel.getTransferType();
0381:
0382:                int tag = dstDataType | COPIED;
0383:                if (ImageUtil.isBinary(dstSampleModel)) {
0384:                    tag = DataBuffer.TYPE_BYTE | COPIED;
0385:                } else if (dstDataType == DataBuffer.TYPE_BYTE
0386:                        || dstDataType == DataBuffer.TYPE_USHORT
0387:                        || dstDataType == DataBuffer.TYPE_SHORT) {
0388:                    tag = TAG_INT_COPIED;
0389:                }
0390:
0391:                if (dstSampleModel instanceof  ComponentSampleModel) {
0392:                    if (srcSampleModels != null) {
0393:                        int numSources = srcSampleModels.length;
0394:                        int i;
0395:                        for (i = 0; i < numSources; i++) {
0396:                            int srcDataType = srcSampleModels[i]
0397:                                    .getTransferType();
0398:
0399:                            if (!(srcSampleModels[i] instanceof  ComponentSampleModel)
0400:                                    || srcDataType != dstDataType) {
0401:                                break;
0402:                            }
0403:                        }
0404:                        if (i == numSources) {
0405:                            tag = dstDataType | UNCOPIED;
0406:                        }
0407:                    } else {
0408:                        tag = dstDataType | UNCOPIED;
0409:                    }
0410:                }
0411:                return tag | UNEXPANDED; // only called when colormodel not around
0412:                // so never expand
0413:            }
0414:
0415:            /**
0416:             * Constructs a RasterAccessor object out of a Raster, Rectangle
0417:             * and formatTagID returned from RasterFormat.findCompatibleTag().
0418:             *
0419:             * <p> The <code>RasterFormatTag</code> must agree with the raster's
0420:             * <code>SampleModel</code> and <code>ColorModel</code>.  It is best
0421:             * to obtain the correct tag using the <code>findCompatibleTags</code>
0422:             * static method.
0423:             *
0424:             * @param raster The raster to be accessed
0425:             * @param rect   A <code>Rectangle</code> from the raster to be accessed
0426:             * @param rft    The <code>RasterFormatTag</code> associated with the Raster
0427:             * @param theColorModel The <code>ColorModel</code> for color components
0428:             *
0429:             * @throws ClassCastException if the data type of
0430:             *         <code>RasterFormatTag</code> does not agree with the actual
0431:             *         data type of the <code>Raster</code>.
0432:             * @throws IllegalArgumentException if <code>raster</code>,
0433:             *         <code>rect</code>, or <code>rft</code> is <code>null</code>.
0434:             * @throws IllegalArgumentException if the <code>Rectangle</code>
0435:             *         is not contained within <code>Raster</code>'s bounds.
0436:             */
0437:            public RasterAccessor(Raster raster, Rectangle rect,
0438:                    RasterFormatTag rft, ColorModel theColorModel) {
0439:
0440:                if (raster == null || rect == null || rft == null) {
0441:                    throw new IllegalArgumentException(JaiI18N
0442:                            .getString("Generic0"));
0443:                }
0444:
0445:                // If requesting a region that lies outside the bounds,
0446:                // throw an exception.
0447:                if (!raster.getBounds().contains(rect)) {
0448:                    throw new IllegalArgumentException(JaiI18N
0449:                            .getString("RasterAccessor2"));
0450:                }
0451:
0452:                this .raster = raster;
0453:                this .rectX = rect.x;
0454:                this .rectY = rect.y;
0455:                this .rectWidth = rect.width;
0456:                this .rectHeight = rect.height;
0457:                this .formatTagID = rft.getFormatTagID();
0458:                if ((formatTagID & COPY_MASK) == UNCOPIED) {
0459:
0460:                    this .numBands = rft.getNumBands();
0461:                    this .pixelStride = rft.getPixelStride();
0462:
0463:                    ComponentSampleModel csm = (ComponentSampleModel) raster
0464:                            .getSampleModel();
0465:                    this .scanlineStride = csm.getScanlineStride();
0466:
0467:                    int bankIndices[] = null;
0468:
0469:                    // if the rft isPixelSequential we can rely on it's
0470:                    // version of bandOffsets and bankIndicies.  If it's
0471:                    // not the SampleModel passed in might not completely
0472:                    // match the one that was passed to the the 
0473:                    // RasterFormatTag constructor so we have to get them
0474:                    // from the passed in Raster/SampleModel
0475:                    if (rft.isPixelSequential()) {
0476:                        this .bandOffsets = rft.getBandOffsets();
0477:                        bankIndices = rft.getBankIndices();
0478:                    } else {
0479:                        this .bandOffsets = csm.getBandOffsets();
0480:                        bankIndices = csm.getBankIndices();
0481:                    }
0482:
0483:                    this .bandDataOffsets = new int[numBands];
0484:
0485:                    int dataBufferOffsets[] = raster.getDataBuffer()
0486:                            .getOffsets();
0487:
0488:                    int subRasterOffset = (rectY - raster
0489:                            .getSampleModelTranslateY())
0490:                            * scanlineStride
0491:                            + (rectX - raster.getSampleModelTranslateX())
0492:                            * pixelStride;
0493:
0494:                    if (dataBufferOffsets.length == 1) {
0495:                        int theDataBufferOffset = dataBufferOffsets[0];
0496:                        for (int i = 0; i < numBands; i++) {
0497:                            bandDataOffsets[i] = bandOffsets[i]
0498:                                    + theDataBufferOffset + subRasterOffset;
0499:                        }
0500:                    } else if (dataBufferOffsets.length == bandDataOffsets.length) {
0501:                        for (int i = 0; i < numBands; i++) {
0502:                            bandDataOffsets[i] = bandOffsets[i]
0503:                                    + dataBufferOffsets[i] + subRasterOffset;
0504:                        }
0505:                    } else {
0506:                        throw new RuntimeException(JaiI18N
0507:                                .getString("RasterAccessor0"));
0508:                    }
0509:
0510:                    switch (formatTagID & DATATYPE_MASK) {
0511:                    case DataBuffer.TYPE_BYTE:
0512:                        DataBufferByte dbb = (DataBufferByte) raster
0513:                                .getDataBuffer();
0514:                        byteDataArrays = new byte[numBands][];
0515:                        for (int i = 0; i < numBands; i++) {
0516:                            byteDataArrays[i] = dbb.getData(bankIndices[i]);
0517:                        }
0518:                        break;
0519:
0520:                    case DataBuffer.TYPE_USHORT:
0521:                        DataBufferUShort dbus = (DataBufferUShort) raster
0522:                                .getDataBuffer();
0523:                        shortDataArrays = new short[numBands][];
0524:                        for (int i = 0; i < numBands; i++) {
0525:                            shortDataArrays[i] = dbus.getData(bankIndices[i]);
0526:                        }
0527:                        break;
0528:
0529:                    case DataBuffer.TYPE_SHORT:
0530:                        DataBufferShort dbs = (DataBufferShort) raster
0531:                                .getDataBuffer();
0532:                        shortDataArrays = new short[numBands][];
0533:                        for (int i = 0; i < numBands; i++) {
0534:                            shortDataArrays[i] = dbs.getData(bankIndices[i]);
0535:                        }
0536:                        break;
0537:
0538:                    case DataBuffer.TYPE_INT:
0539:                        DataBufferInt dbi = (DataBufferInt) raster
0540:                                .getDataBuffer();
0541:                        intDataArrays = new int[numBands][];
0542:                        for (int i = 0; i < numBands; i++) {
0543:                            intDataArrays[i] = dbi.getData(bankIndices[i]);
0544:                        }
0545:                        break;
0546:
0547:                    case DataBuffer.TYPE_FLOAT:
0548:                        DataBuffer dbf = (DataBuffer) raster.getDataBuffer();
0549:                        floatDataArrays = new float[numBands][];
0550:                        for (int i = 0; i < numBands; i++) {
0551:                            floatDataArrays[i] = DataBufferUtils.getDataFloat(
0552:                                    dbf, bankIndices[i]);
0553:                        }
0554:                        break;
0555:
0556:                    case DataBuffer.TYPE_DOUBLE:
0557:                        DataBuffer dbd = (DataBuffer) raster.getDataBuffer();
0558:                        doubleDataArrays = new double[numBands][];
0559:                        for (int i = 0; i < numBands; i++) {
0560:                            doubleDataArrays[i] = DataBufferUtils
0561:                                    .getDataDouble(dbd, bankIndices[i]);
0562:                        }
0563:                        break;
0564:                    }
0565:                    // only do this if not copied and expanded
0566:                    if ((formatTagID & EXPANSION_MASK) == EXPANDED
0567:                            && theColorModel instanceof  IndexColorModel) {
0568:                        IndexColorModel icm = (IndexColorModel) theColorModel;
0569:
0570:                        int newNumBands = icm.getNumComponents();
0571:
0572:                        int mapSize = icm.getMapSize();
0573:                        int newBandDataOffsets[] = new int[newNumBands];
0574:                        int newScanlineStride = rectWidth * newNumBands;
0575:                        int newPixelStride = newNumBands;
0576:                        byte ctable[][] = new byte[newNumBands][mapSize];
0577:
0578:                        icm.getReds(ctable[0]);
0579:                        icm.getGreens(ctable[1]);
0580:                        icm.getBlues(ctable[2]);
0581:                        byte rtable[] = ctable[0];
0582:                        byte gtable[] = ctable[1];
0583:                        byte btable[] = ctable[2];
0584:
0585:                        byte atable[] = null;
0586:                        if (newNumBands == 4) {
0587:                            icm.getAlphas(ctable[3]);
0588:                            atable = ctable[3];
0589:                        }
0590:
0591:                        for (int i = 0; i < newNumBands; i++) {
0592:                            newBandDataOffsets[i] = i;
0593:                        }
0594:
0595:                        switch (formatTagID & DATATYPE_MASK) {
0596:                        case DataBuffer.TYPE_BYTE: {
0597:                            byte newBArray[] = new byte[rectWidth * rectHeight
0598:                                    * newNumBands];
0599:                            byte byteDataArray[] = byteDataArrays[0];
0600:                            int scanlineOffset = bandDataOffsets[0];
0601:                            int newScanlineOffset = 0;
0602:                            for (int j = 0; j < rectHeight; j++) {
0603:                                int pixelOffset = scanlineOffset;
0604:                                int newPixelOffset = newScanlineOffset;
0605:                                for (int i = 0; i < rectWidth; i++) {
0606:                                    int index = byteDataArray[pixelOffset] & 0xff;
0607:                                    for (int k = 0; k < newNumBands; k++) {
0608:                                        newBArray[newPixelOffset + k] = ctable[k][index];
0609:                                    }
0610:                                    pixelOffset += pixelStride;
0611:                                    newPixelOffset += newPixelStride;
0612:                                }
0613:                                scanlineOffset += scanlineStride;
0614:                                newScanlineOffset += newScanlineStride;
0615:                            }
0616:                            byteDataArrays = new byte[newNumBands][];
0617:                            for (int i = 0; i < newNumBands; i++) {
0618:                                byteDataArrays[i] = newBArray;
0619:                            }
0620:                        }
0621:                            break;
0622:
0623:                        case DataBuffer.TYPE_USHORT: {
0624:                            short newIArray[] = new short[rectWidth
0625:                                    * rectHeight * newNumBands];
0626:                            short shortDataArray[] = shortDataArrays[0];
0627:                            int scanlineOffset = bandDataOffsets[0];
0628:                            int newScanlineOffset = 0;
0629:                            for (int j = 0; j < rectHeight; j++) {
0630:                                int pixelOffset = scanlineOffset;
0631:                                int newPixelOffset = newScanlineOffset;
0632:                                for (int i = 0; i < rectWidth; i++) {
0633:                                    int index = (shortDataArray[pixelOffset] & 0xffff);
0634:                                    for (int k = 0; k < newNumBands; k++) {
0635:                                        newIArray[newPixelOffset + k] = (short) (ctable[k][index] & 0xff);
0636:                                    }
0637:                                    pixelOffset += pixelStride;
0638:                                    newPixelOffset += newPixelStride;
0639:                                }
0640:                                scanlineOffset += scanlineStride;
0641:                                newScanlineOffset += newScanlineStride;
0642:                            }
0643:
0644:                            shortDataArrays = new short[newNumBands][];
0645:                            for (int i = 0; i < newNumBands; i++) {
0646:                                shortDataArrays[i] = newIArray;
0647:                            }
0648:                        }
0649:                            break;
0650:
0651:                        case DataBuffer.TYPE_SHORT: {
0652:                            short newIArray[] = new short[rectWidth
0653:                                    * rectHeight * newNumBands];
0654:                            short shortDataArray[] = shortDataArrays[0];
0655:                            int scanlineOffset = bandDataOffsets[0];
0656:                            int newScanlineOffset = 0;
0657:                            for (int j = 0; j < rectHeight; j++) {
0658:                                int pixelOffset = scanlineOffset;
0659:                                int newPixelOffset = newScanlineOffset;
0660:                                for (int i = 0; i < rectWidth; i++) {
0661:                                    int index = shortDataArray[pixelOffset];
0662:                                    for (int k = 0; k < newNumBands; k++) {
0663:                                        newIArray[newPixelOffset + k] = (short) (ctable[k][index] & 0xff);
0664:                                    }
0665:                                    pixelOffset += pixelStride;
0666:                                    newPixelOffset += newPixelStride;
0667:                                }
0668:                                scanlineOffset += scanlineStride;
0669:                                newScanlineOffset += newScanlineStride;
0670:                            }
0671:
0672:                            shortDataArrays = new short[newNumBands][];
0673:                            for (int i = 0; i < newNumBands; i++) {
0674:                                shortDataArrays[i] = newIArray;
0675:                            }
0676:                        }
0677:                            break;
0678:
0679:                        case DataBuffer.TYPE_INT: {
0680:                            int newIArray[] = new int[rectWidth * rectHeight
0681:                                    * newNumBands];
0682:                            int intDataArray[] = intDataArrays[0];
0683:                            int scanlineOffset = bandDataOffsets[0];
0684:                            int newScanlineOffset = 0;
0685:                            for (int j = 0; j < rectHeight; j++) {
0686:                                int pixelOffset = scanlineOffset;
0687:                                int newPixelOffset = newScanlineOffset;
0688:                                for (int i = 0; i < rectWidth; i++) {
0689:                                    int index = intDataArray[pixelOffset];
0690:                                    for (int k = 0; k < newNumBands; k++) {
0691:                                        newIArray[newPixelOffset + k] = (ctable[k][index] & 0xff);
0692:                                    }
0693:                                    pixelOffset += pixelStride;
0694:                                    newPixelOffset += newPixelStride;
0695:                                }
0696:                                scanlineOffset += scanlineStride;
0697:                                newScanlineOffset += newScanlineStride;
0698:                            }
0699:
0700:                            intDataArrays = new int[newNumBands][];
0701:                            for (int i = 0; i < newNumBands; i++) {
0702:                                intDataArrays[i] = newIArray;
0703:                            }
0704:                        }
0705:                            break;
0706:
0707:                        case DataBuffer.TYPE_FLOAT: {
0708:                            float newFArray[] = new float[rectWidth
0709:                                    * rectHeight * newNumBands];
0710:                            float floatDataArray[] = floatDataArrays[0];
0711:                            int scanlineOffset = bandDataOffsets[0];
0712:                            int newScanlineOffset = 0;
0713:                            for (int j = 0; j < rectHeight; j++) {
0714:                                int pixelOffset = scanlineOffset;
0715:                                int newPixelOffset = newScanlineOffset;
0716:                                for (int i = 0; i < rectWidth; i++) {
0717:                                    int index = (int) floatDataArray[pixelOffset];
0718:                                    for (int k = 0; k < newNumBands; k++) {
0719:                                        newFArray[newPixelOffset + k] = (ctable[k][index] & 0xff);
0720:                                    }
0721:                                    pixelOffset += pixelStride;
0722:                                    newPixelOffset += newPixelStride;
0723:                                }
0724:                                scanlineOffset += scanlineStride;
0725:                                newScanlineOffset += newScanlineStride;
0726:                            }
0727:                            floatDataArrays = new float[newNumBands][];
0728:                            for (int i = 0; i < newNumBands; i++) {
0729:                                floatDataArrays[i] = newFArray;
0730:                            }
0731:                        }
0732:                            break;
0733:
0734:                        case DataBuffer.TYPE_DOUBLE: {
0735:                            double newDArray[] = new double[rectWidth
0736:                                    * rectHeight * newNumBands];
0737:                            double doubleDataArray[] = doubleDataArrays[0];
0738:                            int scanlineOffset = bandDataOffsets[0];
0739:                            int newScanlineOffset = 0;
0740:                            for (int j = 0; j < rectHeight; j++) {
0741:                                int pixelOffset = scanlineOffset;
0742:                                int newPixelOffset = newScanlineOffset;
0743:                                for (int i = 0; i < rectWidth; i++) {
0744:                                    int index = (int) doubleDataArray[pixelOffset];
0745:                                    for (int k = 0; k < newNumBands; k++) {
0746:                                        newDArray[newPixelOffset + k] = (ctable[k][index] & 0xff);
0747:                                    }
0748:                                    pixelOffset += pixelStride;
0749:                                    newPixelOffset += newPixelStride;
0750:                                }
0751:                                scanlineOffset += scanlineStride;
0752:                                newScanlineOffset += newScanlineStride;
0753:                            }
0754:                            doubleDataArrays = new double[newNumBands][];
0755:                            for (int i = 0; i < newNumBands; i++) {
0756:                                doubleDataArrays[i] = newDArray;
0757:                            }
0758:                        }
0759:                            break;
0760:                        }
0761:                        this .numBands = newNumBands;
0762:                        this .pixelStride = newPixelStride;
0763:                        this .scanlineStride = newScanlineStride;
0764:                        this .bandDataOffsets = newBandDataOffsets;
0765:                        this .bandOffsets = newBandDataOffsets;
0766:                    }
0767:                } else if ((formatTagID & COPY_MASK) == COPIED
0768:                        && (formatTagID & EXPANSION_MASK) != UNEXPANDED
0769:                        && theColorModel != null) {
0770:                    this .numBands = theColorModel instanceof  IndexColorModel ? theColorModel
0771:                            .getNumComponents()
0772:                            : raster.getSampleModel().getNumBands();
0773:                    this .pixelStride = this .numBands;
0774:                    this .scanlineStride = rectWidth * numBands;
0775:                    this .bandOffsets = new int[numBands];
0776:
0777:                    for (int i = 0; i < numBands; i++) {
0778:                        bandOffsets[i] = i;
0779:                    }
0780:                    this .bandDataOffsets = bandOffsets;
0781:
0782:                    Object odata = null;
0783:                    int offset = 0;
0784:
0785:                    int[] components = new int[theColorModel.getNumComponents()];
0786:
0787:                    switch (formatTagID & DATATYPE_MASK) {
0788:
0789:                    case DataBuffer.TYPE_INT:
0790:                        int idata[] = new int[rectWidth * rectHeight * numBands];
0791:                        intDataArrays = new int[numBands][];
0792:                        for (int i = 0; i < numBands; i++) {
0793:                            intDataArrays[i] = idata;
0794:                        }
0795:
0796:                        odata = raster.getDataElements(rectX, rectY, null);
0797:                        offset = 0;
0798:
0799:                        // Workaround for bug in BytePackedRaster
0800:                        byte[] bdata = null;
0801:                        if (raster instanceof  sun.awt.image.BytePackedRaster) {
0802:                            bdata = (byte[]) odata;
0803:                        }
0804:
0805:                        for (int j = rectY; j < rectY + rectHeight; j++) {
0806:                            for (int i = rectX; i < rectX + rectWidth; i++) {
0807:                                if (bdata != null) {
0808:                                    bdata[0] = (byte) raster.getSample(i, j, 0);
0809:                                } else {
0810:                                    raster.getDataElements(i, j, odata);
0811:                                }
0812:
0813:                                theColorModel.getComponents(odata, components,
0814:                                        0);
0815:
0816:                                idata[offset] = components[0];
0817:                                idata[offset + 1] = components[1];
0818:                                idata[offset + 2] = components[2];
0819:                                if (numBands > 3) {
0820:                                    idata[offset + 3] = components[3];
0821:                                }
0822:
0823:                                offset += pixelStride;
0824:                            }
0825:                        }
0826:                        break;
0827:
0828:                    case DataBuffer.TYPE_FLOAT:
0829:                        float fdata[] = new float[rectWidth * rectHeight
0830:                                * numBands];
0831:                        floatDataArrays = new float[numBands][];
0832:                        for (int i = 0; i < numBands; i++) {
0833:                            floatDataArrays[i] = fdata;
0834:                        }
0835:                        odata = null;
0836:                        offset = 0;
0837:                        for (int j = rectY; j < rectY + rectHeight; j++) {
0838:                            for (int i = rectX; i < rectX + rectWidth; i++) {
0839:                                odata = raster.getDataElements(i, j, odata);
0840:
0841:                                theColorModel.getComponents(odata, components,
0842:                                        0);
0843:
0844:                                fdata[offset] = components[0];
0845:                                fdata[offset + 1] = components[1];
0846:                                fdata[offset + 2] = components[2];
0847:                                if (numBands > 3) {
0848:                                    fdata[offset + 3] = components[3];
0849:                                }
0850:                                offset += pixelStride;
0851:                            }
0852:                        }
0853:                        break;
0854:
0855:                    case DataBuffer.TYPE_DOUBLE:
0856:                        double ddata[] = new double[rectWidth * rectHeight
0857:                                * numBands];
0858:                        doubleDataArrays = new double[numBands][];
0859:                        for (int i = 0; i < numBands; i++) {
0860:                            doubleDataArrays[i] = ddata;
0861:                        }
0862:                        odata = null;
0863:                        offset = 0;
0864:                        for (int j = rectY; j < rectY + rectHeight; j++) {
0865:                            for (int i = rectX; i < rectX + rectWidth; i++) {
0866:                                odata = raster.getDataElements(i, j, odata);
0867:
0868:                                theColorModel.getComponents(odata, components,
0869:                                        0);
0870:
0871:                                ddata[offset] = components[0];
0872:                                ddata[offset + 1] = components[1];
0873:                                ddata[offset + 2] = components[2];
0874:                                if (numBands > 3) {
0875:                                    ddata[offset + 3] = components[3];
0876:                                }
0877:                                offset += pixelStride;
0878:                            }
0879:                        }
0880:                        break;
0881:                    }
0882:                } else {
0883:                    // if ((formatTagID & COPY_MASK) == COPIED &&
0884:                    // (formatTagID & EXPANSION_MASK) == UNEXPANDED) {
0885:                    // this has become a catchall case.  Specifically for
0886:                    // Rasters with null colormodels.  So we take out the
0887:                    // if as the boolean clause will get way complicated
0888:                    // otherwise.
0889:                    this .numBands = rft.getNumBands();
0890:                    this .pixelStride = this .numBands;
0891:                    this .scanlineStride = rectWidth * numBands;
0892:                    this .bandDataOffsets = rft.getBandOffsets();
0893:                    this .bandOffsets = this .bandDataOffsets;
0894:
0895:                    switch (formatTagID & DATATYPE_MASK) {
0896:                    case DataBuffer.TYPE_INT:
0897:                        int idata[] = raster.getPixels(rectX, rectY, rectWidth,
0898:                                rectHeight, (int[]) null);
0899:                        intDataArrays = new int[numBands][];
0900:                        for (int i = 0; i < numBands; i++) {
0901:                            intDataArrays[i] = idata;
0902:                        }
0903:                        break;
0904:
0905:                    case DataBuffer.TYPE_FLOAT:
0906:                        float fdata[] = raster.getPixels(rectX, rectY,
0907:                                rectWidth, rectHeight, (float[]) null);
0908:                        floatDataArrays = new float[numBands][];
0909:                        for (int i = 0; i < numBands; i++) {
0910:                            floatDataArrays[i] = fdata;
0911:                        }
0912:                        break;
0913:
0914:                    case DataBuffer.TYPE_DOUBLE:
0915:                        double ddata[] = raster.getPixels(rectX, rectY,
0916:                                rectWidth, rectHeight, (double[]) null);
0917:                        doubleDataArrays = new double[numBands][];
0918:                        for (int i = 0; i < numBands; i++) {
0919:                            doubleDataArrays[i] = ddata;
0920:                        }
0921:                        break;
0922:                    }
0923:                }
0924:            }
0925:
0926:            /** 
0927:             * Returns the x coordinate of the upper-left corner of the 
0928:             * RasterAccessor's accessible area.
0929:             */
0930:            public int getX() {
0931:                return rectX;
0932:            }
0933:
0934:            /** 
0935:             * Returns the y coordinate of the upper-left corner of the
0936:             * RasterAccessor's accessible area.
0937:             */
0938:            public int getY() {
0939:                return rectY;
0940:            }
0941:
0942:            /** Returns the width of the
0943:             * RasterAccessor's accessible area.
0944:             */
0945:            public int getWidth() {
0946:                return rectWidth;
0947:            }
0948:
0949:            /** Returns the height of the 
0950:             * RasterAccessor's accessible area.
0951:             */
0952:            public int getHeight() {
0953:                return rectHeight;
0954:            }
0955:
0956:            /** Returns the numBands of the presented area. */
0957:            public int getNumBands() {
0958:                return numBands;
0959:            }
0960:
0961:            /**
0962:             * Whether the <code>RasterAccessor</code> represents binary data.
0963:             * This occurs when the <code>Raster</code> has a
0964:             * <code>MultiPixelPackedSampleModel</code> with a single band and
0965:             * one bit per pixel.
0966:             *
0967:             * @since JAI 1.1
0968:             */
0969:            public boolean isBinary() {
0970:                return (formatTagID & TAG_BINARY) == TAG_BINARY
0971:                        && ImageUtil.isBinary(raster.getSampleModel());
0972:            }
0973:
0974:            /**
0975:             * For the case of binary data (<code>isBinary()</code> returns
0976:             * <code>true</code>), return the binary data as a packed byte array.
0977:             * The data will be packed as eight bits per byte with no bit offset,
0978:             * i.e., the first bit in each image line will be the left-most of the
0979:             * first byte of the line.  The line stride in bytes will be
0980:             * <code>(int)((getWidth()+7)/8)</code>.  The length of the returned
0981:             * array will be the line stride multiplied by <code>getHeight()</code>
0982:             *
0983:             * @return the binary data as a packed array of bytes with zero offset
0984:             * of <code>null</code> if the data are not binary.
0985:             *
0986:             * @since JAI 1.1
0987:             */
0988:            public byte[] getBinaryDataArray() {
0989:                if (binaryDataArray == null && isBinary()) {
0990:                    binaryDataArray = ImageUtil.getPackedBinaryData(raster,
0991:                            new Rectangle(rectX, rectY, rectWidth, rectHeight));
0992:                }
0993:                return binaryDataArray;
0994:            }
0995:
0996:            /** 
0997:             *  Returns the image data as a byte array.  Non-null only if 
0998:             *  getDataType = DataBuffer.TYPE_BYTE.
0999:             *
1000:             *  <p> For the case of binary data the corresponding instance variable
1001:             *  <code>byteDataArrays</code> will not be initialized until this
1002:             *  method or <code>getByteDataArray(int b)</code> is invoked.  The
1003:             *  binary data will be returned as bytes with value 0 or 1.
1004:             */
1005:            public byte[][] getByteDataArrays() {
1006:                if (byteDataArrays == null && isBinary()) {
1007:                    byte[] bdata = ImageUtil.getUnpackedBinaryData(raster,
1008:                            new Rectangle(rectX, rectY, rectWidth, rectHeight));
1009:                    byteDataArrays = new byte[][] { bdata };
1010:                }
1011:                return byteDataArrays;
1012:            }
1013:
1014:            /** 
1015:             *  Returns the image data as a byte array for a specific band.
1016:             *  Non-null only if getDataType = DataBuffer.TYPE_BYTE.
1017:             */
1018:            public byte[] getByteDataArray(int b) {
1019:                byte[][] bda = getByteDataArrays();
1020:                return (bda == null ? null : bda[b]);
1021:            }
1022:
1023:            /** 
1024:             *  Returns the image data as a short array.  Non-null only if 
1025:             *  getDataType = DataBuffer.TYPE_USHORT or DataBuffer.TYPE_SHORT.
1026:             */
1027:            public short[][] getShortDataArrays() {
1028:                return shortDataArrays;
1029:            }
1030:
1031:            /** 
1032:             *  Returns the image data as a short array for a specific band.
1033:             *  Non-null only if getDataType = DataBuffer.TYPE_USHORT or
1034:             *  DataBuffer.TYPE_SHORT.
1035:             */
1036:            public short[] getShortDataArray(int b) {
1037:                return (shortDataArrays == null ? null : shortDataArrays[b]);
1038:            }
1039:
1040:            /** 
1041:             *  Returns the image data as an int array.  Non-null only if 
1042:             *  getDataType = DataBuffer.TYPE_INT.
1043:             */
1044:            public int[][] getIntDataArrays() {
1045:                return intDataArrays;
1046:            }
1047:
1048:            /** 
1049:             *  Returns the image data as an int array for a specific band.
1050:             *  Non-null only if getDataType = DataBuffer.TYPE_INT.
1051:             */
1052:            public int[] getIntDataArray(int b) {
1053:                return (intDataArrays == null ? null : intDataArrays[b]);
1054:            }
1055:
1056:            /** 
1057:             *  Returns the image data as a float array.  Non-null only if 
1058:             *  getDataType = DataBuffer.TYPE_FLOAT.
1059:             */
1060:            public float[][] getFloatDataArrays() {
1061:                return floatDataArrays;
1062:            }
1063:
1064:            /** 
1065:             *  Returns the image data as a float array for a specific band.
1066:             *  Non-null only if getDataType = DataBuffer.TYPE_FLOAT.
1067:             */
1068:            public float[] getFloatDataArray(int b) {
1069:                return (floatDataArrays == null ? null : floatDataArrays[b]);
1070:            }
1071:
1072:            /** 
1073:             *  Returns the image data as a double array.  Non-null only if 
1074:             *  getDataType = DataBuffer.TYPE_DOUBLE
1075:             */
1076:            public double[][] getDoubleDataArrays() {
1077:                return doubleDataArrays;
1078:            }
1079:
1080:            /** 
1081:             *  Returns the image data as a double array for a specific band.
1082:             *  Non-null only if getDataType = DataBuffer.TYPE_DOUBLE
1083:             */
1084:            public double[] getDoubleDataArray(int b) {
1085:                return (doubleDataArrays == null ? null : doubleDataArrays[b]);
1086:            }
1087:
1088:            /** 
1089:             *  Returns the image data as an Object for a specific band.
1090:             *
1091:             *  @param b The index of the image band of interest.
1092:             */
1093:            public Object getDataArray(int b) {
1094:                Object dataArray = null;
1095:                switch (getDataType()) {
1096:                case DataBuffer.TYPE_BYTE:
1097:                    dataArray = getByteDataArray(b);
1098:                    break;
1099:
1100:                case DataBuffer.TYPE_SHORT:
1101:                case DataBuffer.TYPE_USHORT:
1102:                    dataArray = getShortDataArray(b);
1103:                    break;
1104:
1105:                case DataBuffer.TYPE_INT:
1106:                    dataArray = getIntDataArray(b);
1107:                    break;
1108:
1109:                case DataBuffer.TYPE_FLOAT:
1110:                    dataArray = getFloatDataArray(b);
1111:                    break;
1112:
1113:                case DataBuffer.TYPE_DOUBLE:
1114:                    dataArray = getDoubleDataArray(b);
1115:                    break;
1116:
1117:                default:
1118:                    dataArray = null;
1119:                }
1120:
1121:                return dataArray;
1122:            }
1123:
1124:            /**  Returns the bandDataOffsets into the dataArrays. */
1125:            public int[] getBandOffsets() {
1126:                return bandDataOffsets;
1127:            }
1128:
1129:            /**  
1130:             * Returns the offset of all band's samples from any 
1131:             * pixel offset.
1132:             */
1133:            public int[] getOffsetsForBands() {
1134:                return bandOffsets;
1135:            }
1136:
1137:            /**  
1138:             * Returns the offset of a specific band's first sample into the
1139:             * DataBuffer including the DataBuffer's offset.
1140:             */
1141:            public int getBandOffset(int b) {
1142:                return bandDataOffsets[b];
1143:            }
1144:
1145:            /**  
1146:             * Returns the offset of a specified band's sample from any 
1147:             * pixel offset.
1148:             */
1149:            public int getOffsetForBand(int b) {
1150:                return bandOffsets[b];
1151:            }
1152:
1153:            /**
1154:             * Returns the scanlineStride for the image data.
1155:             *
1156:             * <p> For binary data this stride is applies to the arrays returned by
1157:             * <code>getByteDataArray()</code> and <code>getByteDataArrays()</code>
1158:             * if the data are accessed as bytes; it does not apply to the array
1159:             * returned by <code>getBinaryDataArray()</code> when the data are
1160:             * accessed as bits packed into bytes.
1161:             */
1162:            public int getScanlineStride() {
1163:                return scanlineStride;
1164:            }
1165:
1166:            /** Returns the pixelStride for the image data. */
1167:            public int getPixelStride() {
1168:                return pixelStride;
1169:            }
1170:
1171:            /** 
1172:             *  Returns the data type of the RasterAccessor object. Note that 
1173:             *  this datatype is not necessarily the same data type as the 
1174:             *  underlying raster.
1175:             */
1176:            public int getDataType() {
1177:                return formatTagID & DATATYPE_MASK;
1178:            }
1179:
1180:            /** 
1181:             *  Returns true if the RasterAccessors's data is copied from it's 
1182:             *  raster. 
1183:             */
1184:            public boolean isDataCopy() {
1185:                return ((formatTagID & COPY_MASK) == COPIED);
1186:            }
1187:
1188:            /**
1189:             * For the case of binary data (<code>isBinary()</code> returns
1190:             * <code>true</code>), copy the binary data back into the
1191:             * <code>Raster</code> of the <code>RasterAccessor</code>.  If
1192:             * this method is invoked in the non-binary case it does nothing.
1193:             * Any bit offset in the original <code>SampleModel</code> will be
1194:             * accounted for.
1195:             *
1196:             * @since JAI 1.1
1197:             */
1198:            // Note: ALL branches of this method have been tested. (bpb 10 May 2000)
1199:            public void copyBinaryDataToRaster() {
1200:                if (binaryDataArray == null || !isBinary()) {
1201:                    return;
1202:                }
1203:
1204:                ImageUtil.setPackedBinaryData(binaryDataArray,
1205:                        (WritableRaster) raster, new Rectangle(rectX, rectY,
1206:                                rectWidth, rectHeight));
1207:            }
1208:
1209:            /** 
1210:             *  Copies data back into the RasterAccessor's raster.  Note that 
1211:             *  the data is cast from the intermediate data format to 
1212:             *  the raster's format.  If clamping is needed, the call
1213:             *  clampDataArrays() method needs to be called before 
1214:             *  calling the copyDataToRaster() method.
1215:             *  Note: the raster is expected to be writable - typically a
1216:             *  destination raster - otherwise, a run-time exception will occur.
1217:             *
1218:             * <p> If the data are binary, then the target bit will be set if
1219:             * and only if the corresponding byte is non-zero.
1220:             */
1221:            public void copyDataToRaster() {
1222:                if (isDataCopy()) {
1223:
1224:                    // Writeback should only be necessary on destRasters which
1225:                    // should be writable so this cast should succeed.
1226:                    WritableRaster wr = (WritableRaster) raster;
1227:                    switch (getDataType()) {
1228:                    case DataBuffer.TYPE_BYTE:
1229:                        // Note: ALL branches of this case have been tested.
1230:                        // (bpb 10 May 2000)
1231:                        if (!isBinary()) {
1232:                            // If this exception occurs then there is a logic
1233:                            // error within this accessor since the only case
1234:                            // wherein byte data should be COPIED is when the
1235:                            // data set is binary.
1236:                            throw new RuntimeException(JaiI18N
1237:                                    .getString("RasterAccessor1"));
1238:                        }
1239:
1240:                        // This case only occurs for binary src and dst.
1241:
1242:                        ImageUtil.setUnpackedBinaryData(byteDataArrays[0], wr,
1243:                                new Rectangle(rectX, rectY, rectWidth,
1244:                                        rectHeight));
1245:                        break;
1246:                    case DataBuffer.TYPE_INT:
1247:                        wr.setPixels(rectX, rectY, rectWidth, rectHeight,
1248:                                intDataArrays[0]);
1249:                        break;
1250:
1251:                    case DataBuffer.TYPE_FLOAT:
1252:                        wr.setPixels(rectX, rectY, rectWidth, rectHeight,
1253:                                floatDataArrays[0]);
1254:                        break;
1255:
1256:                    case DataBuffer.TYPE_DOUBLE:
1257:                        wr.setPixels(rectX, rectY, rectWidth, rectHeight,
1258:                                doubleDataArrays[0]);
1259:                        break;
1260:                    }
1261:                }
1262:            }
1263:
1264:            /**
1265:             *  Indicates if the RasterAccessor has a larger dynamic range than
1266:             *  the underlying Raster.  Except in special cases, where the op
1267:             *  knows something special, this call will determine whether or
1268:             *  not clampDataArrays() needs to be called.
1269:             */
1270:            public boolean needsClamping() {
1271:                int bits[] = raster.getSampleModel().getSampleSize();
1272:
1273:                // Do we even need a clamp?  We do if there's any band
1274:                // of the source image stored in that's less than 32 bits
1275:                // and is stored in a byte, short or int format.  (The automatic
1276:                // casts between floats/doubles and 32-bit ints in setPixel()
1277:                // do what we want.)
1278:
1279:                for (int i = 0; i < bits.length; i++) {
1280:                    if (bits[i] < 32) {
1281:                        return true;
1282:                    }
1283:                }
1284:                return false;
1285:            }
1286:
1287:            /**
1288:             * Clamps data array values to a range that the underlying raster
1289:             * can deal with.  For example, if the underlying raster stores
1290:             * data as bytes, but the samples are unpacked into integer arrays by
1291:             * the RasterAccessor for an operation, the operation will
1292:             * need to call clampDataArrays() so that the data in the int
1293:             * arrays is restricted to the range 0..255 before a setPixels()
1294:             * call is made on the underlying raster.  Note that some
1295:             * operations (for example, lookup) can guarantee that their
1296:             * results don't need clamping so they can call
1297:             * RasterAccessor.copyDataToRaster() without first calling this
1298:             * function.
1299:             */
1300:            public void clampDataArrays() {
1301:                int bits[] = raster.getSampleModel().getSampleSize();
1302:
1303:                // Do we even need a clamp?  We do if there's any band
1304:                // of the source image stored in that's less than 32 bits
1305:                // and is stored in a byte, short or int format.  (The automatic
1306:                // casts between floats/doubles and 32-bit ints in setPixel()
1307:                // do what we want.)
1308:
1309:                boolean needClamp = false;
1310:                boolean uniformBitSize = true;
1311:                int bitSize = bits[0];
1312:                for (int i = 0; i < bits.length; i++) {
1313:                    if (bits[i] < 32) {
1314:                        needClamp = true;
1315:                    }
1316:                    if (bits[i] != bitSize) {
1317:                        uniformBitSize = false;
1318:                    }
1319:                }
1320:                if (!needClamp) {
1321:                    return;
1322:                }
1323:
1324:                int dataType = raster.getDataBuffer().getDataType();
1325:                double hiVals[] = new double[bits.length];
1326:                double loVals[] = new double[bits.length];
1327:
1328:                if (dataType == DataBuffer.TYPE_USHORT && uniformBitSize
1329:                        && bits[0] == 16) {
1330:                    for (int i = 0; i < bits.length; i++) {
1331:                        hiVals[i] = (double) 0xFFFF;
1332:                        loVals[i] = (double) 0;
1333:                    }
1334:                } else if (dataType == DataBuffer.TYPE_SHORT && uniformBitSize
1335:                        && bits[0] == 16) {
1336:                    for (int i = 0; i < bits.length; i++) {
1337:                        hiVals[i] = (double) Short.MAX_VALUE;
1338:                        loVals[i] = (double) Short.MIN_VALUE;
1339:                    }
1340:                } else if (dataType == DataBuffer.TYPE_INT && uniformBitSize
1341:                        && bits[0] == 32) {
1342:                    for (int i = 0; i < bits.length; i++) {
1343:                        hiVals[i] = (double) Integer.MAX_VALUE;
1344:                        loVals[i] = (double) Integer.MIN_VALUE;
1345:                    }
1346:                } else {
1347:                    for (int i = 0; i < bits.length; i++) {
1348:                        hiVals[i] = (double) ((1 << bits[i]) - 1);
1349:                        loVals[i] = (double) 0;
1350:                    }
1351:                }
1352:                clampDataArray(hiVals, loVals);
1353:            }
1354:
1355:            private void clampDataArray(double hiVals[], double loVals[]) {
1356:                switch (getDataType()) {
1357:                case DataBuffer.TYPE_INT:
1358:                    clampIntArrays(toIntArray(hiVals), toIntArray(loVals));
1359:                    break;
1360:
1361:                case DataBuffer.TYPE_FLOAT:
1362:                    clampFloatArrays(toFloatArray(hiVals), toFloatArray(loVals));
1363:                    break;
1364:
1365:                case DataBuffer.TYPE_DOUBLE:
1366:                    clampDoubleArrays(hiVals, loVals);
1367:                    break;
1368:                }
1369:            }
1370:
1371:            private int[] toIntArray(double vals[]) {
1372:                int returnVals[] = new int[vals.length];
1373:                for (int i = 0; i < vals.length; i++) {
1374:                    returnVals[i] = (int) vals[i];
1375:                }
1376:                return returnVals;
1377:            }
1378:
1379:            private float[] toFloatArray(double vals[]) {
1380:                float returnVals[] = new float[vals.length];
1381:                for (int i = 0; i < vals.length; i++) {
1382:                    returnVals[i] = (float) vals[i];
1383:                }
1384:                return returnVals;
1385:            }
1386:
1387:            private void clampIntArrays(int hiVals[], int loVals[]) {
1388:                int width = rectWidth;
1389:                int height = rectHeight;
1390:                for (int k = 0; k < numBands; k++) {
1391:                    int data[] = intDataArrays[k];
1392:                    int scanlineOffset = bandDataOffsets[k];
1393:                    int hiVal = hiVals[k];
1394:                    int loVal = loVals[k];
1395:                    for (int j = 0; j < height; j++) {
1396:                        int pixelOffset = scanlineOffset;
1397:                        for (int i = 0; i < width; i++) {
1398:                            int tmp = data[pixelOffset];
1399:                            if (tmp < loVal) {
1400:                                data[pixelOffset] = loVal;
1401:                            } else if (tmp > hiVal) {
1402:                                data[pixelOffset] = hiVal;
1403:                            }
1404:                            pixelOffset += pixelStride;
1405:                        }
1406:                        scanlineOffset += scanlineStride;
1407:                    }
1408:                }
1409:            }
1410:
1411:            private void clampFloatArrays(float hiVals[], float loVals[]) {
1412:                int width = rectWidth;
1413:                int height = rectHeight;
1414:                for (int k = 0; k < numBands; k++) {
1415:                    float data[] = floatDataArrays[k];
1416:                    int scanlineOffset = bandDataOffsets[k];
1417:                    float hiVal = hiVals[k];
1418:                    float loVal = loVals[k];
1419:                    for (int j = 0; j < height; j++) {
1420:                        int pixelOffset = scanlineOffset;
1421:                        for (int i = 0; i < width; i++) {
1422:                            float tmp = data[pixelOffset];
1423:                            if (tmp < loVal) {
1424:                                data[pixelOffset] = loVal;
1425:                            } else if (tmp > hiVal) {
1426:                                data[pixelOffset] = hiVal;
1427:                            }
1428:                            pixelOffset += pixelStride;
1429:                        }
1430:                        scanlineOffset += scanlineStride;
1431:                    }
1432:                }
1433:            }
1434:
1435:            private void clampDoubleArrays(double hiVals[], double loVals[]) {
1436:                int width = rectWidth;
1437:                int height = rectHeight;
1438:                for (int k = 0; k < numBands; k++) {
1439:                    double data[] = doubleDataArrays[k];
1440:                    int scanlineOffset = bandDataOffsets[k];
1441:                    double hiVal = hiVals[k];
1442:                    double loVal = loVals[k];
1443:                    for (int j = 0; j < height; j++) {
1444:                        int pixelOffset = scanlineOffset;
1445:                        for (int i = 0; i < width; i++) {
1446:                            double tmp = data[pixelOffset];
1447:                            if (tmp < loVal) {
1448:                                data[pixelOffset] = loVal;
1449:                            } else if (tmp > hiVal) {
1450:                                data[pixelOffset] = hiVal;
1451:                            }
1452:                            pixelOffset += pixelStride;
1453:                        }
1454:                        scanlineOffset += scanlineStride;
1455:                    }
1456:                }
1457:            }
1458:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.