Source Code Cross Referenced for BytePackedRaster.java in  » 6.0-JDK-Modules-sun » awt » sun » awt » image » 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 sun » awt » sun.awt.image 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.awt.image;
0027:
0028:        import java.awt.image.Raster;
0029:        import java.awt.image.WritableRaster;
0030:        import java.awt.image.RasterFormatException;
0031:        import java.awt.image.SampleModel;
0032:        import java.awt.image.MultiPixelPackedSampleModel;
0033:        import java.awt.image.DataBuffer;
0034:        import java.awt.image.DataBufferByte;
0035:        import java.awt.Rectangle;
0036:        import java.awt.Point;
0037:
0038:        /**
0039:         * This class is useful for describing 1, 2, or 4 bit image data
0040:         * elements.  This raster has one band whose pixels are packed
0041:         * together into individual bytes in a single byte array.  This type
0042:         * of raster can be used with an IndexColorModel. This raster uses a
0043:         * MultiPixelPackedSampleModel.
0044:         *
0045:         * @version 10 Feb 1997
0046:         */
0047:        public class BytePackedRaster extends SunWritableRaster {
0048:
0049:            /** The data bit offset for each pixel. */
0050:            int dataBitOffset;
0051:
0052:            /** Scanline stride of the image data contained in this Raster. */
0053:            int scanlineStride;
0054:
0055:            /**
0056:             * The bit stride of a pixel, equal to the total number of bits
0057:             * required to store a pixel.
0058:             */
0059:            int pixelBitStride;
0060:
0061:            /** The bit mask for extracting the pixel. */
0062:            int bitMask;
0063:
0064:            /** The image data array. */
0065:            byte[] data;
0066:
0067:            /** 8 minus the pixel bit stride. */
0068:            int shiftOffset;
0069:
0070:            int type;
0071:
0072:            /** A cached copy of minX + width for use in bounds checks. */
0073:            private int maxX;
0074:
0075:            /** A cached copy of minY + height for use in bounds checks. */
0076:            private int maxY;
0077:
0078:            static private native void initIDs();
0079:
0080:            static {
0081:                /* ensure that the necessary native libraries are loaded */
0082:                NativeLibLoader.loadLibraries();
0083:                initIDs();
0084:            }
0085:
0086:            /**
0087:             * Constructs a BytePackedRaster with the given SampleModel.
0088:             * The Raster's upper left corner is origin and it is the same
0089:             * size as the SampleModel.  A DataBuffer large enough to describe the
0090:             * Raster is automatically created.  SampleModel must be of type
0091:             * MultiPixelPackedSampleModel.
0092:             * @param sampleModel     The SampleModel that specifies the layout.
0093:             * @param origin          The Point that specified the origin.
0094:             */
0095:            public BytePackedRaster(SampleModel sampleModel, Point origin) {
0096:                this (sampleModel, sampleModel.createDataBuffer(),
0097:                        new Rectangle(origin.x, origin.y, sampleModel
0098:                                .getWidth(), sampleModel.getHeight()), origin,
0099:                        null);
0100:            }
0101:
0102:            /**
0103:             * Constructs a BytePackedRaster with the given SampleModel
0104:             * and DataBuffer.  The Raster's upper left corner is origin and
0105:             * it is the same size as the SampleModel.  The DataBuffer is not
0106:             * initialized and must be a DataBufferByte compatible with SampleModel.
0107:             * SampleModel must be of type MultiPixelPackedSampleModel.
0108:             * @param sampleModel     The SampleModel that specifies the layout.
0109:             * @param dataBuffer      The DataBufferShort that contains the image data.
0110:             * @param origin          The Point that specifies the origin.
0111:             */
0112:            public BytePackedRaster(SampleModel sampleModel,
0113:                    DataBuffer dataBuffer, Point origin) {
0114:                this (sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
0115:                        sampleModel.getWidth(), sampleModel.getHeight()),
0116:                        origin, null);
0117:            }
0118:
0119:            /**
0120:             * Constructs a BytePackedRaster with the given SampleModel,
0121:             * DataBuffer, and parent.  DataBuffer must be a DataBufferByte and
0122:             * SampleModel must be of type MultiPixelPackedSampleModel.
0123:             * When translated into the base Raster's
0124:             * coordinate system, aRegion must be contained by the base Raster.
0125:             * Origin is the coordinate in the new Raster's coordinate system of
0126:             * the origin of the base Raster.  (The base Raster is the Raster's
0127:             * ancestor which has no parent.)
0128:             *
0129:             * Note that this constructor should generally be called by other
0130:             * constructors or create methods, it should not be used directly.
0131:             * @param sampleModel     The SampleModel that specifies the layout.
0132:             * @param dataBuffer      The DataBufferShort that contains the image data.
0133:             * @param aRegion         The Rectangle that specifies the image area.
0134:             * @param origin          The Point that specifies the origin.
0135:             * @param parent          The parent (if any) of this raster.
0136:             *
0137:             * @exception RasterFormatException if the parameters do not conform
0138:             * to requirements of this Raster type.
0139:             */
0140:            public BytePackedRaster(SampleModel sampleModel,
0141:                    DataBuffer dataBuffer, Rectangle aRegion, Point origin,
0142:                    BytePackedRaster parent) {
0143:                super (sampleModel, dataBuffer, aRegion, origin, parent);
0144:                this .maxX = minX + width;
0145:                this .maxY = minY + height;
0146:
0147:                if (!(dataBuffer instanceof  DataBufferByte)) {
0148:                    throw new RasterFormatException(
0149:                            "BytePackedRasters must have" + "byte DataBuffers");
0150:                }
0151:                DataBufferByte dbb = (DataBufferByte) dataBuffer;
0152:                this .data = stealData(dbb, 0);
0153:                if (dbb.getNumBanks() != 1) {
0154:                    throw new RasterFormatException(
0155:                            "DataBuffer for BytePackedRasters"
0156:                                    + " must only have 1 bank.");
0157:                }
0158:                int dbOffset = dbb.getOffset();
0159:
0160:                if (sampleModel instanceof  MultiPixelPackedSampleModel) {
0161:                    MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
0162:                    this .type = IntegerComponentRaster.TYPE_BYTE_BINARY_SAMPLES;
0163:                    pixelBitStride = mppsm.getPixelBitStride();
0164:                    if (pixelBitStride != 1 && pixelBitStride != 2
0165:                            && pixelBitStride != 4) {
0166:                        throw new RasterFormatException(
0167:                                "BytePackedRasters must have a bit depth of 1, 2, or 4");
0168:                    }
0169:                    scanlineStride = mppsm.getScanlineStride();
0170:                    dataBitOffset = mppsm.getDataBitOffset() + dbOffset * 8;
0171:                    int xOffset = aRegion.x - origin.x;
0172:                    int yOffset = aRegion.y - origin.y;
0173:                    dataBitOffset += xOffset * pixelBitStride + yOffset
0174:                            * scanlineStride * 8;
0175:                    bitMask = (1 << pixelBitStride) - 1;
0176:                    shiftOffset = 8 - pixelBitStride;
0177:                } else {
0178:                    throw new RasterFormatException(
0179:                            "BytePackedRasters must have"
0180:                                    + "MultiPixelPackedSampleModel");
0181:                }
0182:                verify(false);
0183:            }
0184:
0185:            /**
0186:             * Returns the data bit offset for the Raster.  The data
0187:             * bit offset is the bit index into the data array element
0188:             * corresponding to the first sample of the first scanline.
0189:             */
0190:            public int getDataBitOffset() {
0191:                return dataBitOffset;
0192:            }
0193:
0194:            /**
0195:             * Returns the scanline stride -- the number of data array elements between
0196:             * a given sample and the sample in the same column
0197:             * of the next row.
0198:             */
0199:            public int getScanlineStride() {
0200:                return scanlineStride;
0201:            }
0202:
0203:            /**
0204:             * Returns pixel bit stride -- the number of bits between two
0205:             * samples on the same scanline.
0206:             */
0207:            public int getPixelBitStride() {
0208:                return pixelBitStride;
0209:            }
0210:
0211:            /**
0212:             * Returns a reference to the entire data array.
0213:             */
0214:            public byte[] getDataStorage() {
0215:                return data;
0216:            }
0217:
0218:            /**
0219:             * Returns the data element at the specified
0220:             * location.  
0221:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0222:             * if the pixel coordinate is out of bounds.
0223:             * A ClassCastException will be thrown if the input object is non null
0224:             * and references anything other than an array of transferType.
0225:             * @param x        The X coordinate of the pixel location.
0226:             * @param y        The Y coordinate of the pixel location.
0227:             * @param outData  An object reference to an array of type defined by
0228:             *                 getTransferType() and length getNumDataElements().
0229:             *                 If null an array of appropriate type and size will be
0230:             *                 allocated.
0231:             * @return         An object reference to an array of type defined by
0232:             *                 getTransferType() with the request pixel data.
0233:             */
0234:            public Object getDataElements(int x, int y, Object obj) {
0235:                if ((x < this .minX) || (y < this .minY) || (x >= this .maxX)
0236:                        || (y >= this .maxY)) {
0237:                    throw new ArrayIndexOutOfBoundsException(
0238:                            "Coordinate out of bounds!");
0239:                }
0240:                byte outData[];
0241:                if (obj == null) {
0242:                    outData = new byte[numDataElements];
0243:                } else {
0244:                    outData = (byte[]) obj;
0245:                }
0246:                int bitnum = dataBitOffset + (x - minX) * pixelBitStride;
0247:                // Fix 4184283
0248:                int element = data[(y - minY) * scanlineStride + (bitnum >> 3)] & 0xff;
0249:                int shift = shiftOffset - (bitnum & 7);
0250:                outData[0] = (byte) ((element >> shift) & bitMask);
0251:                return outData;
0252:            }
0253:
0254:            /**
0255:             * Returns the pixel data for the specified rectangle of pixels in a
0256:             * primitive array of type TransferType.
0257:             * For image data supported by the Java 2D API, this
0258:             * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or
0259:             * DataBuffer.TYPE_INT.  Data may be returned in a packed format,
0260:             * thus increasing efficiency for data transfers.
0261:             * 
0262:             * An ArrayIndexOutOfBoundsException may be thrown
0263:             * if the coordinates are not in bounds.
0264:             * A ClassCastException will be thrown if the input object is non null
0265:             * and references anything other than an array of TransferType.
0266:             * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
0267:             * @param x        The X coordinate of the upper left pixel location.
0268:             * @param y        The Y coordinate of the upper left pixel location.
0269:             * @param w        Width of the pixel rectangle.
0270:             * @param h        Height of the pixel rectangle.
0271:             * @param outData  An object reference to an array of type defined by
0272:             *                 getTransferType() and length w*h*getNumDataElements().  
0273:             *                 If null, an array of appropriate type and size will be
0274:             *                 allocated.
0275:             * @return         An object reference to an array of type defined by
0276:             *                 getTransferType() with the requested pixel data.
0277:             */
0278:            public Object getDataElements(int x, int y, int w, int h,
0279:                    Object outData) {
0280:                return getByteData(x, y, w, h, (byte[]) outData);
0281:            }
0282:
0283:            /**
0284:             * Returns an array  of data elements from the specified rectangular
0285:             * region.
0286:             * 
0287:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0288:             * if the pixel coordinates are out of bounds.
0289:             * A ClassCastException will be thrown if the input object is non null
0290:             * and references anything other than an array of transferType.
0291:             * <pre>
0292:             *       byte[] bandData = (byte[])raster.getPixelData(x, y, w, h, null);
0293:             *       int pixel;
0294:             *       // To find a data element at location (x2, y2)
0295:             *       pixel = bandData[((y2-y)*w + (x2-x))];
0296:             * </pre>
0297:             * @param x        The X coordinate of the upper left pixel location.
0298:             * @param y        The Y coordinate of the upper left pixel location.
0299:             * @param width    Width of the pixel rectangle.
0300:             * @param height   Height of the pixel rectangle.
0301:             * @param outData  An object reference to an array of type defined by
0302:             *                 getTransferType() and length w*h*getNumDataElements().
0303:             *                 If null an array of appropriate type and size will be
0304:             *                 allocated.
0305:             * @return         An object reference to an array of type defined by
0306:             *                 getTransferType() with the request pixel data.
0307:             */
0308:            public Object getPixelData(int x, int y, int w, int h, Object obj) {
0309:                if ((x < this .minX) || (y < this .minY) || (x + w > this .maxX)
0310:                        || (y + h > this .maxY)) {
0311:                    throw new ArrayIndexOutOfBoundsException(
0312:                            "Coordinate out of bounds!");
0313:                }
0314:                byte outData[];
0315:                if (obj == null) {
0316:                    outData = new byte[numDataElements * w * h];
0317:                } else {
0318:                    outData = (byte[]) obj;
0319:                }
0320:                int pixbits = pixelBitStride;
0321:                int scanbit = dataBitOffset + (x - minX) * pixbits;
0322:                int index = (y - minY) * scanlineStride;
0323:                int outindex = 0;
0324:                byte data[] = this .data;
0325:
0326:                for (int j = 0; j < h; j++) {
0327:                    int bitnum = scanbit;
0328:                    for (int i = 0; i < w; i++) {
0329:                        int shift = shiftOffset - (bitnum & 7);
0330:                        outData[outindex++] = (byte) (bitMask & (data[index
0331:                                + (bitnum >> 3)] >> shift));
0332:                        bitnum += pixbits;
0333:                    }
0334:                    index += scanlineStride;
0335:                }
0336:                return outData;
0337:            }
0338:
0339:            /**
0340:             * Returns a byte array containing the specified data elements
0341:             * from the data array.  The band index will be ignored.
0342:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0343:             * if the pixel coordinates are out of bounds.
0344:             * <pre>
0345:             *       byte[] byteData = getByteData(x, y, band, w, h, null);
0346:             *       // To find a data element at location (x2, y2)
0347:             *       byte element = byteData[(y2-y)*w + (x2-x)];
0348:             * </pre>
0349:             * @param x        The X coordinate of the upper left pixel location.
0350:             * @param y        The Y coordinate of the upper left pixel location.
0351:             * @param width    Width of the pixel rectangle.
0352:             * @param height   Height of the pixel rectangle.
0353:             * @param band     The band to return, is ignored.
0354:             * @param outData  If non-null, data elements
0355:             *                 at the specified locations are returned in this array.
0356:             * @return         Byte array with data elements.
0357:             */
0358:            public byte[] getByteData(int x, int y, int w, int h, int band,
0359:                    byte[] outData) {
0360:                return getByteData(x, y, w, h, outData);
0361:            }
0362:
0363:            /**
0364:             * Returns a byte array containing the specified data elements
0365:             * from the data array.
0366:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0367:             * if the pixel coordinates are out of bounds.
0368:             * <pre>
0369:             *       byte[] byteData = raster.getByteData(x, y, w, h, null);
0370:             *       byte pixel;
0371:             *       // To find a data element at location (x2, y2)
0372:             *       pixel = byteData[((y2-y)*w + (x2-x))];
0373:             * </pre>
0374:             * @param x        The X coordinate of the upper left pixel location.
0375:             * @param y        The Y coordinate of the upper left pixel location.
0376:             * @param width    Width of the pixel rectangle.
0377:             * @param height   Height of the pixel rectangle.
0378:             * @param outData  If non-null, data elements
0379:             *                 at the specified locations are returned in this array.
0380:             * @return         Byte array with data elements.
0381:             */
0382:            public byte[] getByteData(int x, int y, int w, int h, byte[] outData) {
0383:                if ((x < this .minX) || (y < this .minY) || (x + w > this .maxX)
0384:                        || (y + h > this .maxY)) {
0385:                    throw new ArrayIndexOutOfBoundsException(
0386:                            "Coordinate out of bounds!");
0387:                }
0388:                if (outData == null) {
0389:                    outData = new byte[w * h];
0390:                }
0391:                int pixbits = pixelBitStride;
0392:                int scanbit = dataBitOffset + (x - minX) * pixbits;
0393:                int index = (y - minY) * scanlineStride;
0394:                int outindex = 0;
0395:                byte data[] = this .data;
0396:
0397:                for (int j = 0; j < h; j++) {
0398:                    int bitnum = scanbit;
0399:                    int element;
0400:
0401:                    // Process initial portion of scanline
0402:                    int i = 0;
0403:                    while ((i < w) && ((bitnum & 7) != 0)) {
0404:                        int shift = shiftOffset - (bitnum & 7);
0405:                        outData[outindex++] = (byte) (bitMask & (data[index
0406:                                + (bitnum >> 3)] >> shift));
0407:                        bitnum += pixbits;
0408:                        i++;
0409:                    }
0410:
0411:                    // Process central portion of scanline 8 pixels at a time
0412:                    int inIndex = index + (bitnum >> 3);
0413:                    switch (pixbits) {
0414:                    case 1:
0415:                        for (; i < w - 7; i += 8) {
0416:                            element = data[inIndex++];
0417:                            outData[outindex++] = (byte) ((element >> 7) & 1);
0418:                            outData[outindex++] = (byte) ((element >> 6) & 1);
0419:                            outData[outindex++] = (byte) ((element >> 5) & 1);
0420:                            outData[outindex++] = (byte) ((element >> 4) & 1);
0421:                            outData[outindex++] = (byte) ((element >> 3) & 1);
0422:                            outData[outindex++] = (byte) ((element >> 2) & 1);
0423:                            outData[outindex++] = (byte) ((element >> 1) & 1);
0424:                            outData[outindex++] = (byte) (element & 1);
0425:                            bitnum += 8;
0426:                        }
0427:                        break;
0428:
0429:                    case 2:
0430:                        for (; i < w - 7; i += 8) {
0431:                            element = data[inIndex++];
0432:                            outData[outindex++] = (byte) ((element >> 6) & 3);
0433:                            outData[outindex++] = (byte) ((element >> 4) & 3);
0434:                            outData[outindex++] = (byte) ((element >> 2) & 3);
0435:                            outData[outindex++] = (byte) (element & 3);
0436:
0437:                            element = data[inIndex++];
0438:                            outData[outindex++] = (byte) ((element >> 6) & 3);
0439:                            outData[outindex++] = (byte) ((element >> 4) & 3);
0440:                            outData[outindex++] = (byte) ((element >> 2) & 3);
0441:                            outData[outindex++] = (byte) (element & 3);
0442:
0443:                            bitnum += 16;
0444:                        }
0445:                        break;
0446:
0447:                    case 4:
0448:                        for (; i < w - 7; i += 8) {
0449:                            element = data[inIndex++];
0450:                            outData[outindex++] = (byte) ((element >> 4) & 0xf);
0451:                            outData[outindex++] = (byte) (element & 0xf);
0452:
0453:                            element = data[inIndex++];
0454:                            outData[outindex++] = (byte) ((element >> 4) & 0xf);
0455:                            outData[outindex++] = (byte) (element & 0xf);
0456:
0457:                            element = data[inIndex++];
0458:                            outData[outindex++] = (byte) ((element >> 4) & 0xf);
0459:                            outData[outindex++] = (byte) (element & 0xf);
0460:
0461:                            element = data[inIndex++];
0462:                            outData[outindex++] = (byte) ((element >> 4) & 0xf);
0463:                            outData[outindex++] = (byte) (element & 0xf);
0464:
0465:                            bitnum += 32;
0466:                        }
0467:                        break;
0468:                    }
0469:
0470:                    // Process final portion of scanline
0471:                    for (; i < w; i++) {
0472:                        int shift = shiftOffset - (bitnum & 7);
0473:                        outData[outindex++] = (byte) (bitMask & (data[index
0474:                                + (bitnum >> 3)] >> shift));
0475:                        bitnum += pixbits;
0476:                    }
0477:
0478:                    index += scanlineStride;
0479:                }
0480:
0481:                return outData;
0482:            }
0483:
0484:            /**
0485:             * Stores the data elements at the specified location.
0486:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0487:             * if the pixel coordinate is out of bounds.
0488:             * A ClassCastException will be thrown if the input object is non null
0489:             * and references anything other than an array of transferType.
0490:             * @param x        The X coordinate of the pixel location.
0491:             * @param y        The Y coordinate of the pixel location.
0492:             * @param inData   An object reference to an array of type defined by
0493:             *                 getTransferType() and length getNumDataElements()
0494:             *                 containing the pixel data to place at x,y.
0495:             */
0496:            public void setDataElements(int x, int y, Object obj) {
0497:                if ((x < this .minX) || (y < this .minY) || (x >= this .maxX)
0498:                        || (y >= this .maxY)) {
0499:                    throw new ArrayIndexOutOfBoundsException(
0500:                            "Coordinate out of bounds!");
0501:                }
0502:                byte inData[] = (byte[]) obj;
0503:                int bitnum = dataBitOffset + (x - minX) * pixelBitStride;
0504:                int index = (y - minY) * scanlineStride + (bitnum >> 3);
0505:                int shift = shiftOffset - (bitnum & 7);
0506:
0507:                byte element = data[index];
0508:                element &= ~(bitMask << shift);
0509:                element |= (inData[0] & bitMask) << shift;
0510:                data[index] = element;
0511:
0512:                markDirty();
0513:            }
0514:
0515:            /**
0516:             * Stores the Raster data at the specified location.
0517:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0518:             * if the pixel coordinates are out of bounds.
0519:             * @param x          The X coordinate of the pixel location.
0520:             * @param y          The Y coordinate of the pixel location.
0521:             * @param inRaster   Raster of data to place at x,y location.
0522:             */
0523:            public void setDataElements(int x, int y, Raster inRaster) {
0524:                // Check if we can use fast code
0525:                if (!(inRaster instanceof  BytePackedRaster)
0526:                        || ((BytePackedRaster) inRaster).pixelBitStride != pixelBitStride) {
0527:                    super .setDataElements(x, y, inRaster);
0528:                    return;
0529:                }
0530:
0531:                int srcOffX = inRaster.getMinX();
0532:                int srcOffY = inRaster.getMinY();
0533:                int dstOffX = srcOffX + x;
0534:                int dstOffY = srcOffY + y;
0535:                int width = inRaster.getWidth();
0536:                int height = inRaster.getHeight();
0537:                if ((dstOffX < this .minX) || (dstOffY < this .minY)
0538:                        || (dstOffX + width > this .maxX)
0539:                        || (dstOffY + height > this .maxY)) {
0540:                    throw new ArrayIndexOutOfBoundsException(
0541:                            "Coordinate out of bounds!");
0542:                }
0543:                setDataElements(dstOffX, dstOffY, srcOffX, srcOffY, width,
0544:                        height, (BytePackedRaster) inRaster);
0545:            }
0546:
0547:            /**
0548:             * Stores the Raster data at the specified location.
0549:             * @param dstX The absolute X coordinate of the destination pixel
0550:             * that will receive a copy of the upper-left pixel of the
0551:             * inRaster
0552:             * @param dstY The absolute Y coordinate of the destination pixel
0553:             * that will receive a copy of the upper-left pixel of the
0554:             * inRaster
0555:             * @param srcX The absolute X coordinate of the upper-left source
0556:             * pixel that will be copied into this Raster
0557:             * @param srcY The absolute Y coordinate of the upper-left source
0558:             * pixel that will be copied into this Raster
0559:             * @param width      The number of pixels to store horizontally
0560:             * @param height     The number of pixels to store vertically
0561:             * @param inRaster   BytePackedRaster of data to place at x,y location.
0562:             */
0563:            private void setDataElements(int dstX, int dstY, int srcX,
0564:                    int srcY, int width, int height, BytePackedRaster inRaster) {
0565:                // Assume bounds checking has been performed previously
0566:                if (width <= 0 || height <= 0) {
0567:                    return;
0568:                }
0569:
0570:                byte[] inData = inRaster.data;
0571:                byte[] outData = this .data;
0572:
0573:                int inscan = inRaster.scanlineStride;
0574:                int outscan = this .scanlineStride;
0575:                int inbit = inRaster.dataBitOffset + 8 * (srcY - inRaster.minY)
0576:                        * inscan + (srcX - inRaster.minX)
0577:                        * inRaster.pixelBitStride;
0578:                int outbit = (this .dataBitOffset + 8 * (dstY - minY) * outscan + (dstX - minX)
0579:                        * this .pixelBitStride);
0580:                int copybits = width * pixelBitStride;
0581:
0582:                // Check whether the same bit alignment is present in both
0583:                // Rasters; if so, we can copy whole bytes using
0584:                // System.arraycopy.  If not, we must do a "funnel shift"
0585:                // where adjacent bytes contribute to each destination byte.
0586:                if ((inbit & 7) == (outbit & 7)) {
0587:                    // copy is bit aligned
0588:                    int bitpos = outbit & 7;
0589:                    if (bitpos != 0) {
0590:                        int bits = 8 - bitpos;
0591:                        // Copy partial bytes on left
0592:                        int inbyte = inbit >> 3;
0593:                        int outbyte = outbit >> 3;
0594:                        int mask = 0xff >> bitpos;
0595:                        if (copybits < bits) {
0596:                            // Fix bug 4399076: previously had '8 - copybits' instead
0597:                            // of 'bits - copybits'.
0598:                            //
0599:                            // Prior to the this expression, 'mask' has its rightmost
0600:                            // 'bits' bits set to '1'.  We want it to have a total
0601:                            // of 'copybits' bits set, therefore we want to introduce
0602:                            // 'bits - copybits' zeroes on the right.
0603:                            mask &= 0xff << (bits - copybits);
0604:                            bits = copybits;
0605:                        }
0606:                        for (int j = 0; j < height; j++) {
0607:                            int element = outData[outbyte];
0608:                            element &= ~mask;
0609:                            element |= (inData[inbyte] & mask);
0610:                            outData[outbyte] = (byte) element;
0611:                            inbyte += inscan;
0612:                            outbyte += outscan;
0613:                        }
0614:                        inbit += bits;
0615:                        outbit += bits;
0616:                        copybits -= bits;
0617:                    }
0618:                    if (copybits >= 8) {
0619:                        // Copy whole bytes
0620:                        int inbyte = inbit >> 3;
0621:                        int outbyte = outbit >> 3;
0622:                        int copybytes = copybits >> 3;
0623:                        if (copybytes == inscan && inscan == outscan) {
0624:                            System.arraycopy(inData, inbyte, outData, outbyte,
0625:                                    inscan * height);
0626:                        } else {
0627:                            for (int j = 0; j < height; j++) {
0628:                                System.arraycopy(inData, inbyte, outData,
0629:                                        outbyte, copybytes);
0630:                                inbyte += inscan;
0631:                                outbyte += outscan;
0632:                            }
0633:                        }
0634:
0635:                        int bits = copybytes * 8;
0636:                        inbit += bits;
0637:                        outbit += bits;
0638:                        copybits -= bits;
0639:                    }
0640:                    if (copybits > 0) {
0641:                        // Copy partial bytes on right
0642:                        int inbyte = inbit >> 3;
0643:                        int outbyte = outbit >> 3;
0644:                        int mask = (0xff00 >> copybits) & 0xff;
0645:                        for (int j = 0; j < height; j++) {
0646:                            int element = outData[outbyte];
0647:                            element &= ~mask;
0648:                            element |= (inData[inbyte] & mask);
0649:                            outData[outbyte] = (byte) element;
0650:                            inbyte += inscan;
0651:                            outbyte += outscan;
0652:                        }
0653:                    }
0654:                } else {
0655:                    // Unaligned case, see RFE #4284166
0656:                    // Note that the code in that RFE is not correct
0657:
0658:                    // Insert bits into the first byte of the output
0659:                    // if either the starting bit position is not zero or
0660:                    // we are writing fewer than 8 bits in total
0661:                    int bitpos = outbit & 7;
0662:                    if (bitpos != 0 || copybits < 8) {
0663:                        int bits = 8 - bitpos;
0664:                        int inbyte = inbit >> 3;
0665:                        int outbyte = outbit >> 3;
0666:
0667:                        int lshift = inbit & 7;
0668:                        int rshift = 8 - lshift;
0669:                        int mask = 0xff >> bitpos;
0670:                        if (copybits < bits) {
0671:                            // Fix mask if we're only writing a partial byte
0672:                            mask &= 0xff << (bits - copybits);
0673:                            bits = copybits;
0674:                        }
0675:                        int lastByte = inData.length - 1;
0676:                        for (int j = 0; j < height; j++) {
0677:                            // Read two bytes from the source if possible
0678:                            // Don't worry about going over a scanline boundary
0679:                            // since any extra bits won't get used anyway
0680:                            byte inData0 = inData[inbyte];
0681:                            byte inData1 = (byte) 0;
0682:                            if (inbyte < lastByte) {
0683:                                inData1 = inData[inbyte + 1];
0684:                            }
0685:
0686:                            // Insert the new bits into the output
0687:                            int element = outData[outbyte];
0688:                            element &= ~mask;
0689:                            element |= (((inData0 << lshift) | ((inData1 & 0xff) >> rshift)) >> bitpos)
0690:                                    & mask;
0691:                            outData[outbyte] = (byte) element;
0692:                            inbyte += inscan;
0693:                            outbyte += outscan;
0694:                        }
0695:
0696:                        inbit += bits;
0697:                        outbit += bits;
0698:                        copybits -= bits;
0699:                    }
0700:
0701:                    // Now we have outbit & 7 == 0 so we can write
0702:                    // complete bytes for a while 
0703:
0704:                    // Make sure we have work to do in the central loop
0705:                    // to avoid reading past the end of the scanline 
0706:                    if (copybits >= 8) {
0707:                        int inbyte = inbit >> 3;
0708:                        int outbyte = outbit >> 3;
0709:                        int copybytes = copybits >> 3;
0710:                        int lshift = inbit & 7;
0711:                        int rshift = 8 - lshift;
0712:
0713:                        for (int j = 0; j < height; j++) {
0714:                            int ibyte = inbyte + j * inscan;
0715:                            int obyte = outbyte + j * outscan;
0716:
0717:                            int inData0 = inData[ibyte];
0718:                            // Combine adjacent bytes while 8 or more bits left
0719:                            for (int i = 0; i < copybytes; i++) {
0720:                                int inData1 = inData[ibyte + 1];
0721:                                int val = (inData0 << lshift)
0722:                                        | ((inData1 & 0xff) >> rshift);
0723:                                outData[obyte] = (byte) val;
0724:                                inData0 = inData1;
0725:
0726:                                ++ibyte;
0727:                                ++obyte;
0728:                            }
0729:                        }
0730:
0731:                        int bits = copybytes * 8;
0732:                        inbit += bits;
0733:                        outbit += bits;
0734:                        copybits -= bits;
0735:                    }
0736:
0737:                    // Finish last byte 
0738:                    if (copybits > 0) {
0739:                        int inbyte = inbit >> 3;
0740:                        int outbyte = outbit >> 3;
0741:                        int mask = (0xff00 >> copybits) & 0xff;
0742:                        int lshift = inbit & 7;
0743:                        int rshift = 8 - lshift;
0744:
0745:                        int lastByte = inData.length - 1;
0746:                        for (int j = 0; j < height; j++) {
0747:                            byte inData0 = inData[inbyte];
0748:                            byte inData1 = (byte) 0;
0749:                            if (inbyte < lastByte) {
0750:                                inData1 = inData[inbyte + 1];
0751:                            }
0752:
0753:                            // Insert the new bits into the output
0754:                            int element = outData[outbyte];
0755:                            element &= ~mask;
0756:                            element |= ((inData0 << lshift) | ((inData1 & 0xff) >> rshift))
0757:                                    & mask;
0758:                            outData[outbyte] = (byte) element;
0759:
0760:                            inbyte += inscan;
0761:                            outbyte += outscan;
0762:                        }
0763:                    }
0764:                }
0765:
0766:                markDirty();
0767:            }
0768:
0769:            /**
0770:             * Copies pixels from Raster srcRaster to this WritableRaster.
0771:             * For each (x, y) address in srcRaster, the corresponding pixel
0772:             * is copied to address (x+dx, y+dy) in this WritableRaster,
0773:             * unless (x+dx, y+dy) falls outside the bounds of this raster.
0774:             * srcRaster must have the same number of bands as this WritableRaster.
0775:             * The copy is a simple copy of source samples to the corresponding
0776:             * destination samples.  For details, see
0777:             * {@link WritableRaster#setRect(Raster)}.
0778:             *
0779:             * @param dx        The X translation factor from src space to dst space
0780:             *                  of the copy.
0781:             * @param dy        The Y translation factor from src space to dst space
0782:             *                  of the copy.
0783:             * @param srcRaster The Raster from which to copy pixels.
0784:             */
0785:            public void setRect(int dx, int dy, Raster srcRaster) {
0786:                // Check if we can use fast code
0787:                if (!(srcRaster instanceof  BytePackedRaster)
0788:                        || ((BytePackedRaster) srcRaster).pixelBitStride != pixelBitStride) {
0789:                    super .setRect(dx, dy, srcRaster);
0790:                    return;
0791:                }
0792:
0793:                int width = srcRaster.getWidth();
0794:                int height = srcRaster.getHeight();
0795:                int srcOffX = srcRaster.getMinX();
0796:                int srcOffY = srcRaster.getMinY();
0797:                int dstOffX = dx + srcOffX;
0798:                int dstOffY = dy + srcOffY;
0799:
0800:                // Clip to this raster
0801:                if (dstOffX < this .minX) {
0802:                    int skipX = this .minX - dstOffX;
0803:                    width -= skipX;
0804:                    srcOffX += skipX;
0805:                    dstOffX = this .minX;
0806:                }
0807:                if (dstOffY < this .minY) {
0808:                    int skipY = this .minY - dstOffY;
0809:                    height -= skipY;
0810:                    srcOffY += skipY;
0811:                    dstOffY = this .minY;
0812:                }
0813:                if (dstOffX + width > this .maxX) {
0814:                    width = this .maxX - dstOffX;
0815:                }
0816:                if (dstOffY + height > this .maxY) {
0817:                    height = this .maxY - dstOffY;
0818:                }
0819:
0820:                setDataElements(dstOffX, dstOffY, srcOffX, srcOffY, width,
0821:                        height, (BytePackedRaster) srcRaster);
0822:            }
0823:
0824:            /**
0825:             * Stores an array of data elements into the specified rectangular
0826:             * region.
0827:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0828:             * if the pixel coordinates are out of bounds.
0829:             * A ClassCastException will be thrown if the input object is non null
0830:             * and references anything other than an array of transferType.
0831:             * The data elements in the
0832:             * data array are assumed to be packed.  That is, a data element
0833:             * at location (x2, y2) would be found at:
0834:             * <pre>
0835:             *      inData[((y2-y)*w + (x2-x))]
0836:             * </pre>
0837:             * @param x        The X coordinate of the upper left pixel location.
0838:             * @param y        The Y coordinate of the upper left pixel location.
0839:             * @param w        Width of the pixel rectangle.
0840:             * @param h        Height of the pixel rectangle.
0841:             * @param inData   An object reference to an array of type defined by
0842:             *                 getTransferType() and length w*h*getNumDataElements()
0843:             *                 containing the pixel data to place between x,y and
0844:             *                 x+h, y+h.
0845:             */
0846:            public void setDataElements(int x, int y, int w, int h, Object obj) {
0847:                putByteData(x, y, w, h, (byte[]) obj);
0848:            }
0849:
0850:            /**
0851:             * Stores a byte array of data elements into the specified rectangular
0852:             * region.  The band index will be ignored.
0853:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0854:             * if the pixel coordinates are out of bounds.
0855:             * The data elements in the
0856:             * data array are assumed to be packed.  That is, a data element
0857:             * at location (x2, y2) would be found at:
0858:             * <pre>
0859:             *      inData[((y2-y)*w + (x2-x))]
0860:             * </pre>
0861:             * @param x        The X coordinate of the upper left pixel location.
0862:             * @param y        The Y coordinate of the upper left pixel location.
0863:             * @param w        Width of the pixel rectangle.
0864:             * @param h        Height of the pixel rectangle.
0865:             * @param band     The band to set, is ignored.
0866:             * @param inData   The data elements to be stored.
0867:             */
0868:            public void putByteData(int x, int y, int w, int h, int band,
0869:                    byte[] inData) {
0870:                putByteData(x, y, w, h, inData);
0871:            }
0872:
0873:            /**
0874:             * Stores a byte array of data elements into the specified rectangular
0875:             * region.
0876:             * An ArrayIndexOutOfBounds exception will be thrown at runtime
0877:             * if the pixel coordinates are out of bounds.
0878:             * The data elements in the
0879:             * data array are assumed to be packed.  That is, a data element
0880:             * at location (x2, y2) would be found at:
0881:             * <pre>
0882:             *      inData[((y2-y)*w + (x2-x))]
0883:             * </pre>
0884:             * @param x        The X coordinate of the upper left pixel location.
0885:             * @param y        The Y coordinate of the upper left pixel location.
0886:             * @param w        Width of the pixel rectangle.
0887:             * @param h        Height of the pixel rectangle.
0888:             * @param inData   The data elements to be stored.
0889:             */
0890:            public void putByteData(int x, int y, int w, int h, byte[] inData) {
0891:                if ((x < this .minX) || (y < this .minY) || (x + w > this .maxX)
0892:                        || (y + h > this .maxY)) {
0893:                    throw new ArrayIndexOutOfBoundsException(
0894:                            "Coordinate out of bounds!");
0895:                }
0896:                if (w == 0 || h == 0) {
0897:                    return;
0898:                }
0899:
0900:                int pixbits = pixelBitStride;
0901:                int scanbit = dataBitOffset + (x - minX) * pixbits;
0902:                int index = (y - minY) * scanlineStride;
0903:                int outindex = 0;
0904:                byte data[] = this .data;
0905:                for (int j = 0; j < h; j++) {
0906:                    int bitnum = scanbit;
0907:                    int element;
0908:
0909:                    // Process initial portion of scanline
0910:                    int i = 0;
0911:                    while ((i < w) && ((bitnum & 7) != 0)) {
0912:                        int shift = shiftOffset - (bitnum & 7);
0913:                        element = data[index + (bitnum >> 3)];
0914:                        element &= ~(bitMask << shift);
0915:                        element |= (inData[outindex++] & bitMask) << shift;
0916:                        data[index + (bitnum >> 3)] = (byte) element;
0917:
0918:                        bitnum += pixbits;
0919:                        i++;
0920:                    }
0921:
0922:                    // Process central portion of scanline 8 pixels at a time
0923:                    int inIndex = index + (bitnum >> 3);
0924:                    switch (pixbits) {
0925:                    case 1:
0926:                        for (; i < w - 7; i += 8) {
0927:                            element = (inData[outindex++] & 1) << 7;
0928:                            element |= (inData[outindex++] & 1) << 6;
0929:                            element |= (inData[outindex++] & 1) << 5;
0930:                            element |= (inData[outindex++] & 1) << 4;
0931:                            element |= (inData[outindex++] & 1) << 3;
0932:                            element |= (inData[outindex++] & 1) << 2;
0933:                            element |= (inData[outindex++] & 1) << 1;
0934:                            element |= (inData[outindex++] & 1);
0935:
0936:                            data[inIndex++] = (byte) element;
0937:
0938:                            bitnum += 8;
0939:                        }
0940:                        break;
0941:
0942:                    case 2:
0943:                        for (; i < w - 7; i += 8) {
0944:                            element = (inData[outindex++] & 3) << 6;
0945:                            element |= (inData[outindex++] & 3) << 4;
0946:                            element |= (inData[outindex++] & 3) << 2;
0947:                            element |= (inData[outindex++] & 3);
0948:                            data[inIndex++] = (byte) element;
0949:
0950:                            element = (inData[outindex++] & 3) << 6;
0951:                            element |= (inData[outindex++] & 3) << 4;
0952:                            element |= (inData[outindex++] & 3) << 2;
0953:                            element |= (inData[outindex++] & 3);
0954:                            data[inIndex++] = (byte) element;
0955:
0956:                            bitnum += 16;
0957:                        }
0958:                        break;
0959:
0960:                    case 4:
0961:                        for (; i < w - 7; i += 8) {
0962:                            element = (inData[outindex++] & 0xf) << 4;
0963:                            element |= (inData[outindex++] & 0xf);
0964:                            data[inIndex++] = (byte) element;
0965:
0966:                            element = (inData[outindex++] & 0xf) << 4;
0967:                            element |= (inData[outindex++] & 0xf);
0968:                            data[inIndex++] = (byte) element;
0969:
0970:                            element = (inData[outindex++] & 0xf) << 4;
0971:                            element |= (inData[outindex++] & 0xf);
0972:                            data[inIndex++] = (byte) element;
0973:
0974:                            element = (inData[outindex++] & 0xf) << 4;
0975:                            element |= (inData[outindex++] & 0xf);
0976:                            data[inIndex++] = (byte) element;
0977:
0978:                            bitnum += 32;
0979:                        }
0980:                        break;
0981:                    }
0982:
0983:                    // Process final portion of scanline
0984:                    for (; i < w; i++) {
0985:                        int shift = shiftOffset - (bitnum & 7);
0986:
0987:                        element = data[index + (bitnum >> 3)];
0988:                        element &= ~(bitMask << shift);
0989:                        element |= (inData[outindex++] & bitMask) << shift;
0990:                        data[index + (bitnum >> 3)] = (byte) element;
0991:
0992:                        bitnum += pixbits;
0993:                    }
0994:
0995:                    index += scanlineStride;
0996:                }
0997:
0998:                markDirty();
0999:            }
1000:
1001:            /** 
1002:             * Returns an int array containing all samples for a rectangle of pixels,
1003:             * one sample per array element.
1004:             * An ArrayIndexOutOfBoundsException may be thrown
1005:             * if the coordinates are not in bounds.
1006:             * @param x,&nbsp;y   the coordinates of the upper-left pixel location
1007:             * @param w      Width of the pixel rectangle
1008:             * @param h      Height of the pixel rectangle
1009:             * @param iArray An optionally pre-allocated int array
1010:             * @return the samples for the specified rectangle of pixels.
1011:             */
1012:            public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
1013:                if ((x < this .minX) || (y < this .minY) || (x + w > this .maxX)
1014:                        || (y + h > this .maxY)) {
1015:                    throw new ArrayIndexOutOfBoundsException(
1016:                            "Coordinate out of bounds!");
1017:                }
1018:                if (iArray == null) {
1019:                    iArray = new int[w * h];
1020:                }
1021:                int pixbits = pixelBitStride;
1022:                int scanbit = dataBitOffset + (x - minX) * pixbits;
1023:                int index = (y - minY) * scanlineStride;
1024:                int outindex = 0;
1025:                byte data[] = this .data;
1026:
1027:                for (int j = 0; j < h; j++) {
1028:                    int bitnum = scanbit;
1029:                    int element;
1030:
1031:                    // Process initial portion of scanline
1032:                    int i = 0;
1033:                    while ((i < w) && ((bitnum & 7) != 0)) {
1034:                        int shift = shiftOffset - (bitnum & 7);
1035:                        iArray[outindex++] = bitMask
1036:                                & (data[index + (bitnum >> 3)] >> shift);
1037:                        bitnum += pixbits;
1038:                        i++;
1039:                    }
1040:
1041:                    // Process central portion of scanline 8 pixels at a time
1042:                    int inIndex = index + (bitnum >> 3);
1043:                    switch (pixbits) {
1044:                    case 1:
1045:                        for (; i < w - 7; i += 8) {
1046:                            element = data[inIndex++];
1047:                            iArray[outindex++] = (element >> 7) & 1;
1048:                            iArray[outindex++] = (element >> 6) & 1;
1049:                            iArray[outindex++] = (element >> 5) & 1;
1050:                            iArray[outindex++] = (element >> 4) & 1;
1051:                            iArray[outindex++] = (element >> 3) & 1;
1052:                            iArray[outindex++] = (element >> 2) & 1;
1053:                            iArray[outindex++] = (element >> 1) & 1;
1054:                            iArray[outindex++] = element & 1;
1055:                            bitnum += 8;
1056:                        }
1057:                        break;
1058:
1059:                    case 2:
1060:                        for (; i < w - 7; i += 8) {
1061:                            element = data[inIndex++];
1062:                            iArray[outindex++] = (element >> 6) & 3;
1063:                            iArray[outindex++] = (element >> 4) & 3;
1064:                            iArray[outindex++] = (element >> 2) & 3;
1065:                            iArray[outindex++] = element & 3;
1066:
1067:                            element = data[inIndex++];
1068:                            iArray[outindex++] = (element >> 6) & 3;
1069:                            iArray[outindex++] = (element >> 4) & 3;
1070:                            iArray[outindex++] = (element >> 2) & 3;
1071:                            iArray[outindex++] = element & 3;
1072:
1073:                            bitnum += 16;
1074:                        }
1075:                        break;
1076:
1077:                    case 4:
1078:                        for (; i < w - 7; i += 8) {
1079:                            element = data[inIndex++];
1080:                            iArray[outindex++] = (element >> 4) & 0xf;
1081:                            iArray[outindex++] = element & 0xf;
1082:
1083:                            element = data[inIndex++];
1084:                            iArray[outindex++] = (element >> 4) & 0xf;
1085:                            iArray[outindex++] = element & 0xf;
1086:
1087:                            element = data[inIndex++];
1088:                            iArray[outindex++] = (element >> 4) & 0xf;
1089:                            iArray[outindex++] = element & 0xf;
1090:
1091:                            element = data[inIndex++];
1092:                            iArray[outindex++] = (element >> 4) & 0xf;
1093:                            iArray[outindex++] = element & 0xf;
1094:
1095:                            bitnum += 32;
1096:                        }
1097:                        break;
1098:                    }
1099:
1100:                    // Process final portion of scanline
1101:                    for (; i < w; i++) {
1102:                        int shift = shiftOffset - (bitnum & 7);
1103:                        iArray[outindex++] = bitMask
1104:                                & (data[index + (bitnum >> 3)] >> shift);
1105:                        bitnum += pixbits;
1106:                    }
1107:
1108:                    index += scanlineStride;
1109:                }
1110:
1111:                return iArray;
1112:            }
1113:
1114:            /** 
1115:             * Sets all samples for a rectangle of pixels from an int array containing
1116:             * one sample per array element.
1117:             * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1118:             * not in bounds.
1119:             * @param x        The X coordinate of the upper left pixel location.
1120:             * @param y        The Y coordinate of the upper left pixel location.
1121:             * @param w        Width of the pixel rectangle.
1122:             * @param h        Height of the pixel rectangle.
1123:             * @param iArray   The input int pixel array.
1124:             */
1125:            public void setPixels(int x, int y, int w, int h, int iArray[]) {
1126:                if ((x < this .minX) || (y < this .minY) || (x + w > this .maxX)
1127:                        || (y + h > this .maxY)) {
1128:                    throw new ArrayIndexOutOfBoundsException(
1129:                            "Coordinate out of bounds!");
1130:                }
1131:                int pixbits = pixelBitStride;
1132:                int scanbit = dataBitOffset + (x - minX) * pixbits;
1133:                int index = (y - minY) * scanlineStride;
1134:                int outindex = 0;
1135:                byte data[] = this .data;
1136:                for (int j = 0; j < h; j++) {
1137:                    int bitnum = scanbit;
1138:                    int element;
1139:
1140:                    // Process initial portion of scanline
1141:                    int i = 0;
1142:                    while ((i < w) && ((bitnum & 7) != 0)) {
1143:                        int shift = shiftOffset - (bitnum & 7);
1144:                        element = data[index + (bitnum >> 3)];
1145:                        element &= ~(bitMask << shift);
1146:                        element |= (iArray[outindex++] & bitMask) << shift;
1147:                        data[index + (bitnum >> 3)] = (byte) element;
1148:
1149:                        bitnum += pixbits;
1150:                        i++;
1151:                    }
1152:
1153:                    // Process central portion of scanline 8 pixels at a time
1154:                    int inIndex = index + (bitnum >> 3);
1155:                    switch (pixbits) {
1156:                    case 1:
1157:                        for (; i < w - 7; i += 8) {
1158:                            element = (iArray[outindex++] & 1) << 7;
1159:                            element |= (iArray[outindex++] & 1) << 6;
1160:                            element |= (iArray[outindex++] & 1) << 5;
1161:                            element |= (iArray[outindex++] & 1) << 4;
1162:                            element |= (iArray[outindex++] & 1) << 3;
1163:                            element |= (iArray[outindex++] & 1) << 2;
1164:                            element |= (iArray[outindex++] & 1) << 1;
1165:                            element |= (iArray[outindex++] & 1);
1166:                            data[inIndex++] = (byte) element;
1167:
1168:                            bitnum += 8;
1169:                        }
1170:                        break;
1171:
1172:                    case 2:
1173:                        for (; i < w - 7; i += 8) {
1174:                            element = (iArray[outindex++] & 3) << 6;
1175:                            element |= (iArray[outindex++] & 3) << 4;
1176:                            element |= (iArray[outindex++] & 3) << 2;
1177:                            element |= (iArray[outindex++] & 3);
1178:                            data[inIndex++] = (byte) element;
1179:
1180:                            element = (iArray[outindex++] & 3) << 6;
1181:                            element |= (iArray[outindex++] & 3) << 4;
1182:                            element |= (iArray[outindex++] & 3) << 2;
1183:                            element |= (iArray[outindex++] & 3);
1184:                            data[inIndex++] = (byte) element;
1185:
1186:                            bitnum += 16;
1187:                        }
1188:                        break;
1189:
1190:                    case 4:
1191:                        for (; i < w - 7; i += 8) {
1192:                            element = (iArray[outindex++] & 0xf) << 4;
1193:                            element |= (iArray[outindex++] & 0xf);
1194:                            data[inIndex++] = (byte) element;
1195:
1196:                            element = (iArray[outindex++] & 0xf) << 4;
1197:                            element |= (iArray[outindex++] & 0xf);
1198:                            data[inIndex++] = (byte) element;
1199:
1200:                            element = (iArray[outindex++] & 0xf) << 4;
1201:                            element |= (iArray[outindex++] & 0xf);
1202:                            data[inIndex++] = (byte) element;
1203:
1204:                            element = (iArray[outindex++] & 0xf) << 4;
1205:                            element |= (iArray[outindex++] & 0xf);
1206:                            data[inIndex++] = (byte) element;
1207:
1208:                            bitnum += 32;
1209:                        }
1210:                        break;
1211:                    }
1212:
1213:                    // Process final portion of scanline
1214:                    for (; i < w; i++) {
1215:                        int shift = shiftOffset - (bitnum & 7);
1216:
1217:                        element = data[index + (bitnum >> 3)];
1218:                        element &= ~(bitMask << shift);
1219:                        element |= (iArray[outindex++] & bitMask) << shift;
1220:                        data[index + (bitnum >> 3)] = (byte) element;
1221:
1222:                        bitnum += pixbits;
1223:                    }
1224:
1225:                    index += scanlineStride;
1226:                }
1227:
1228:                markDirty();
1229:            }
1230:
1231:            /**
1232:             * Creates a subraster given a region of the raster.  The x and y
1233:             * coordinates specify the horizontal and vertical offsets
1234:             * from the upper-left corner of this raster to the upper-left corner
1235:             * of the subraster.  Note that the subraster will reference the same
1236:             * DataBuffer as the parent raster, but using different offsets. The
1237:             * bandList is ignored.
1238:             * @param x               X offset.
1239:             * @param y               Y offset.
1240:             * @param width           Width (in pixels) of the subraster.
1241:             * @param height          Height (in pixels) of the subraster.
1242:             * @param x0              Translated X origin of the subraster.
1243:             * @param y0              Translated Y origin of the subraster.
1244:             * @param bandList        Array of band indices.
1245:             * @exception RasterFormatException
1246:             *            if the specified bounding box is outside of the parent raster.
1247:             */
1248:            public Raster createChild(int x, int y, int width, int height,
1249:                    int x0, int y0, int[] bandList) {
1250:                WritableRaster newRaster = createWritableChild(x, y, width,
1251:                        height, x0, y0, bandList);
1252:                return (Raster) newRaster;
1253:            }
1254:
1255:            /**
1256:             * Creates a Writable subRaster given a region of the Raster. The x and y
1257:             * coordinates specify the horizontal and vertical offsets
1258:             * from the upper-left corner of this Raster to the upper-left corner
1259:             * of the subRaster.  The bandList is ignored.
1260:             * A translation to the subRaster may also be specified.
1261:             * Note that the subRaster will reference the same
1262:             * DataBuffer as the parent Raster, but using different offsets.
1263:             * @param x               X offset.
1264:             * @param y               Y offset.
1265:             * @param width           Width (in pixels) of the subraster.
1266:             * @param height          Height (in pixels) of the subraster.
1267:             * @param x0              Translated X origin of the subraster.
1268:             * @param y0              Translated Y origin of the subraster.
1269:             * @param bandList        Array of band indices.
1270:             * @exception RasterFormatException
1271:             *            if the specified bounding box is outside of the parent Raster.
1272:             */
1273:            public WritableRaster createWritableChild(int x, int y, int width,
1274:                    int height, int x0, int y0, int[] bandList) {
1275:                if (x < this .minX) {
1276:                    throw new RasterFormatException("x lies outside the raster");
1277:                }
1278:                if (y < this .minY) {
1279:                    throw new RasterFormatException("y lies outside the raster");
1280:                }
1281:                if ((x + width < x) || (x + width > this .minX + this .width)) {
1282:                    throw new RasterFormatException(
1283:                            "(x + width) is outside of Raster");
1284:                }
1285:                if ((y + height < y) || (y + height > this .minY + this .height)) {
1286:                    throw new RasterFormatException(
1287:                            "(y + height) is outside of Raster");
1288:                }
1289:
1290:                SampleModel sm;
1291:
1292:                if (bandList != null) {
1293:                    sm = sampleModel.createSubsetSampleModel(bandList);
1294:                } else {
1295:                    sm = sampleModel;
1296:                }
1297:
1298:                int deltaX = x0 - x;
1299:                int deltaY = y0 - y;
1300:
1301:                return new BytePackedRaster(sm, dataBuffer, new Rectangle(x0,
1302:                        y0, width, height), new Point(sampleModelTranslateX
1303:                        + deltaX, sampleModelTranslateY + deltaY), this );
1304:            }
1305:
1306:            /**
1307:             * Creates a raster with the same layout but using a different
1308:             * width and height, and with new zeroed data arrays.
1309:             */
1310:            public WritableRaster createCompatibleWritableRaster(int w, int h) {
1311:                if (w <= 0 || h <= 0) {
1312:                    throw new RasterFormatException("negative "
1313:                            + ((w <= 0) ? "width" : "height"));
1314:                }
1315:
1316:                SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
1317:
1318:                return new BytePackedRaster(sm, new Point(0, 0));
1319:            }
1320:
1321:            /**
1322:             * Creates a raster with the same layout and the same
1323:             * width and height, and with new zeroed data arrays.
1324:             */
1325:            public WritableRaster createCompatibleWritableRaster() {
1326:                return createCompatibleWritableRaster(width, height);
1327:            }
1328:
1329:            /**
1330:             * Verify that the layout parameters are consistent with
1331:             * the data.  If strictCheck
1332:             * is false, this method will check for ArrayIndexOutOfBounds conditions.  
1333:             * If strictCheck is true, this method will check for additional error
1334:             * conditions such as line wraparound (width of a line greater than
1335:             * the scanline stride).
1336:             * @return   String   Error string, if the layout is incompatible with
1337:             *                    the data.  Otherwise returns null.
1338:             */
1339:            private void verify(boolean strictCheck) {
1340:                // Make sure data for Raster is in a legal range
1341:                if (dataBitOffset < 0) {
1342:                    throw new RasterFormatException("Data offsets must be >= 0");
1343:                }
1344:
1345:                int lastbit = (dataBitOffset + (height - 1) * scanlineStride
1346:                        * 8 + (width - 1) * pixelBitStride + pixelBitStride - 1);
1347:                if (lastbit / 8 >= data.length) {
1348:                    throw new RasterFormatException(
1349:                            "raster dimensions overflow " + "array bounds");
1350:                }
1351:                if (strictCheck) {
1352:                    if (height > 1) {
1353:                        lastbit = width * pixelBitStride - 1;
1354:                        if (lastbit / 8 >= scanlineStride) {
1355:                            throw new RasterFormatException("data for adjacent"
1356:                                    + " scanlines overlaps");
1357:                        }
1358:                    }
1359:                }
1360:            }
1361:
1362:            public String toString() {
1363:                return new String("BytePackedRaster: width = " + width
1364:                        + " height = " + height + " #channels " + numBands
1365:                        + " xOff = " + sampleModelTranslateX + " yOff = "
1366:                        + sampleModelTranslateY);
1367:            }
1368:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.