Source Code Cross Referenced for BMPImageReader.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » imageioimpl » plugins » bmp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * $RCSfile: BMPImageReader.java,v $
0003:         *
0004:         * 
0005:         * Copyright (c) 2005 Sun Microsystems, Inc. All  Rights Reserved.
0006:         * 
0007:         * Redistribution and use in source and binary forms, with or without
0008:         * modification, are permitted provided that the following conditions
0009:         * are met: 
0010:         * 
0011:         * - Redistribution of source code must retain the above copyright 
0012:         *   notice, this  list of conditions and the following disclaimer.
0013:         * 
0014:         * - Redistribution in binary form must reproduce the above copyright
0015:         *   notice, this list of conditions and the following disclaimer in 
0016:         *   the documentation and/or other materials provided with the
0017:         *   distribution.
0018:         * 
0019:         * Neither the name of Sun Microsystems, Inc. or the names of 
0020:         * contributors may be used to endorse or promote products derived 
0021:         * from this software without specific prior written permission.
0022:         * 
0023:         * This software is provided "AS IS," without a warranty of any 
0024:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 
0025:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 
0026:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
0027:         * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 
0028:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
0029:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
0030:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 
0031:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
0032:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
0033:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
0034:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
0035:         * POSSIBILITY OF SUCH DAMAGES. 
0036:         * 
0037:         * You acknowledge that this software is not designed or intended for 
0038:         * use in the design, construction, operation or maintenance of any 
0039:         * nuclear facility. 
0040:         *
0041:         * $Revision: 1.2 $
0042:         * $Date: 2006/04/14 21:29:14 $
0043:         * $State: Exp $
0044:         */
0045:
0046:        package com.sun.media.imageioimpl.plugins.bmp;
0047:
0048:        import java.awt.Point;
0049:        import java.awt.Rectangle;
0050:        import java.awt.Transparency;
0051:        import java.awt.color.ColorSpace;
0052:        import java.awt.color.ICC_ColorSpace;
0053:        import java.awt.color.ICC_Profile;
0054:        import java.awt.image.BufferedImage;
0055:        import java.awt.image.ColorModel;
0056:        import java.awt.image.ComponentColorModel;
0057:        import java.awt.image.ComponentSampleModel;
0058:        import java.awt.image.DataBuffer;
0059:        import java.awt.image.DataBufferByte;
0060:        import java.awt.image.DataBufferInt;
0061:        import java.awt.image.DataBufferUShort;
0062:        import java.awt.image.DirectColorModel;
0063:        import java.awt.image.IndexColorModel;
0064:        import java.awt.image.MultiPixelPackedSampleModel;
0065:        import java.awt.image.PixelInterleavedSampleModel;
0066:        import java.awt.image.Raster;
0067:        import java.awt.image.SampleModel;
0068:        import java.awt.image.SinglePixelPackedSampleModel;
0069:        import java.awt.image.WritableRaster;
0070:
0071:        import javax.imageio.IIOException;
0072:        import javax.imageio.ImageIO;
0073:        import javax.imageio.ImageReader;
0074:        import javax.imageio.ImageReadParam;
0075:        import javax.imageio.ImageTypeSpecifier;
0076:        import javax.imageio.metadata.IIOMetadata;
0077:        import javax.imageio.spi.ImageReaderSpi;
0078:        import javax.imageio.stream.ImageInputStream;
0079:        import javax.imageio.event.IIOReadProgressListener;
0080:        import javax.imageio.event.IIOReadUpdateListener;
0081:        import javax.imageio.event.IIOReadWarningListener;
0082:
0083:        import java.io.*;
0084:        import java.nio.*;
0085:        import java.util.ArrayList;
0086:        import java.util.Iterator;
0087:        import java.util.StringTokenizer;
0088:
0089:        import com.sun.media.imageioimpl.common.ImageUtil;
0090:
0091:        /** This class is the Java Image IO plugin reader for BMP images.
0092:         *  It may subsample the image, clip the image, select sub-bands,
0093:         *  and shift the decoded image origin if the proper decoding parameter
0094:         *  are set in the provided <code>ImageReadParam</code>.
0095:         *
0096:         *  This class supports Microsoft Windows Bitmap Version 3-5,
0097:         *  as well as OS/2 Bitmap Version 2.x (for single-image BMP file).
0098:         */
0099:        public class BMPImageReader extends ImageReader implements  BMPConstants {
0100:            // BMP Image types
0101:            private static final int VERSION_2_1_BIT = 0;
0102:            private static final int VERSION_2_4_BIT = 1;
0103:            private static final int VERSION_2_8_BIT = 2;
0104:            private static final int VERSION_2_24_BIT = 3;
0105:
0106:            private static final int VERSION_3_1_BIT = 4;
0107:            private static final int VERSION_3_4_BIT = 5;
0108:            private static final int VERSION_3_8_BIT = 6;
0109:            private static final int VERSION_3_24_BIT = 7;
0110:
0111:            private static final int VERSION_3_NT_16_BIT = 8;
0112:            private static final int VERSION_3_NT_32_BIT = 9;
0113:
0114:            private static final int VERSION_4_1_BIT = 10;
0115:            private static final int VERSION_4_4_BIT = 11;
0116:            private static final int VERSION_4_8_BIT = 12;
0117:            private static final int VERSION_4_16_BIT = 13;
0118:            private static final int VERSION_4_24_BIT = 14;
0119:            private static final int VERSION_4_32_BIT = 15;
0120:
0121:            private static final int VERSION_3_XP_EMBEDDED = 16;
0122:            private static final int VERSION_4_XP_EMBEDDED = 17;
0123:            private static final int VERSION_5_XP_EMBEDDED = 18;
0124:
0125:            // BMP variables
0126:            private long bitmapFileSize;
0127:            private long bitmapOffset;
0128:            private long compression;
0129:            private long imageSize;
0130:            private byte palette[];
0131:            private int imageType;
0132:            private int numBands;
0133:            private boolean isBottomUp;
0134:            private int bitsPerPixel;
0135:            private int redMask, greenMask, blueMask, alphaMask;
0136:
0137:            private SampleModel sampleModel, originalSampleModel;
0138:            private ColorModel colorModel, originalColorModel;
0139:
0140:            /** The input stream where reads from */
0141:            private ImageInputStream iis = null;
0142:
0143:            /** Indicates whether the header is read. */
0144:            private boolean gotHeader = false;
0145:
0146:            /** The stream position where the image data starts. */
0147:            private long imageDataOffset;
0148:
0149:            /** The original image width. */
0150:            private int width;
0151:
0152:            /** The original image height. */
0153:            private int height;
0154:
0155:            /** The destination region. */
0156:            private Rectangle destinationRegion;
0157:
0158:            /** The source region. */
0159:            private Rectangle sourceRegion;
0160:
0161:            /** The metadata from the stream. */
0162:            private BMPMetadata metadata;
0163:
0164:            /** The destination image. */
0165:            private BufferedImage bi;
0166:
0167:            /** Indicates whether subsampled, subregion is required, and offset is
0168:             *  defined
0169:             */
0170:            private boolean noTransform = true;
0171:
0172:            /** Indicates whether subband is selected. */
0173:            private boolean seleBand = false;
0174:
0175:            /** The scaling factors. */
0176:            private int scaleX, scaleY;
0177:
0178:            /** source and destination bands. */
0179:            private int[] sourceBands, destBands;
0180:
0181:            /** Constructs <code>BMPImageReader</code> from the provided
0182:             *  <code>ImageReaderSpi</code>.
0183:             */
0184:            public BMPImageReader(ImageReaderSpi originator) {
0185:                super (originator);
0186:            }
0187:
0188:            /** Overrides the method defined in the superclass. */
0189:            public void setInput(Object input, boolean seekForwardOnly,
0190:                    boolean ignoreMetadata) {
0191:                super .setInput(input, seekForwardOnly, ignoreMetadata);
0192:                iis = (ImageInputStream) input; // Always works
0193:                if (iis != null)
0194:                    iis.setByteOrder(ByteOrder.LITTLE_ENDIAN);
0195:                resetHeaderInfo();
0196:            }
0197:
0198:            /** Overrides the method defined in the superclass. */
0199:            public int getNumImages(boolean allowSearch) throws IOException {
0200:                if (iis == null) {
0201:                    throw new IllegalStateException(I18N
0202:                            .getString("GetNumImages0"));
0203:                }
0204:                if (seekForwardOnly && allowSearch) {
0205:                    throw new IllegalStateException(I18N
0206:                            .getString("GetNumImages1"));
0207:                }
0208:                return 1;
0209:            }
0210:
0211:            public int getWidth(int imageIndex) throws IOException {
0212:                checkIndex(imageIndex);
0213:                readHeader();
0214:                return width;
0215:            }
0216:
0217:            public int getHeight(int imageIndex) throws IOException {
0218:                checkIndex(imageIndex);
0219:                readHeader();
0220:                return height;
0221:            }
0222:
0223:            private void checkIndex(int imageIndex) {
0224:                if (imageIndex != 0) {
0225:                    throw new IndexOutOfBoundsException(I18N
0226:                            .getString("BMPImageReader0"));
0227:                }
0228:            }
0229:
0230:            public void readHeader() throws IOException {
0231:                if (gotHeader) {
0232:                    // Seek to where the image data starts, since that is where
0233:                    // the stream pointer should be after header is read
0234:                    iis.seek(imageDataOffset);
0235:                    return;
0236:                }
0237:
0238:                if (iis == null) {
0239:                    throw new IllegalStateException(I18N
0240:                            .getString("BMPImageReader5"));
0241:                }
0242:                int profileData = 0, profileSize = 0;
0243:
0244:                this .metadata = new BMPMetadata();
0245:                iis.mark();
0246:
0247:                // read and check the magic marker
0248:                byte[] marker = new byte[2];
0249:                iis.read(marker);
0250:                if (marker[0] != 0x42 || marker[1] != 0x4d)
0251:                    throw new IllegalArgumentException(I18N
0252:                            .getString("BMPImageReader1"));
0253:
0254:                // Read file size
0255:                bitmapFileSize = iis.readUnsignedInt();
0256:                // skip the two reserved fields
0257:                iis.skipBytes(4);
0258:
0259:                // Offset to the bitmap from the beginning
0260:                bitmapOffset = iis.readUnsignedInt();
0261:                // End File Header
0262:
0263:                // Start BitmapCoreHeader
0264:                long size = iis.readUnsignedInt();
0265:
0266:                if (size == 12) {
0267:                    width = iis.readShort();
0268:                    height = iis.readShort();
0269:                } else {
0270:                    width = iis.readInt();
0271:                    height = iis.readInt();
0272:                }
0273:
0274:                metadata.width = width;
0275:                metadata.height = height;
0276:
0277:                int planes = iis.readUnsignedShort();
0278:                bitsPerPixel = iis.readUnsignedShort();
0279:
0280:                //metadata.colorPlane = planes;
0281:                metadata.bitsPerPixel = (short) bitsPerPixel;
0282:
0283:                // As BMP always has 3 rgb bands, except for Version 5,
0284:                // which is bgra
0285:                numBands = 3;
0286:
0287:                if (size == 12) {
0288:                    // Windows 2.x and OS/2 1.x
0289:                    metadata.bmpVersion = VERSION_2;
0290:
0291:                    // Classify the image type
0292:                    if (bitsPerPixel == 1) {
0293:                        imageType = VERSION_2_1_BIT;
0294:                    } else if (bitsPerPixel == 4) {
0295:                        imageType = VERSION_2_4_BIT;
0296:                    } else if (bitsPerPixel == 8) {
0297:                        imageType = VERSION_2_8_BIT;
0298:                    } else if (bitsPerPixel == 24) {
0299:                        imageType = VERSION_2_24_BIT;
0300:                    }
0301:
0302:                    // Read in the palette
0303:                    int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 3);
0304:                    int sizeOfPalette = numberOfEntries * 3;
0305:                    palette = new byte[sizeOfPalette];
0306:                    iis.readFully(palette, 0, sizeOfPalette);
0307:                    metadata.palette = palette;
0308:                    metadata.paletteSize = numberOfEntries;
0309:                } else {
0310:                    compression = iis.readUnsignedInt();
0311:                    imageSize = iis.readUnsignedInt();
0312:                    long xPelsPerMeter = iis.readInt();
0313:                    long yPelsPerMeter = iis.readInt();
0314:                    long colorsUsed = iis.readUnsignedInt();
0315:                    long colorsImportant = iis.readUnsignedInt();
0316:
0317:                    metadata.compression = (int) compression;
0318:                    metadata.imageSize = (int) imageSize;
0319:                    metadata.xPixelsPerMeter = (int) xPelsPerMeter;
0320:                    metadata.yPixelsPerMeter = (int) yPelsPerMeter;
0321:                    metadata.colorsUsed = (int) colorsUsed;
0322:                    metadata.colorsImportant = (int) colorsImportant;
0323:
0324:                    if (size == 40) {
0325:                        // Windows 3.x and Windows NT
0326:                        switch ((int) compression) {
0327:
0328:                        case BI_JPEG:
0329:                        case BI_PNG:
0330:                            metadata.bmpVersion = VERSION_3;
0331:                            imageType = VERSION_3_XP_EMBEDDED;
0332:                            break;
0333:
0334:                        case BI_RGB: // No compression
0335:                        case BI_RLE8: // 8-bit RLE compression
0336:                        case BI_RLE4: // 4-bit RLE compression
0337:
0338:                            // Read in the palette
0339:                            int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
0340:                            int sizeOfPalette = numberOfEntries * 4;
0341:                            palette = new byte[sizeOfPalette];
0342:                            iis.readFully(palette, 0, sizeOfPalette);
0343:
0344:                            metadata.palette = palette;
0345:                            metadata.paletteSize = numberOfEntries;
0346:
0347:                            if (bitsPerPixel == 1) {
0348:                                imageType = VERSION_3_1_BIT;
0349:                            } else if (bitsPerPixel == 4) {
0350:                                imageType = VERSION_3_4_BIT;
0351:                            } else if (bitsPerPixel == 8) {
0352:                                imageType = VERSION_3_8_BIT;
0353:                            } else if (bitsPerPixel == 24) {
0354:                                imageType = VERSION_3_24_BIT;
0355:                            } else if (bitsPerPixel == 16) {
0356:                                imageType = VERSION_3_NT_16_BIT;
0357:
0358:                                redMask = 0x7C00;
0359:                                greenMask = 0x3E0;
0360:                                blueMask = (1 << 5) - 1;// 0x1F;
0361:                                metadata.redMask = redMask;
0362:                                metadata.greenMask = greenMask;
0363:                                metadata.blueMask = blueMask;
0364:                            } else if (bitsPerPixel == 32) {
0365:                                imageType = VERSION_3_NT_32_BIT;
0366:                                redMask = 0x00FF0000;
0367:                                greenMask = 0x0000FF00;
0368:                                blueMask = 0x000000FF;
0369:                                metadata.redMask = redMask;
0370:                                metadata.greenMask = greenMask;
0371:                                metadata.blueMask = blueMask;
0372:                            }
0373:
0374:                            metadata.bmpVersion = VERSION_3;
0375:                            break;
0376:
0377:                        case BI_BITFIELDS:
0378:
0379:                            if (bitsPerPixel == 16) {
0380:                                imageType = VERSION_3_NT_16_BIT;
0381:                            } else if (bitsPerPixel == 32) {
0382:                                imageType = VERSION_3_NT_32_BIT;
0383:                            }
0384:
0385:                            // BitsField encoding
0386:                            redMask = (int) iis.readUnsignedInt();
0387:                            greenMask = (int) iis.readUnsignedInt();
0388:                            blueMask = (int) iis.readUnsignedInt();
0389:                            metadata.redMask = redMask;
0390:                            metadata.greenMask = greenMask;
0391:                            metadata.blueMask = blueMask;
0392:
0393:                            if (colorsUsed != 0) {
0394:                                // there is a palette
0395:                                sizeOfPalette = (int) colorsUsed * 4;
0396:                                palette = new byte[sizeOfPalette];
0397:                                iis.readFully(palette, 0, sizeOfPalette);
0398:                                metadata.palette = palette;
0399:                                metadata.paletteSize = (int) colorsUsed;
0400:                            }
0401:                            metadata.bmpVersion = VERSION_3_NT;
0402:
0403:                            break;
0404:                        default:
0405:                            throw new RuntimeException(I18N
0406:                                    .getString("BMPImageReader2"));
0407:                        }
0408:                    } else if (size == 108 || size == 124) {
0409:                        // Windows 4.x BMP
0410:                        if (size == 108)
0411:                            metadata.bmpVersion = VERSION_4;
0412:                        else if (size == 124)
0413:                            metadata.bmpVersion = VERSION_5;
0414:
0415:                        // rgb masks, valid only if comp is BI_BITFIELDS
0416:                        redMask = (int) iis.readUnsignedInt();
0417:                        greenMask = (int) iis.readUnsignedInt();
0418:                        blueMask = (int) iis.readUnsignedInt();
0419:                        // Only supported for 32bpp BI_RGB argb
0420:                        alphaMask = (int) iis.readUnsignedInt();
0421:                        long csType = iis.readUnsignedInt();
0422:                        int redX = iis.readInt();
0423:                        int redY = iis.readInt();
0424:                        int redZ = iis.readInt();
0425:                        int greenX = iis.readInt();
0426:                        int greenY = iis.readInt();
0427:                        int greenZ = iis.readInt();
0428:                        int blueX = iis.readInt();
0429:                        int blueY = iis.readInt();
0430:                        int blueZ = iis.readInt();
0431:                        long gammaRed = iis.readUnsignedInt();
0432:                        long gammaGreen = iis.readUnsignedInt();
0433:                        long gammaBlue = iis.readUnsignedInt();
0434:
0435:                        if (size == 124) {
0436:                            metadata.intent = iis.readInt();
0437:                            profileData = iis.readInt();
0438:                            profileSize = iis.readInt();
0439:                            iis.skipBytes(4);
0440:                        }
0441:
0442:                        metadata.colorSpace = (int) csType;
0443:
0444:                        if (csType == LCS_CALIBRATED_RGB) {
0445:                            // All the new fields are valid only for this case
0446:                            metadata.redX = redX;
0447:                            metadata.redY = redY;
0448:                            metadata.redZ = redZ;
0449:                            metadata.greenX = greenX;
0450:                            metadata.greenY = greenY;
0451:                            metadata.greenZ = greenZ;
0452:                            metadata.blueX = blueX;
0453:                            metadata.blueY = blueY;
0454:                            metadata.blueZ = blueZ;
0455:                            metadata.gammaRed = (int) gammaRed;
0456:                            metadata.gammaGreen = (int) gammaGreen;
0457:                            metadata.gammaBlue = (int) gammaBlue;
0458:                        }
0459:
0460:                        // Read in the palette
0461:                        int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
0462:                        int sizeOfPalette = numberOfEntries * 4;
0463:                        palette = new byte[sizeOfPalette];
0464:                        iis.readFully(palette, 0, sizeOfPalette);
0465:                        metadata.palette = palette;
0466:                        metadata.paletteSize = numberOfEntries;
0467:
0468:                        switch ((int) compression) {
0469:                        case BI_JPEG:
0470:                        case BI_PNG:
0471:                            if (size == 108) {
0472:                                imageType = VERSION_4_XP_EMBEDDED;
0473:                            } else if (size == 124) {
0474:                                imageType = VERSION_5_XP_EMBEDDED;
0475:                            }
0476:                            break;
0477:                        default:
0478:                            if (bitsPerPixel == 1) {
0479:                                imageType = VERSION_4_1_BIT;
0480:                            } else if (bitsPerPixel == 4) {
0481:                                imageType = VERSION_4_4_BIT;
0482:                            } else if (bitsPerPixel == 8) {
0483:                                imageType = VERSION_4_8_BIT;
0484:                            } else if (bitsPerPixel == 16) {
0485:                                imageType = VERSION_4_16_BIT;
0486:                                if ((int) compression == BI_RGB) {
0487:                                    redMask = 0x7C00;
0488:                                    greenMask = 0x3E0;
0489:                                    blueMask = 0x1F;
0490:                                }
0491:                            } else if (bitsPerPixel == 24) {
0492:                                imageType = VERSION_4_24_BIT;
0493:                            } else if (bitsPerPixel == 32) {
0494:                                imageType = VERSION_4_32_BIT;
0495:                                if ((int) compression == BI_RGB) {
0496:                                    redMask = 0x00FF0000;
0497:                                    greenMask = 0x0000FF00;
0498:                                    blueMask = 0x000000FF;
0499:                                }
0500:                            }
0501:
0502:                            metadata.redMask = redMask;
0503:                            metadata.greenMask = greenMask;
0504:                            metadata.blueMask = blueMask;
0505:                            metadata.alphaMask = alphaMask;
0506:                        }
0507:                    } else {
0508:                        throw new RuntimeException(I18N
0509:                                .getString("BMPImageReader3"));
0510:                    }
0511:                }
0512:
0513:                if (height > 0) {
0514:                    // bottom up image
0515:                    isBottomUp = true;
0516:                } else {
0517:                    // top down image
0518:                    isBottomUp = false;
0519:                    height = Math.abs(height);
0520:                }
0521:
0522:                // Reset Image Layout so there's only one tile.
0523:                //Define the color space
0524:                ColorSpace colorSpace = ColorSpace
0525:                        .getInstance(ColorSpace.CS_sRGB);
0526:                if (metadata.colorSpace == PROFILE_LINKED
0527:                        || metadata.colorSpace == PROFILE_EMBEDDED) {
0528:
0529:                    iis.mark();
0530:                    iis.skipBytes(profileData - size);
0531:                    byte[] profile = new byte[profileSize];
0532:                    iis.readFully(profile, 0, profileSize);
0533:                    iis.reset();
0534:
0535:                    try {
0536:                        if (metadata.colorSpace == PROFILE_LINKED)
0537:                            colorSpace = new ICC_ColorSpace(ICC_Profile
0538:                                    .getInstance(new String(profile)));
0539:                        else
0540:                            colorSpace = new ICC_ColorSpace(ICC_Profile
0541:                                    .getInstance(profile));
0542:                    } catch (Exception e) {
0543:                        colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
0544:                    }
0545:                }
0546:
0547:                if (bitsPerPixel == 0 || compression == BI_JPEG
0548:                        || compression == BI_PNG) {
0549:                    // the colorModel and sampleModel will be initialzed
0550:                    // by the  reader of embedded image
0551:                    colorModel = null;
0552:                    sampleModel = null;
0553:                } else if (bitsPerPixel == 1 || bitsPerPixel == 4
0554:                        || bitsPerPixel == 8) {
0555:                    // When number of bitsPerPixel is <= 8, we use IndexColorModel.
0556:                    numBands = 1;
0557:
0558:                    if (bitsPerPixel == 8) {
0559:                        int[] bandOffsets = new int[numBands];
0560:                        for (int i = 0; i < numBands; i++) {
0561:                            bandOffsets[i] = numBands - 1 - i;
0562:                        }
0563:                        sampleModel = new PixelInterleavedSampleModel(
0564:                                DataBuffer.TYPE_BYTE, width, height, numBands,
0565:                                numBands * width, bandOffsets);
0566:                    } else {
0567:                        // 1 and 4 bit pixels can be stored in a packed format.
0568:                        sampleModel = new MultiPixelPackedSampleModel(
0569:                                DataBuffer.TYPE_BYTE, width, height,
0570:                                bitsPerPixel);
0571:                    }
0572:
0573:                    // Create IndexColorModel from the palette.
0574:                    byte r[], g[], b[];
0575:                    if (imageType == VERSION_2_1_BIT
0576:                            || imageType == VERSION_2_4_BIT
0577:                            || imageType == VERSION_2_8_BIT) {
0578:
0579:                        size = palette.length / 3;
0580:
0581:                        if (size > 256) {
0582:                            size = 256;
0583:                        }
0584:
0585:                        int off;
0586:                        r = new byte[(int) size];
0587:                        g = new byte[(int) size];
0588:                        b = new byte[(int) size];
0589:                        for (int i = 0; i < (int) size; i++) {
0590:                            off = 3 * i;
0591:                            b[i] = palette[off];
0592:                            g[i] = palette[off + 1];
0593:                            r[i] = palette[off + 2];
0594:                        }
0595:                    } else {
0596:                        size = palette.length / 4;
0597:
0598:                        if (size > 256) {
0599:                            size = 256;
0600:                        }
0601:
0602:                        int off;
0603:                        r = new byte[(int) size];
0604:                        g = new byte[(int) size];
0605:                        b = new byte[(int) size];
0606:                        for (int i = 0; i < size; i++) {
0607:                            off = 4 * i;
0608:                            b[i] = palette[off];
0609:                            g[i] = palette[off + 1];
0610:                            r[i] = palette[off + 2];
0611:                        }
0612:                    }
0613:
0614:                    if (ImageUtil.isIndicesForGrayscale(r, g, b))
0615:                        colorModel = ImageUtil.createColorModel(null,
0616:                                sampleModel);
0617:                    else
0618:                        colorModel = new IndexColorModel(bitsPerPixel,
0619:                                (int) size, r, g, b);
0620:                } else if (bitsPerPixel == 16) {
0621:                    numBands = 3;
0622:                    sampleModel = new SinglePixelPackedSampleModel(
0623:                            DataBuffer.TYPE_USHORT, width, height, new int[] {
0624:                                    redMask, greenMask, blueMask });
0625:
0626:                    colorModel = new DirectColorModel(colorSpace, 16, redMask,
0627:                            greenMask, blueMask, 0, false,
0628:                            DataBuffer.TYPE_USHORT);
0629:
0630:                } else if (bitsPerPixel == 32) {
0631:                    numBands = alphaMask == 0 ? 3 : 4;
0632:
0633:                    if (redMask == 0 || greenMask == 0 || blueMask == 0) {
0634:                        redMask = 0xFF0000;
0635:                        greenMask = 0xFF00;
0636:                        blueMask = 0xFF;
0637:                        alphaMask = 0xFF000000;
0638:                    }
0639:
0640:                    // The number of bands in the SampleModel is determined by
0641:                    // the length of the mask array passed in.
0642:                    int[] bitMasks = numBands == 3 ? new int[] { redMask,
0643:                            greenMask, blueMask } : new int[] { redMask,
0644:                            greenMask, blueMask, alphaMask };
0645:
0646:                    sampleModel = new SinglePixelPackedSampleModel(
0647:                            DataBuffer.TYPE_INT, width, height, bitMasks);
0648:
0649:                    colorModel = new DirectColorModel(colorSpace, 32, redMask,
0650:                            greenMask, blueMask, alphaMask, false,
0651:                            DataBuffer.TYPE_INT);
0652:                } else {
0653:                    numBands = 3;
0654:                    // Create SampleModel
0655:                    int[] bandOffsets = new int[numBands];
0656:                    for (int i = 0; i < numBands; i++) {
0657:                        bandOffsets[i] = numBands - 1 - i;
0658:                    }
0659:
0660:                    sampleModel = new PixelInterleavedSampleModel(
0661:                            DataBuffer.TYPE_BYTE, width, height, numBands,
0662:                            numBands * width, bandOffsets);
0663:
0664:                    colorModel = ImageUtil.createColorModel(colorSpace,
0665:                            sampleModel);
0666:                }
0667:
0668:                originalSampleModel = sampleModel;
0669:                originalColorModel = colorModel;
0670:
0671:                // Reset to the start of bitmap; then jump to the
0672:                //start of image data
0673:                iis.reset();
0674:                iis.skipBytes(bitmapOffset);
0675:                gotHeader = true;
0676:
0677:                // Store the stream position where the image data starts
0678:                imageDataOffset = iis.getStreamPosition();
0679:            }
0680:
0681:            public Iterator getImageTypes(int imageIndex) throws IOException {
0682:                checkIndex(imageIndex);
0683:                readHeader();
0684:                ArrayList list = new ArrayList(1);
0685:                list.add(new ImageTypeSpecifier(originalColorModel,
0686:                        originalSampleModel));
0687:                return list.iterator();
0688:            }
0689:
0690:            public ImageReadParam getDefaultReadParam() {
0691:                return new ImageReadParam();
0692:            }
0693:
0694:            public IIOMetadata getImageMetadata(int imageIndex)
0695:                    throws IOException {
0696:                checkIndex(imageIndex);
0697:                if (metadata == null) {
0698:                    readHeader();
0699:                }
0700:                return metadata;
0701:            }
0702:
0703:            public IIOMetadata getStreamMetadata() throws IOException {
0704:                return null;
0705:            }
0706:
0707:            public boolean isRandomAccessEasy(int imageIndex)
0708:                    throws IOException {
0709:                checkIndex(imageIndex);
0710:                readHeader();
0711:                return metadata.compression == BI_RGB;
0712:            }
0713:
0714:            public BufferedImage read(int imageIndex, ImageReadParam param)
0715:                    throws IOException {
0716:
0717:                if (iis == null) {
0718:                    throw new IllegalStateException(I18N
0719:                            .getString("BMPImageReader5"));
0720:                }
0721:
0722:                checkIndex(imageIndex);
0723:                clearAbortRequest();
0724:                processImageStarted(imageIndex);
0725:
0726:                if (param == null)
0727:                    param = getDefaultReadParam();
0728:
0729:                //read header
0730:                readHeader();
0731:
0732:                sourceRegion = new Rectangle(0, 0, 0, 0);
0733:                destinationRegion = new Rectangle(0, 0, 0, 0);
0734:
0735:                computeRegions(param, this .width, this .height, param
0736:                        .getDestination(), sourceRegion, destinationRegion);
0737:
0738:                scaleX = param.getSourceXSubsampling();
0739:                scaleY = param.getSourceYSubsampling();
0740:
0741:                // If the destination band is set used it
0742:                sourceBands = param.getSourceBands();
0743:                destBands = param.getDestinationBands();
0744:
0745:                seleBand = (sourceBands != null) && (destBands != null);
0746:                noTransform = destinationRegion.equals(new Rectangle(0, 0,
0747:                        width, height))
0748:                        || seleBand;
0749:
0750:                if (!seleBand) {
0751:                    sourceBands = new int[numBands];
0752:                    destBands = new int[numBands];
0753:                    for (int i = 0; i < numBands; i++)
0754:                        destBands[i] = sourceBands[i] = i;
0755:                }
0756:
0757:                // If the destination is provided, then use it.  Otherwise, create new one
0758:                bi = param.getDestination();
0759:
0760:                // Get the image data.
0761:                WritableRaster raster = null;
0762:
0763:                if (bi == null) {
0764:                    if (sampleModel != null && colorModel != null) {
0765:                        sampleModel = sampleModel.createCompatibleSampleModel(
0766:                                destinationRegion.x + destinationRegion.width,
0767:                                destinationRegion.y + destinationRegion.height);
0768:                        if (seleBand)
0769:                            sampleModel = sampleModel
0770:                                    .createSubsetSampleModel(sourceBands);
0771:                        raster = Raster.createWritableRaster(sampleModel,
0772:                                new Point());
0773:                        bi = new BufferedImage(colorModel, raster, false, null);
0774:                    }
0775:                } else {
0776:                    raster = bi.getWritableTile(0, 0);
0777:                    sampleModel = bi.getSampleModel();
0778:                    colorModel = bi.getColorModel();
0779:
0780:                    noTransform &= destinationRegion.equals(raster.getBounds());
0781:                }
0782:
0783:                byte bdata[] = null; // buffer for byte data
0784:                short sdata[] = null; // buffer for short data
0785:                int idata[] = null; // buffer for int data
0786:
0787:                // the sampleModel can be null in case of embedded image
0788:                if (sampleModel != null) {
0789:                    if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE)
0790:                        bdata = (byte[]) ((DataBufferByte) raster
0791:                                .getDataBuffer()).getData();
0792:                    else if (sampleModel.getDataType() == DataBuffer.TYPE_USHORT)
0793:                        sdata = (short[]) ((DataBufferUShort) raster
0794:                                .getDataBuffer()).getData();
0795:                    else if (sampleModel.getDataType() == DataBuffer.TYPE_INT)
0796:                        idata = (int[]) ((DataBufferInt) raster.getDataBuffer())
0797:                                .getData();
0798:                }
0799:
0800:                // There should only be one tile.
0801:                switch (imageType) {
0802:
0803:                case VERSION_2_1_BIT:
0804:                    // no compression
0805:                    read1Bit(bdata);
0806:                    break;
0807:
0808:                case VERSION_2_4_BIT:
0809:                    // no compression
0810:                    read4Bit(bdata);
0811:                    break;
0812:
0813:                case VERSION_2_8_BIT:
0814:                    // no compression
0815:                    read8Bit(bdata);
0816:                    break;
0817:
0818:                case VERSION_2_24_BIT:
0819:                    // no compression
0820:                    read24Bit(bdata);
0821:                    break;
0822:
0823:                case VERSION_3_1_BIT:
0824:                    // 1-bit images cannot be compressed.
0825:                    read1Bit(bdata);
0826:                    break;
0827:
0828:                case VERSION_3_4_BIT:
0829:                    switch ((int) compression) {
0830:                    case BI_RGB:
0831:                        read4Bit(bdata);
0832:                        break;
0833:
0834:                    case BI_RLE4:
0835:                        readRLE4(bdata);
0836:                        break;
0837:
0838:                    default:
0839:                        throw new RuntimeException(I18N
0840:                                .getString("BMPImageReader1"));
0841:                    }
0842:                    break;
0843:
0844:                case VERSION_3_8_BIT:
0845:                    switch ((int) compression) {
0846:                    case BI_RGB:
0847:                        read8Bit(bdata);
0848:                        break;
0849:
0850:                    case BI_RLE8:
0851:                        readRLE8(bdata);
0852:                        break;
0853:
0854:                    default:
0855:                        throw new RuntimeException(I18N
0856:                                .getString("BMPImageReader1"));
0857:                    }
0858:
0859:                    break;
0860:
0861:                case VERSION_3_24_BIT:
0862:                    // 24-bit images are not compressed
0863:                    read24Bit(bdata);
0864:                    break;
0865:
0866:                case VERSION_3_NT_16_BIT:
0867:                    read16Bit(sdata);
0868:                    break;
0869:
0870:                case VERSION_3_NT_32_BIT:
0871:                    read32Bit(idata);
0872:                    break;
0873:
0874:                case VERSION_3_XP_EMBEDDED:
0875:                case VERSION_4_XP_EMBEDDED:
0876:                case VERSION_5_XP_EMBEDDED:
0877:                    bi = readEmbedded((int) compression, bi, param);
0878:                    break;
0879:
0880:                case VERSION_4_1_BIT:
0881:                    read1Bit(bdata);
0882:                    break;
0883:
0884:                case VERSION_4_4_BIT:
0885:                    switch ((int) compression) {
0886:
0887:                    case BI_RGB:
0888:                        read4Bit(bdata);
0889:                        break;
0890:
0891:                    case BI_RLE4:
0892:                        readRLE4(bdata);
0893:                        break;
0894:
0895:                    default:
0896:                        throw new RuntimeException(I18N
0897:                                .getString("BMPImageReader1"));
0898:                    }
0899:
0900:                case VERSION_4_8_BIT:
0901:                    switch ((int) compression) {
0902:
0903:                    case BI_RGB:
0904:                        read8Bit(bdata);
0905:                        break;
0906:
0907:                    case BI_RLE8:
0908:                        readRLE8(bdata);
0909:                        break;
0910:
0911:                    default:
0912:                        throw new RuntimeException(I18N
0913:                                .getString("BMPImageReader1"));
0914:                    }
0915:                    break;
0916:
0917:                case VERSION_4_16_BIT:
0918:                    read16Bit(sdata);
0919:                    break;
0920:
0921:                case VERSION_4_24_BIT:
0922:                    read24Bit(bdata);
0923:                    break;
0924:
0925:                case VERSION_4_32_BIT:
0926:                    read32Bit(idata);
0927:                    break;
0928:                }
0929:
0930:                if (abortRequested())
0931:                    processReadAborted();
0932:                else
0933:                    processImageComplete();
0934:
0935:                return bi;
0936:            }
0937:
0938:            public boolean canReadRaster() {
0939:                return true;
0940:            }
0941:
0942:            public Raster readRaster(int imageIndex, ImageReadParam param)
0943:                    throws IOException {
0944:                BufferedImage bi = read(imageIndex, param);
0945:                return bi.getData();
0946:            }
0947:
0948:            private void resetHeaderInfo() {
0949:                gotHeader = false;
0950:                bi = null;
0951:                sampleModel = originalSampleModel = null;
0952:                colorModel = originalColorModel = null;
0953:            }
0954:
0955:            public void reset() {
0956:                super .reset();
0957:                iis = null;
0958:                resetHeaderInfo();
0959:            }
0960:
0961:            // Deal with 1 Bit images using IndexColorModels
0962:            private void read1Bit(byte[] bdata) throws IOException {
0963:                int bytesPerScanline = (width + 7) / 8;
0964:                int padding = bytesPerScanline % 4;
0965:                if (padding != 0) {
0966:                    padding = 4 - padding;
0967:                }
0968:
0969:                int lineLength = bytesPerScanline + padding;
0970:
0971:                if (noTransform) {
0972:                    int j = isBottomUp ? (height - 1) * bytesPerScanline : 0;
0973:
0974:                    for (int i = 0; i < height; i++) {
0975:                        if (abortRequested()) {
0976:                            break;
0977:                        }
0978:                        iis.readFully(bdata, j, bytesPerScanline);
0979:                        iis.skipBytes(padding);
0980:                        j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
0981:                        processImageUpdate(bi, 0, i, destinationRegion.width,
0982:                                1, 1, 1, new int[] { 0 });
0983:                        processImageProgress(100.0F * i
0984:                                / destinationRegion.height);
0985:                    }
0986:                } else {
0987:                    byte[] buf = new byte[lineLength];
0988:                    int lineStride = ((MultiPixelPackedSampleModel) sampleModel)
0989:                            .getScanlineStride();
0990:
0991:                    if (isBottomUp) {
0992:                        int lastLine = sourceRegion.y
0993:                                + (destinationRegion.height - 1) * scaleY;
0994:                        iis.skipBytes(lineLength * (height - 1 - lastLine));
0995:                    } else
0996:                        iis.skipBytes(lineLength * sourceRegion.y);
0997:
0998:                    int skipLength = lineLength * (scaleY - 1);
0999:
1000:                    // cache the values to avoid duplicated computation
1001:                    int[] srcOff = new int[destinationRegion.width];
1002:                    int[] destOff = new int[destinationRegion.width];
1003:                    int[] srcPos = new int[destinationRegion.width];
1004:                    int[] destPos = new int[destinationRegion.width];
1005:
1006:                    for (int i = destinationRegion.x, x = sourceRegion.x, j = 0; i < destinationRegion.x
1007:                            + destinationRegion.width; i++, j++, x += scaleX) {
1008:                        srcPos[j] = x >> 3;
1009:                        srcOff[j] = 7 - (x & 7);
1010:                        destPos[j] = i >> 3;
1011:                        destOff[j] = 7 - (i & 7);
1012:                    }
1013:
1014:                    int k = destinationRegion.y * lineStride;
1015:                    if (isBottomUp)
1016:                        k += (destinationRegion.height - 1) * lineStride;
1017:
1018:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1019:
1020:                        if (abortRequested())
1021:                            break;
1022:                        iis.read(buf, 0, lineLength);
1023:                        for (int i = 0; i < destinationRegion.width; i++) {
1024:                            //get the bit and assign to the data buffer of the raster
1025:                            int v = (buf[srcPos[i]] >> srcOff[i]) & 1;
1026:                            bdata[k + destPos[i]] |= v << destOff[i];
1027:                        }
1028:
1029:                        k += isBottomUp ? -lineStride : lineStride;
1030:                        iis.skipBytes(skipLength);
1031:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1032:                                1, 1, 1, new int[] { 0 });
1033:                        processImageProgress(100.0F * j
1034:                                / destinationRegion.height);
1035:                    }
1036:                }
1037:            }
1038:
1039:            // Method to read a 4 bit BMP image data
1040:            private void read4Bit(byte[] bdata) throws IOException {
1041:
1042:                int bytesPerScanline = (width + 1) / 2;
1043:
1044:                // Padding bytes at the end of each scanline
1045:                int padding = bytesPerScanline % 4;
1046:                if (padding != 0)
1047:                    padding = 4 - padding;
1048:
1049:                int lineLength = bytesPerScanline + padding;
1050:
1051:                if (noTransform) {
1052:                    int j = isBottomUp ? (height - 1) * bytesPerScanline : 0;
1053:
1054:                    for (int i = 0; i < height; i++) {
1055:                        if (abortRequested()) {
1056:                            break;
1057:                        }
1058:                        iis.readFully(bdata, j, bytesPerScanline);
1059:                        iis.skipBytes(padding);
1060:                        j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
1061:                        processImageUpdate(bi, 0, i, destinationRegion.width,
1062:                                1, 1, 1, new int[] { 0 });
1063:                        processImageProgress(100.0F * i
1064:                                / destinationRegion.height);
1065:                    }
1066:                } else {
1067:                    byte[] buf = new byte[lineLength];
1068:                    int lineStride = ((MultiPixelPackedSampleModel) sampleModel)
1069:                            .getScanlineStride();
1070:
1071:                    if (isBottomUp) {
1072:                        int lastLine = sourceRegion.y
1073:                                + (destinationRegion.height - 1) * scaleY;
1074:                        iis.skipBytes(lineLength * (height - 1 - lastLine));
1075:                    } else
1076:                        iis.skipBytes(lineLength * sourceRegion.y);
1077:
1078:                    int skipLength = lineLength * (scaleY - 1);
1079:
1080:                    // cache the values to avoid duplicated computation
1081:                    int[] srcOff = new int[destinationRegion.width];
1082:                    int[] destOff = new int[destinationRegion.width];
1083:                    int[] srcPos = new int[destinationRegion.width];
1084:                    int[] destPos = new int[destinationRegion.width];
1085:
1086:                    for (int i = destinationRegion.x, x = sourceRegion.x, j = 0; i < destinationRegion.x
1087:                            + destinationRegion.width; i++, j++, x += scaleX) {
1088:                        srcPos[j] = x >> 1;
1089:                        srcOff[j] = (1 - (x & 1)) << 2;
1090:                        destPos[j] = i >> 1;
1091:                        destOff[j] = (1 - (i & 1)) << 2;
1092:                    }
1093:
1094:                    int k = destinationRegion.y * lineStride;
1095:                    if (isBottomUp)
1096:                        k += (destinationRegion.height - 1) * lineStride;
1097:
1098:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1099:
1100:                        if (abortRequested())
1101:                            break;
1102:                        iis.read(buf, 0, lineLength);
1103:                        for (int i = 0; i < destinationRegion.width; i++) {
1104:                            //get the bit and assign to the data buffer of the raster
1105:                            int v = (buf[srcPos[i]] >> srcOff[i]) & 0x0F;
1106:                            bdata[k + destPos[i]] |= v << destOff[i];
1107:                        }
1108:
1109:                        k += isBottomUp ? -lineStride : lineStride;
1110:                        iis.skipBytes(skipLength);
1111:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1112:                                1, 1, 1, new int[] { 0 });
1113:                        processImageProgress(100.0F * j
1114:                                / destinationRegion.height);
1115:                    }
1116:                }
1117:            }
1118:
1119:            // Method to read 8 bit BMP image data
1120:            private void read8Bit(byte[] bdata) throws IOException {
1121:
1122:                // Padding bytes at the end of each scanline
1123:                int padding = width % 4;
1124:                if (padding != 0) {
1125:                    padding = 4 - padding;
1126:                }
1127:
1128:                int lineLength = width + padding;
1129:
1130:                if (noTransform) {
1131:                    int j = isBottomUp ? (height - 1) * width : 0;
1132:
1133:                    for (int i = 0; i < height; i++) {
1134:                        if (abortRequested()) {
1135:                            break;
1136:                        }
1137:                        iis.readFully(bdata, j, width);
1138:                        iis.skipBytes(padding);
1139:                        j += isBottomUp ? -width : width;
1140:                        processImageUpdate(bi, 0, i, destinationRegion.width,
1141:                                1, 1, 1, new int[] { 0 });
1142:                        processImageProgress(100.0F * i
1143:                                / destinationRegion.height);
1144:                    }
1145:                } else {
1146:                    byte[] buf = new byte[lineLength];
1147:                    int lineStride = ((ComponentSampleModel) sampleModel)
1148:                            .getScanlineStride();
1149:
1150:                    if (isBottomUp) {
1151:                        int lastLine = sourceRegion.y
1152:                                + (destinationRegion.height - 1) * scaleY;
1153:                        iis.skipBytes(lineLength * (height - 1 - lastLine));
1154:                    } else
1155:                        iis.skipBytes(lineLength * sourceRegion.y);
1156:
1157:                    int skipLength = lineLength * (scaleY - 1);
1158:
1159:                    int k = destinationRegion.y * lineStride;
1160:                    if (isBottomUp)
1161:                        k += (destinationRegion.height - 1) * lineStride;
1162:                    k += destinationRegion.x;
1163:
1164:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1165:
1166:                        if (abortRequested())
1167:                            break;
1168:                        iis.read(buf, 0, lineLength);
1169:                        for (int i = 0, m = sourceRegion.x; i < destinationRegion.width; i++, m += scaleX) {
1170:                            //get the bit and assign to the data buffer of the raster
1171:                            bdata[k + i] = buf[m];
1172:                        }
1173:
1174:                        k += isBottomUp ? -lineStride : lineStride;
1175:                        iis.skipBytes(skipLength);
1176:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1177:                                1, 1, 1, new int[] { 0 });
1178:                        processImageProgress(100.0F * j
1179:                                / destinationRegion.height);
1180:                    }
1181:                }
1182:            }
1183:
1184:            // Method to read 24 bit BMP image data
1185:            private void read24Bit(byte[] bdata) throws IOException {
1186:                // Padding bytes at the end of each scanline
1187:                // width * bitsPerPixel should be divisible by 32
1188:                int padding = width * 3 % 4;
1189:                if (padding != 0)
1190:                    padding = 4 - padding;
1191:
1192:                int lineStride = width * 3;
1193:                int lineLength = lineStride + padding;
1194:
1195:                if (noTransform) {
1196:                    int j = isBottomUp ? (height - 1) * width * 3 : 0;
1197:
1198:                    for (int i = 0; i < height; i++) {
1199:                        if (abortRequested()) {
1200:                            break;
1201:                        }
1202:                        iis.readFully(bdata, j, lineStride);
1203:                        iis.skipBytes(padding);
1204:                        j += isBottomUp ? -lineStride : lineStride;
1205:                        processImageUpdate(bi, 0, i, destinationRegion.width,
1206:                                1, 1, 1, new int[] { 0 });
1207:                        processImageProgress(100.0F * i
1208:                                / destinationRegion.height);
1209:                    }
1210:                } else {
1211:                    byte[] buf = new byte[lineLength];
1212:                    lineStride = ((ComponentSampleModel) sampleModel)
1213:                            .getScanlineStride();
1214:
1215:                    if (isBottomUp) {
1216:                        int lastLine = sourceRegion.y
1217:                                + (destinationRegion.height - 1) * scaleY;
1218:                        iis.skipBytes(lineLength * (height - 1 - lastLine));
1219:                    } else
1220:                        iis.skipBytes(lineLength * sourceRegion.y);
1221:
1222:                    int skipLength = lineLength * (scaleY - 1);
1223:
1224:                    int k = destinationRegion.y * lineStride;
1225:                    if (isBottomUp)
1226:                        k += (destinationRegion.height - 1) * lineStride;
1227:                    k += destinationRegion.x * 3;
1228:
1229:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1230:
1231:                        if (abortRequested())
1232:                            break;
1233:                        iis.read(buf, 0, lineLength);
1234:                        for (int i = 0, m = 3 * sourceRegion.x; i < destinationRegion.width; i++, m += 3 * scaleX) {
1235:                            //get the bit and assign to the data buffer of the raster
1236:                            int n = 3 * i + k;
1237:                            for (int b = 0; b < destBands.length; b++)
1238:                                bdata[n + destBands[b]] = buf[m
1239:                                        + sourceBands[b]];
1240:                        }
1241:
1242:                        k += isBottomUp ? -lineStride : lineStride;
1243:                        iis.skipBytes(skipLength);
1244:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1245:                                1, 1, 1, new int[] { 0 });
1246:                        processImageProgress(100.0F * j
1247:                                / destinationRegion.height);
1248:                    }
1249:                }
1250:            }
1251:
1252:            private void read16Bit(short sdata[]) throws IOException {
1253:                // Padding bytes at the end of each scanline
1254:                // width * bitsPerPixel should be divisible by 32
1255:                int padding = width * 2 % 4;
1256:
1257:                if (padding != 0)
1258:                    padding = 4 - padding;
1259:
1260:                int lineLength = width + padding / 2;
1261:
1262:                if (noTransform) {
1263:                    int j = isBottomUp ? (height - 1) * width : 0;
1264:                    for (int i = 0; i < height; i++) {
1265:                        if (abortRequested()) {
1266:                            break;
1267:                        }
1268:
1269:                        iis.readFully(sdata, j, width);
1270:                        iis.skipBytes(padding);
1271:                        j += isBottomUp ? -width : width;
1272:                        processImageUpdate(bi, 0, i, destinationRegion.width,
1273:                                1, 1, 1, new int[] { 0 });
1274:                        processImageProgress(100.0F * i
1275:                                / destinationRegion.height);
1276:                    }
1277:                } else {
1278:                    short[] buf = new short[lineLength];
1279:                    int lineStride = ((SinglePixelPackedSampleModel) sampleModel)
1280:                            .getScanlineStride();
1281:
1282:                    if (isBottomUp) {
1283:                        int lastLine = sourceRegion.y
1284:                                + (destinationRegion.height - 1) * scaleY;
1285:                        iis
1286:                                .skipBytes(lineLength * (height - 1 - lastLine) << 1);
1287:                    } else
1288:                        iis.skipBytes(lineLength * sourceRegion.y << 1);
1289:
1290:                    int skipLength = lineLength * (scaleY - 1) << 1;
1291:
1292:                    int k = destinationRegion.y * lineStride;
1293:                    if (isBottomUp)
1294:                        k += (destinationRegion.height - 1) * lineStride;
1295:                    k += destinationRegion.x;
1296:
1297:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1298:
1299:                        if (abortRequested())
1300:                            break;
1301:                        iis.readFully(buf, 0, lineLength);
1302:                        for (int i = 0, m = sourceRegion.x; i < destinationRegion.width; i++, m += scaleX) {
1303:                            //get the bit and assign to the data buffer of the raster
1304:                            sdata[k + i] = buf[m];
1305:                        }
1306:
1307:                        k += isBottomUp ? -lineStride : lineStride;
1308:                        iis.skipBytes(skipLength);
1309:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1310:                                1, 1, 1, new int[] { 0 });
1311:                        processImageProgress(100.0F * j
1312:                                / destinationRegion.height);
1313:                    }
1314:                }
1315:            }
1316:
1317:            private void read32Bit(int idata[]) throws IOException {
1318:                if (noTransform) {
1319:                    int j = isBottomUp ? (height - 1) * width : 0;
1320:
1321:                    for (int i = 0; i < height; i++) {
1322:                        if (abortRequested()) {
1323:                            break;
1324:                        }
1325:                        iis.readFully(idata, j, width);
1326:                        j += isBottomUp ? -width : width;
1327:                        processImageUpdate(bi, 0, i, destinationRegion.width,
1328:                                1, 1, 1, new int[] { 0 });
1329:                        processImageProgress(100.0F * i
1330:                                / destinationRegion.height);
1331:                    }
1332:                } else {
1333:                    int[] buf = new int[width];
1334:                    int lineStride = ((SinglePixelPackedSampleModel) sampleModel)
1335:                            .getScanlineStride();
1336:
1337:                    if (isBottomUp) {
1338:                        int lastLine = sourceRegion.y
1339:                                + (destinationRegion.height - 1) * scaleY;
1340:                        iis.skipBytes(width * (height - 1 - lastLine) << 2);
1341:                    } else
1342:                        iis.skipBytes(width * sourceRegion.y << 2);
1343:
1344:                    int skipLength = width * (scaleY - 1) << 2;
1345:
1346:                    int k = destinationRegion.y * lineStride;
1347:                    if (isBottomUp)
1348:                        k += (destinationRegion.height - 1) * lineStride;
1349:                    k += destinationRegion.x;
1350:
1351:                    for (int j = 0, y = sourceRegion.y; j < destinationRegion.height; j++, y += scaleY) {
1352:
1353:                        if (abortRequested())
1354:                            break;
1355:                        iis.readFully(buf, 0, width);
1356:                        for (int i = 0, m = sourceRegion.x; i < destinationRegion.width; i++, m += scaleX) {
1357:                            //get the bit and assign to the data buffer of the raster
1358:                            idata[k + i] = buf[m];
1359:                        }
1360:
1361:                        k += isBottomUp ? -lineStride : lineStride;
1362:                        iis.skipBytes(skipLength);
1363:                        processImageUpdate(bi, 0, j, destinationRegion.width,
1364:                                1, 1, 1, new int[] { 0 });
1365:                        processImageProgress(100.0F * j
1366:                                / destinationRegion.height);
1367:                    }
1368:                }
1369:            }
1370:
1371:            private void readRLE8(byte bdata[]) throws IOException {
1372:                // If imageSize field is not provided, calculate it.
1373:                int imSize = (int) imageSize;
1374:                if (imSize == 0) {
1375:                    imSize = (int) (bitmapFileSize - bitmapOffset);
1376:                }
1377:
1378:                int padding = 0;
1379:                // If width is not 32 bit aligned, then while uncompressing each
1380:                // scanline will have padding bytes, calculate the amount of padding
1381:                int remainder = width % 4;
1382:                if (remainder != 0) {
1383:                    padding = 4 - remainder;
1384:                }
1385:
1386:                // Read till we have the whole image
1387:                byte values[] = new byte[imSize];
1388:                int bytesRead = 0;
1389:                iis.readFully(values, 0, imSize);
1390:
1391:                // Since data is compressed, decompress it
1392:                decodeRLE8(imSize, padding, values, bdata);
1393:            }
1394:
1395:            private void decodeRLE8(int imSize, int padding, byte[] values,
1396:                    byte[] bdata) throws IOException {
1397:
1398:                byte val[] = new byte[width * height];
1399:                int count = 0, l = 0;
1400:                int value;
1401:                boolean flag = false;
1402:                int lineNo = isBottomUp ? height - 1 : 0;
1403:                int lineStride = ((ComponentSampleModel) sampleModel)
1404:                        .getScanlineStride();
1405:                int finished = 0;
1406:
1407:                while (count != imSize) {
1408:                    value = values[count++] & 0xff;
1409:                    if (value == 0) {
1410:                        switch (values[count++] & 0xff) {
1411:
1412:                        case 0:
1413:                        case 1:
1414:                            // 0 is End-of-scanline marker, 1 is End-of-RLE marker
1415:                            // In either case, we want to copy the just decoded 
1416:                            // scanline from val array to bdata array
1417:                            if (lineNo >= sourceRegion.y
1418:                                    && lineNo < sourceRegion.y
1419:                                            + sourceRegion.height) {
1420:                                if (noTransform) {
1421:                                    int pos = lineNo * width;
1422:                                    for (int i = 0; i < width; i++)
1423:                                        bdata[pos++] = val[i];
1424:                                    processImageUpdate(bi, 0, lineNo,
1425:                                            destinationRegion.width, 1, 1, 1,
1426:                                            new int[] { 0 });
1427:                                    finished++;
1428:                                } else if ((lineNo - sourceRegion.y) % scaleY == 0) {
1429:                                    int currentLine = (lineNo - sourceRegion.y)
1430:                                            / scaleY + destinationRegion.y;
1431:                                    int pos = currentLine * lineStride;
1432:                                    pos += destinationRegion.x;
1433:                                    for (int i = sourceRegion.x; i < sourceRegion.x
1434:                                            + sourceRegion.width; i += scaleX)
1435:                                        bdata[pos++] = val[i];
1436:                                    processImageUpdate(bi, 0, currentLine,
1437:                                            destinationRegion.width, 1, 1, 1,
1438:                                            new int[] { 0 });
1439:                                    finished++;
1440:                                }
1441:                            }
1442:                            processImageProgress(100.0F * finished
1443:                                    / destinationRegion.height);
1444:                            lineNo += isBottomUp ? -1 : 1;
1445:                            l = 0;
1446:
1447:                            if (abortRequested()) {
1448:                                break;
1449:                            }
1450:
1451:                            // End-of-RLE marker
1452:                            if ((values[count - 1] & 0xff) == 1)
1453:                                flag = true;
1454:
1455:                            break;
1456:
1457:                        case 2:
1458:                            // delta or vector marker
1459:                            int xoff = values[count++] & 0xff;
1460:                            int yoff = values[count] & 0xff;
1461:                            // Move to the position xoff, yoff down
1462:                            l += xoff + yoff * width;
1463:                            break;
1464:
1465:                        default:
1466:                            int end = values[count - 1] & 0xff;
1467:                            for (int i = 0; i < end; i++) {
1468:                                val[l++] = (byte) (values[count++] & 0xff);
1469:                            }
1470:
1471:                            // Whenever end pixels can fit into odd number of bytes,
1472:                            // an extra padding byte will be present, so skip that.
1473:                            if ((end & 1) == 1) {
1474:                                count++;
1475:                            }
1476:                        }
1477:                    } else {
1478:                        for (int i = 0; i < value; i++) {
1479:                            val[l++] = (byte) (values[count] & 0xff);
1480:                        }
1481:
1482:                        count++;
1483:                    }
1484:
1485:                    // If End-of-RLE data, then exit the while loop
1486:                    if (flag) {
1487:                        break;
1488:                    }
1489:                }
1490:            }
1491:
1492:            private void readRLE4(byte[] bdata) throws IOException {
1493:
1494:                // If imageSize field is not specified, calculate it.
1495:                int imSize = (int) imageSize;
1496:                if (imSize == 0) {
1497:                    imSize = (int) (bitmapFileSize - bitmapOffset);
1498:                }
1499:
1500:                int padding = 0;
1501:                // If width is not 32 byte aligned, then while uncompressing each
1502:                // scanline will have padding bytes, calculate the amount of padding
1503:                int remainder = width % 4;
1504:                if (remainder != 0) {
1505:                    padding = 4 - remainder;
1506:                }
1507:
1508:                // Read till we have the whole image
1509:                byte[] values = new byte[imSize];
1510:                iis.readFully(values, 0, imSize);
1511:
1512:                // Decompress the RLE4 compressed data.
1513:                decodeRLE4(imSize, padding, values, bdata);
1514:            }
1515:
1516:            private void decodeRLE4(int imSize, int padding, byte[] values,
1517:                    byte[] bdata) throws IOException {
1518:                byte[] val = new byte[width];
1519:                int count = 0, l = 0;
1520:                int value;
1521:                boolean flag = false;
1522:                int lineNo = isBottomUp ? height - 1 : 0;
1523:                int lineStride = ((MultiPixelPackedSampleModel) sampleModel)
1524:                        .getScanlineStride();
1525:                int finished = 0;
1526:
1527:                while (count != imSize) {
1528:
1529:                    value = values[count++] & 0xFF;
1530:                    if (value == 0) {
1531:
1532:                        // Absolute mode
1533:                        switch (values[count++] & 0xFF) {
1534:
1535:                        case 0:
1536:                        case 1:
1537:                            // 0 is End-of-scanline marker, 1 is End-of-RLE marker
1538:                            // In either case, we want to copy the just decoded 
1539:                            // scanline from val array to bdata array
1540:                            if (lineNo >= sourceRegion.y
1541:                                    && lineNo < sourceRegion.y
1542:                                            + sourceRegion.height) {
1543:                                if (noTransform) {
1544:                                    int pos = lineNo * (width + 1 >> 1);
1545:                                    for (int i = 0, j = 0; i < width >> 1; i++)
1546:                                        bdata[pos++] = (byte) ((val[j++] << 4) | val[j++]);
1547:                                    if ((width & 1) == 1)
1548:                                        bdata[pos] |= val[width - 1] << 4;
1549:
1550:                                    processImageUpdate(bi, 0, lineNo,
1551:                                            destinationRegion.width, 1, 1, 1,
1552:                                            new int[] { 0 });
1553:                                    finished++;
1554:                                } else if ((lineNo - sourceRegion.y) % scaleY == 0) {
1555:                                    int currentLine = (lineNo - sourceRegion.y)
1556:                                            / scaleY + destinationRegion.y;
1557:                                    int pos = currentLine * lineStride;
1558:                                    pos += destinationRegion.x >> 1;
1559:                                    int shift = (1 - (destinationRegion.x & 1)) << 2;
1560:                                    for (int i = sourceRegion.x; i < sourceRegion.x
1561:                                            + sourceRegion.width; i += scaleX) {
1562:                                        bdata[pos] |= val[i] << shift;
1563:                                        shift += 4;
1564:                                        if (shift == 4) {
1565:                                            pos++;
1566:                                        }
1567:                                        shift &= 7;
1568:                                    }
1569:                                    processImageUpdate(bi, 0, currentLine,
1570:                                            destinationRegion.width, 1, 1, 1,
1571:                                            new int[] { 0 });
1572:                                    finished++;
1573:                                }
1574:                            }
1575:                            processImageProgress(100.0F * finished
1576:                                    / destinationRegion.height);
1577:                            lineNo += isBottomUp ? -1 : 1;
1578:                            l = 0;
1579:
1580:                            if (abortRequested()) {
1581:                                break;
1582:                            }
1583:
1584:                            // End-of-RLE marker
1585:                            if ((values[count - 1] & 0xff) == 1)
1586:                                flag = true;
1587:                            break;
1588:
1589:                        case 2:
1590:                            // delta or vector marker
1591:                            int xoff = values[count++] & 0xFF;
1592:                            int yoff = values[count] & 0xFF;
1593:                            // Move to the position xoff, yoff down
1594:                            l += xoff + yoff * width;
1595:                            break;
1596:
1597:                        default:
1598:                            int end = values[count - 1] & 0xFF;
1599:                            for (int i = 0; i < end; i++) {
1600:                                val[l++] = (byte) (((i & 1) == 0) ? (values[count] & 0xf0) >> 4
1601:                                        : (values[count++] & 0x0f));
1602:                            }
1603:
1604:                            // When end is odd, the above for loop does not
1605:                            // increment count, so do it now.
1606:                            if ((end & 1) == 1) {
1607:                                count++;
1608:                            }
1609:
1610:                            // Whenever end pixels can fit into odd number of bytes,
1611:                            // an extra padding byte will be present, so skip that.
1612:                            if ((((int) Math.ceil(end / 2)) & 1) == 1) {
1613:                                count++;
1614:                            }
1615:                            break;
1616:                        }
1617:                    } else {
1618:                        // Encoded mode
1619:                        int alternate[] = { (values[count] & 0xf0) >> 4,
1620:                                values[count] & 0x0f };
1621:                        for (int i = 0; (i < value) && (l < width); i++) {
1622:                            val[l++] = (byte) alternate[i & 1];
1623:                        }
1624:
1625:                        count++;
1626:                    }
1627:
1628:                    // If End-of-RLE data, then exit the while loop
1629:                    if (flag) {
1630:                        break;
1631:                    }
1632:                }
1633:            }
1634:
1635:            /** Decodes the jpeg/png image embedded in the bitmap using any jpeg
1636:             *  ImageIO-style plugin.
1637:             *
1638:             * @param bi The destination <code>BufferedImage</code>.
1639:             * @param bmpParam The <code>ImageReadParam</code> for decoding this
1640:             *          BMP image.  The parameters for subregion, band selection and
1641:             *          subsampling are used in decoding the jpeg image.
1642:             */
1643:
1644:            private BufferedImage readEmbedded(int type, BufferedImage bi,
1645:                    ImageReadParam bmpParam) throws IOException {
1646:                String format;
1647:                switch (type) {
1648:                case BI_JPEG:
1649:                    format = "JPEG";
1650:                    break;
1651:                case BI_PNG:
1652:                    format = "PNG";
1653:                    break;
1654:                default:
1655:                    throw new IOException("Unexpected compression type: "
1656:                            + type);
1657:                }
1658:                ImageReader reader = (ImageReader) ImageIO
1659:                        .getImageReadersByFormatName(format).next();
1660:                if (reader == null) {
1661:                    throw new RuntimeException(I18N
1662:                            .getString("BMPImageReader4")
1663:                            + " " + format);
1664:                }
1665:                // prepare input
1666:                byte[] buff = new byte[(int) imageSize];
1667:                iis.read(buff);
1668:                reader
1669:                        .setInput(ImageIO
1670:                                .createImageInputStream(new ByteArrayInputStream(
1671:                                        buff)));
1672:                if (bi == null) {
1673:                    ImageTypeSpecifier embType = (ImageTypeSpecifier) reader
1674:                            .getImageTypes(0).next();
1675:                    bi = embType.createBufferedImage(destinationRegion.x
1676:                            + destinationRegion.width, destinationRegion.y
1677:                            + destinationRegion.height);
1678:                }
1679:
1680:                reader
1681:                        .addIIOReadProgressListener(new EmbeddedProgressAdapter() {
1682:                            public void imageProgress(ImageReader source,
1683:                                    float percentageDone) {
1684:                                processImageProgress(percentageDone);
1685:                            }
1686:                        });
1687:
1688:                reader.addIIOReadUpdateListener(new IIOReadUpdateListener() {
1689:                    public void imageUpdate(ImageReader source,
1690:                            BufferedImage theImage, int minX, int minY,
1691:                            int width, int height, int periodX, int periodY,
1692:                            int[] bands) {
1693:                        processImageUpdate(theImage, minX, minY, width, height,
1694:                                periodX, periodY, bands);
1695:                    }
1696:
1697:                    public void passComplete(ImageReader source,
1698:                            BufferedImage theImage) {
1699:                        processPassComplete(theImage);
1700:                    }
1701:
1702:                    public void passStarted(ImageReader source,
1703:                            BufferedImage theImage, int pass, int minPass,
1704:                            int maxPass, int minX, int minY, int periodX,
1705:                            int periodY, int[] bands) {
1706:                        processPassStarted(theImage, pass, minPass, maxPass,
1707:                                minX, minY, periodX, periodY, bands);
1708:                    }
1709:
1710:                    public void thumbnailPassComplete(ImageReader source,
1711:                            BufferedImage thumb) {
1712:                    }
1713:
1714:                    public void thumbnailPassStarted(ImageReader source,
1715:                            BufferedImage thumb, int pass, int minPass,
1716:                            int maxPass, int minX, int minY, int periodX,
1717:                            int periodY, int[] bands) {
1718:                    }
1719:
1720:                    public void thumbnailUpdate(ImageReader source,
1721:                            BufferedImage theThumbnail, int minX, int minY,
1722:                            int width, int height, int periodX, int periodY,
1723:                            int[] bands) {
1724:                    }
1725:                });
1726:
1727:                reader.addIIOReadWarningListener(new IIOReadWarningListener() {
1728:                    public void warningOccurred(ImageReader source,
1729:                            String warning) {
1730:                        processWarningOccurred(warning);
1731:                    }
1732:                });
1733:
1734:                ImageReadParam param = reader.getDefaultReadParam();
1735:                param.setDestination(bi);
1736:                param.setDestinationBands(bmpParam.getDestinationBands());
1737:                param.setDestinationOffset(bmpParam.getDestinationOffset());
1738:                param.setSourceBands(bmpParam.getSourceBands());
1739:                param.setSourceRegion(bmpParam.getSourceRegion());
1740:                param.setSourceSubsampling(bmpParam.getSourceXSubsampling(),
1741:                        bmpParam.getSourceYSubsampling(), bmpParam
1742:                                .getSubsamplingXOffset(), bmpParam
1743:                                .getSubsamplingYOffset());
1744:                reader.read(0, param);
1745:                return bi;
1746:            }
1747:
1748:            private class EmbeddedProgressAdapter implements 
1749:                    IIOReadProgressListener {
1750:                public void imageComplete(ImageReader src) {
1751:                }
1752:
1753:                public void imageProgress(ImageReader src, float percentageDone) {
1754:                }
1755:
1756:                public void imageStarted(ImageReader src, int imageIndex) {
1757:                }
1758:
1759:                public void thumbnailComplete(ImageReader src) {
1760:                }
1761:
1762:                public void thumbnailProgress(ImageReader src,
1763:                        float percentageDone) {
1764:                }
1765:
1766:                public void thumbnailStarted(ImageReader src, int iIdx, int tIdx) {
1767:                }
1768:
1769:                public void sequenceComplete(ImageReader src) {
1770:                }
1771:
1772:                public void sequenceStarted(ImageReader src, int minIndex) {
1773:                }
1774:
1775:                public void readAborted(ImageReader src) {
1776:                }
1777:            }
1778:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.