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


0001:        /*
0002:         * $RCSfile: ImageUtil.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.7 $
0042:         * $Date: 2007/08/28 18:45:06 $
0043:         * $State: Exp $
0044:         */
0045:        package com.sun.media.imageioimpl.common;
0046:
0047:        import java.awt.Point;
0048:        import java.awt.Rectangle;
0049:        import java.awt.Transparency;
0050:        import java.awt.color.ColorSpace;
0051:        import java.awt.color.ICC_ColorSpace;
0052:        import java.awt.image.BufferedImage;
0053:        import java.awt.image.ColorModel;
0054:        import java.awt.image.ComponentColorModel;
0055:        import java.awt.image.ComponentSampleModel;
0056:        import java.awt.image.DataBuffer;
0057:        import java.awt.image.DataBufferByte;
0058:        import java.awt.image.DataBufferInt;
0059:        import java.awt.image.DataBufferShort;
0060:        import java.awt.image.DataBufferUShort;
0061:        import java.awt.image.DirectColorModel;
0062:        import java.awt.image.IndexColorModel;
0063:        import java.awt.image.MultiPixelPackedSampleModel;
0064:        import java.awt.image.Raster;
0065:        import java.awt.image.RenderedImage;
0066:        import java.awt.image.SampleModel;
0067:        import java.awt.image.SinglePixelPackedSampleModel;
0068:        import java.awt.image.WritableRaster;
0069:        import java.io.IOException;
0070:        import java.util.Arrays;
0071:        import java.util.ArrayList;
0072:        import java.util.Iterator;
0073:        import java.util.List;
0074:        import java.util.Locale;
0075:
0076:        //import javax.imageio.ImageTypeSpecifier;
0077:
0078:        import javax.imageio.IIOException;
0079:        import javax.imageio.IIOImage;
0080:        import javax.imageio.ImageReadParam;
0081:        import javax.imageio.ImageTypeSpecifier;
0082:        import javax.imageio.ImageWriter;
0083:        import javax.imageio.spi.IIORegistry;
0084:        import javax.imageio.spi.ImageReaderSpi;
0085:        import javax.imageio.spi.ImageReaderWriterSpi;
0086:        import javax.imageio.spi.ImageWriterSpi;
0087:        import javax.imageio.spi.ServiceRegistry;
0088:        import javax.imageio.stream.ImageInputStream;
0089:
0090:        public class ImageUtil {
0091:            /* XXX testing only
0092:            public static void main(String[] args) {
0093:                ImageTypeSpecifier bilevel =
0094:                    ImageTypeSpecifier.createIndexed(new byte[] {(byte)0, (byte)255},
0095:                                                     new byte[] {(byte)0, (byte)255},
0096:                                                     new byte[] {(byte)0, (byte)255},
0097:                                                     null, 1,
0098:                                                     DataBuffer.TYPE_BYTE);
0099:                ImageTypeSpecifier gray =
0100:                    ImageTypeSpecifier.createGrayscale(8, DataBuffer.TYPE_BYTE, false);
0101:                ImageTypeSpecifier grayAlpha =
0102:                    ImageTypeSpecifier.createGrayscale(8, DataBuffer.TYPE_BYTE, false,
0103:                                                       false);
0104:                ImageTypeSpecifier rgb =
0105:                    ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_sRGB),
0106:                                                         new int[] {0, 1, 2},
0107:                                                         DataBuffer.TYPE_BYTE,
0108:                                                         false,
0109:                                                         false);
0110:                ImageTypeSpecifier rgba =
0111:                    ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_sRGB),
0112:                                                         new int[] {0, 1, 2, 3},
0113:                                                         DataBuffer.TYPE_BYTE,
0114:                                                         true,
0115:                                                         false);
0116:                ImageTypeSpecifier packed =
0117:                    ImageTypeSpecifier.createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB),
0118:                                                    0xff000000,
0119:                                                    0x00ff0000,
0120:                                                    0x0000ff00,
0121:                                                    0x000000ff,
0122:                                                    DataBuffer.TYPE_BYTE,
0123:                                                    false);
0124:
0125:                SampleModel bandedSM =
0126:                    new java.awt.image.BandedSampleModel(DataBuffer.TYPE_BYTE,
0127:                                                         1, 1, 15);
0128:
0129:                System.out.println(createColorModel(bilevel.getSampleModel()));
0130:                System.out.println(createColorModel(gray.getSampleModel()));
0131:                System.out.println(createColorModel(grayAlpha.getSampleModel()));
0132:                System.out.println(createColorModel(rgb.getSampleModel()));
0133:                System.out.println(createColorModel(rgba.getSampleModel()));
0134:                System.out.println(createColorModel(packed.getSampleModel()));
0135:                System.out.println(createColorModel(bandedSM));
0136:            }
0137:             */
0138:
0139:            /**
0140:             * Creates a <code>ColorModel</code> that may be used with the
0141:             * specified <code>SampleModel</code>.  If a suitable
0142:             * <code>ColorModel</code> cannot be found, this method returns
0143:             * <code>null</code>.
0144:             *
0145:             * <p> Suitable <code>ColorModel</code>s are guaranteed to exist
0146:             * for all instances of <code>ComponentSampleModel</code>.
0147:             * For 1- and 3- banded <code>SampleModel</code>s, the returned
0148:             * <code>ColorModel</code> will be opaque.  For 2- and 4-banded
0149:             * <code>SampleModel</code>s, the output will use alpha transparency
0150:             * which is not premultiplied.  1- and 2-banded data will use a
0151:             * grayscale <code>ColorSpace</code>, and 3- and 4-banded data a sRGB
0152:             * <code>ColorSpace</code>. Data with 5 or more bands will have a
0153:             * <code>BogusColorSpace</code>.</p>
0154:             *
0155:             * <p>An instance of <code>DirectColorModel</code> will be created for
0156:             * instances of <code>SinglePixelPackedSampleModel</code> with no more
0157:             * than 4 bands.</p>
0158:             *
0159:             * <p>An instance of <code>IndexColorModel</code> will be created for
0160:             * instances of <code>MultiPixelPackedSampleModel</code>. The colormap
0161:             * will be a grayscale ramp with <code>1&nbsp;<<&nbsp;numberOfBits</code>
0162:             * entries ranging from zero to at most 255.</p>
0163:             *
0164:             * @return An instance of <code>ColorModel</code> that is suitable for
0165:             *         the supplied <code>SampleModel</code>, or <code>null</code>.
0166:             *
0167:             * @throws IllegalArgumentException  If <code>sampleModel</code> is
0168:             *         <code>null</code>.
0169:             */
0170:            public static final ColorModel createColorModel(
0171:                    SampleModel sampleModel) {
0172:                // Check the parameter.
0173:                if (sampleModel == null) {
0174:                    throw new IllegalArgumentException("sampleModel == null!");
0175:                }
0176:
0177:                // Get the data type.
0178:                int dataType = sampleModel.getDataType();
0179:
0180:                // Check the data type
0181:                switch (dataType) {
0182:                case DataBuffer.TYPE_BYTE:
0183:                case DataBuffer.TYPE_USHORT:
0184:                case DataBuffer.TYPE_SHORT:
0185:                case DataBuffer.TYPE_INT:
0186:                case DataBuffer.TYPE_FLOAT:
0187:                case DataBuffer.TYPE_DOUBLE:
0188:                    break;
0189:                default:
0190:                    // Return null for other types.
0191:                    return null;
0192:                }
0193:
0194:                // The return variable.
0195:                ColorModel colorModel = null;
0196:
0197:                // Get the sample size.
0198:                int[] sampleSize = sampleModel.getSampleSize();
0199:
0200:                // Create a Component ColorModel.
0201:                if (sampleModel instanceof  ComponentSampleModel) {
0202:                    // Get the number of bands.
0203:                    int numBands = sampleModel.getNumBands();
0204:
0205:                    // Determine the color space.
0206:                    ColorSpace colorSpace = null;
0207:                    if (numBands <= 2) {
0208:                        colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
0209:                    } else if (numBands <= 4) {
0210:                        colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
0211:                    } else {
0212:                        colorSpace = new BogusColorSpace(numBands);
0213:                    }
0214:
0215:                    boolean hasAlpha = (numBands == 2) || (numBands == 4);
0216:                    boolean isAlphaPremultiplied = false;
0217:                    int transparency = hasAlpha ? Transparency.TRANSLUCENT
0218:                            : Transparency.OPAQUE;
0219:
0220:                    colorModel = new ComponentColorModel(colorSpace,
0221:                            sampleSize, hasAlpha, isAlphaPremultiplied,
0222:                            transparency, dataType);
0223:                } else if (sampleModel.getNumBands() <= 4
0224:                        && sampleModel instanceof  SinglePixelPackedSampleModel) {
0225:                    SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sampleModel;
0226:
0227:                    int[] bitMasks = sppsm.getBitMasks();
0228:                    int rmask = 0;
0229:                    int gmask = 0;
0230:                    int bmask = 0;
0231:                    int amask = 0;
0232:
0233:                    int numBands = bitMasks.length;
0234:                    if (numBands <= 2) {
0235:                        rmask = gmask = bmask = bitMasks[0];
0236:                        if (numBands == 2) {
0237:                            amask = bitMasks[1];
0238:                        }
0239:                    } else {
0240:                        rmask = bitMasks[0];
0241:                        gmask = bitMasks[1];
0242:                        bmask = bitMasks[2];
0243:                        if (numBands == 4) {
0244:                            amask = bitMasks[3];
0245:                        }
0246:                    }
0247:
0248:                    int bits = 0;
0249:                    for (int i = 0; i < sampleSize.length; i++) {
0250:                        bits += sampleSize[i];
0251:                    }
0252:
0253:                    return new DirectColorModel(bits, rmask, gmask, bmask,
0254:                            amask);
0255:
0256:                } else if (sampleModel instanceof  MultiPixelPackedSampleModel) {
0257:                    // Load the colormap with a ramp.
0258:                    int bitsPerSample = sampleSize[0];
0259:                    int numEntries = 1 << bitsPerSample;
0260:                    byte[] map = new byte[numEntries];
0261:                    for (int i = 0; i < numEntries; i++) {
0262:                        map[i] = (byte) (i * 255 / (numEntries - 1));
0263:                    }
0264:
0265:                    colorModel = new IndexColorModel(bitsPerSample, numEntries,
0266:                            map, map, map);
0267:
0268:                }
0269:
0270:                return colorModel;
0271:            }
0272:
0273:            /**
0274:             * For the case of binary data (<code>isBinary()</code> returns
0275:             * <code>true</code>), return the binary data as a packed byte array.
0276:             * The data will be packed as eight bits per byte with no bit offset,
0277:             * i.e., the first bit in each image line will be the left-most of the
0278:             * first byte of the line.  The line stride in bytes will be
0279:             * <code>(int)((getWidth()+7)/8)</code>.  The length of the returned
0280:             * array will be the line stride multiplied by <code>getHeight()</code>
0281:             *
0282:             * @return the binary data as a packed array of bytes with zero offset
0283:             * of <code>null</code> if the data are not binary.
0284:             * @throws IllegalArgumentException if <code>isBinary()</code> returns
0285:             * <code>false</code> with the <code>SampleModel</code> of the
0286:             * supplied <code>Raster</code> as argument.
0287:             */
0288:            public static byte[] getPackedBinaryData(Raster raster,
0289:                    Rectangle rect) {
0290:                SampleModel sm = raster.getSampleModel();
0291:                if (!isBinary(sm)) {
0292:                    throw new IllegalArgumentException(I18N
0293:                            .getString("ImageUtil0"));
0294:                }
0295:
0296:                int rectX = rect.x;
0297:                int rectY = rect.y;
0298:                int rectWidth = rect.width;
0299:                int rectHeight = rect.height;
0300:
0301:                DataBuffer dataBuffer = raster.getDataBuffer();
0302:
0303:                int dx = rectX - raster.getSampleModelTranslateX();
0304:                int dy = rectY - raster.getSampleModelTranslateY();
0305:
0306:                MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
0307:                int lineStride = mpp.getScanlineStride();
0308:                int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
0309:                int bitOffset = mpp.getBitOffset(dx);
0310:
0311:                int numBytesPerRow = (rectWidth + 7) / 8;
0312:                if (dataBuffer instanceof  DataBufferByte
0313:                        && eltOffset == 0
0314:                        && bitOffset == 0
0315:                        && numBytesPerRow == lineStride
0316:                        && ((DataBufferByte) dataBuffer).getData().length == numBytesPerRow
0317:                                * rectHeight) {
0318:                    return ((DataBufferByte) dataBuffer).getData();
0319:                }
0320:
0321:                byte[] binaryDataArray = new byte[numBytesPerRow * rectHeight];
0322:
0323:                int b = 0;
0324:
0325:                if (bitOffset == 0) {
0326:                    if (dataBuffer instanceof  DataBufferByte) {
0327:                        byte[] data = ((DataBufferByte) dataBuffer).getData();
0328:                        int stride = numBytesPerRow;
0329:                        int offset = 0;
0330:                        for (int y = 0; y < rectHeight; y++) {
0331:                            System.arraycopy(data, eltOffset, binaryDataArray,
0332:                                    offset, stride);
0333:                            offset += stride;
0334:                            eltOffset += lineStride;
0335:                        }
0336:                    } else if (dataBuffer instanceof  DataBufferShort
0337:                            || dataBuffer instanceof  DataBufferUShort) {
0338:                        short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0339:                                .getData()
0340:                                : ((DataBufferUShort) dataBuffer).getData();
0341:
0342:                        for (int y = 0; y < rectHeight; y++) {
0343:                            int xRemaining = rectWidth;
0344:                            int i = eltOffset;
0345:                            while (xRemaining > 8) {
0346:                                short datum = data[i++];
0347:                                binaryDataArray[b++] = (byte) ((datum >>> 8) & 0xFF);
0348:                                binaryDataArray[b++] = (byte) (datum & 0xFF);
0349:                                xRemaining -= 16;
0350:                            }
0351:                            if (xRemaining > 0) {
0352:                                binaryDataArray[b++] = (byte) ((data[i] >>> 8) & 0XFF);
0353:                            }
0354:                            eltOffset += lineStride;
0355:                        }
0356:                    } else if (dataBuffer instanceof  DataBufferInt) {
0357:                        int[] data = ((DataBufferInt) dataBuffer).getData();
0358:
0359:                        for (int y = 0; y < rectHeight; y++) {
0360:                            int xRemaining = rectWidth;
0361:                            int i = eltOffset;
0362:                            while (xRemaining > 24) {
0363:                                int datum = data[i++];
0364:                                binaryDataArray[b++] = (byte) ((datum >>> 24) & 0xFF);
0365:                                binaryDataArray[b++] = (byte) ((datum >>> 16) & 0xFF);
0366:                                binaryDataArray[b++] = (byte) ((datum >>> 8) & 0xFF);
0367:                                binaryDataArray[b++] = (byte) (datum & 0xFF);
0368:                                xRemaining -= 32;
0369:                            }
0370:                            int shift = 24;
0371:                            while (xRemaining > 0) {
0372:                                binaryDataArray[b++] = (byte) ((data[i] >>> shift) & 0xFF);
0373:                                shift -= 8;
0374:                                xRemaining -= 8;
0375:                            }
0376:                            eltOffset += lineStride;
0377:                        }
0378:                    }
0379:                } else { // bitOffset != 0
0380:                    if (dataBuffer instanceof  DataBufferByte) {
0381:                        byte[] data = ((DataBufferByte) dataBuffer).getData();
0382:
0383:                        if ((bitOffset & 7) == 0) {
0384:                            int stride = numBytesPerRow;
0385:                            int offset = 0;
0386:                            for (int y = 0; y < rectHeight; y++) {
0387:                                System.arraycopy(data, eltOffset,
0388:                                        binaryDataArray, offset, stride);
0389:                                offset += stride;
0390:                                eltOffset += lineStride;
0391:                            }
0392:                        } else { // bitOffset % 8 != 0
0393:                            int leftShift = bitOffset & 7;
0394:                            int rightShift = 8 - leftShift;
0395:                            for (int y = 0; y < rectHeight; y++) {
0396:                                int i = eltOffset;
0397:                                int xRemaining = rectWidth;
0398:                                while (xRemaining > 0) {
0399:                                    if (xRemaining > rightShift) {
0400:                                        binaryDataArray[b++] = (byte) (((data[i++] & 0xFF) << leftShift) | ((data[i] & 0xFF) >>> rightShift));
0401:                                    } else {
0402:                                        binaryDataArray[b++] = (byte) ((data[i] & 0xFF) << leftShift);
0403:                                    }
0404:                                    xRemaining -= 8;
0405:                                }
0406:                                eltOffset += lineStride;
0407:                            }
0408:                        }
0409:                    } else if (dataBuffer instanceof  DataBufferShort
0410:                            || dataBuffer instanceof  DataBufferUShort) {
0411:                        short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0412:                                .getData()
0413:                                : ((DataBufferUShort) dataBuffer).getData();
0414:
0415:                        for (int y = 0; y < rectHeight; y++) {
0416:                            int bOffset = bitOffset;
0417:                            for (int x = 0; x < rectWidth; x += 8, bOffset += 8) {
0418:                                int i = eltOffset + bOffset / 16;
0419:                                int mod = bOffset % 16;
0420:                                int left = data[i] & 0xFFFF;
0421:                                if (mod <= 8) {
0422:                                    binaryDataArray[b++] = (byte) (left >>> (8 - mod));
0423:                                } else {
0424:                                    int delta = mod - 8;
0425:                                    int right = data[i + 1] & 0xFFFF;
0426:                                    binaryDataArray[b++] = (byte) ((left << delta) | (right >>> (16 - delta)));
0427:                                }
0428:                            }
0429:                            eltOffset += lineStride;
0430:                        }
0431:                    } else if (dataBuffer instanceof  DataBufferInt) {
0432:                        int[] data = ((DataBufferInt) dataBuffer).getData();
0433:
0434:                        for (int y = 0; y < rectHeight; y++) {
0435:                            int bOffset = bitOffset;
0436:                            for (int x = 0; x < rectWidth; x += 8, bOffset += 8) {
0437:                                int i = eltOffset + bOffset / 32;
0438:                                int mod = bOffset % 32;
0439:                                int left = data[i];
0440:                                if (mod <= 24) {
0441:                                    binaryDataArray[b++] = (byte) (left >>> (24 - mod));
0442:                                } else {
0443:                                    int delta = mod - 24;
0444:                                    int right = data[i + 1];
0445:                                    binaryDataArray[b++] = (byte) ((left << delta) | (right >>> (32 - delta)));
0446:                                }
0447:                            }
0448:                            eltOffset += lineStride;
0449:                        }
0450:                    }
0451:                }
0452:
0453:                return binaryDataArray;
0454:            }
0455:
0456:            /**
0457:             * Returns the binary data unpacked into an array of bytes.
0458:             * The line stride will be the width of the <code>Raster</code>.
0459:             *
0460:             * @throws IllegalArgumentException if <code>isBinary()</code> returns
0461:             * <code>false</code> with the <code>SampleModel</code> of the
0462:             * supplied <code>Raster</code> as argument.
0463:             */
0464:            public static byte[] getUnpackedBinaryData(Raster raster,
0465:                    Rectangle rect) {
0466:                SampleModel sm = raster.getSampleModel();
0467:                if (!isBinary(sm)) {
0468:                    throw new IllegalArgumentException(I18N
0469:                            .getString("ImageUtil0"));
0470:                }
0471:
0472:                int rectX = rect.x;
0473:                int rectY = rect.y;
0474:                int rectWidth = rect.width;
0475:                int rectHeight = rect.height;
0476:
0477:                DataBuffer dataBuffer = raster.getDataBuffer();
0478:
0479:                int dx = rectX - raster.getSampleModelTranslateX();
0480:                int dy = rectY - raster.getSampleModelTranslateY();
0481:
0482:                MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
0483:                int lineStride = mpp.getScanlineStride();
0484:                int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
0485:                int bitOffset = mpp.getBitOffset(dx);
0486:
0487:                byte[] bdata = new byte[rectWidth * rectHeight];
0488:                int maxY = rectY + rectHeight;
0489:                int maxX = rectX + rectWidth;
0490:                int k = 0;
0491:
0492:                if (dataBuffer instanceof  DataBufferByte) {
0493:                    byte[] data = ((DataBufferByte) dataBuffer).getData();
0494:                    for (int y = rectY; y < maxY; y++) {
0495:                        int bOffset = eltOffset * 8 + bitOffset;
0496:                        for (int x = rectX; x < maxX; x++) {
0497:                            byte b = data[bOffset / 8];
0498:                            bdata[k++] = (byte) ((b >>> (7 - bOffset & 7)) & 0x0000001);
0499:                            bOffset++;
0500:                        }
0501:                        eltOffset += lineStride;
0502:                    }
0503:                } else if (dataBuffer instanceof  DataBufferShort
0504:                        || dataBuffer instanceof  DataBufferUShort) {
0505:                    short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0506:                            .getData()
0507:                            : ((DataBufferUShort) dataBuffer).getData();
0508:                    for (int y = rectY; y < maxY; y++) {
0509:                        int bOffset = eltOffset * 16 + bitOffset;
0510:                        for (int x = rectX; x < maxX; x++) {
0511:                            short s = data[bOffset / 16];
0512:                            bdata[k++] = (byte) ((s >>> (15 - bOffset % 16)) & 0x0000001);
0513:                            bOffset++;
0514:                        }
0515:                        eltOffset += lineStride;
0516:                    }
0517:                } else if (dataBuffer instanceof  DataBufferInt) {
0518:                    int[] data = ((DataBufferInt) dataBuffer).getData();
0519:                    for (int y = rectY; y < maxY; y++) {
0520:                        int bOffset = eltOffset * 32 + bitOffset;
0521:                        for (int x = rectX; x < maxX; x++) {
0522:                            int i = data[bOffset / 32];
0523:                            bdata[k++] = (byte) ((i >>> (31 - bOffset % 32)) & 0x0000001);
0524:                            bOffset++;
0525:                        }
0526:                        eltOffset += lineStride;
0527:                    }
0528:                }
0529:
0530:                return bdata;
0531:            }
0532:
0533:            /**
0534:             * Sets the supplied <code>Raster</code>'s data from an array
0535:             * of packed binary data of the form returned by
0536:             * <code>getPackedBinaryData()</code>.
0537:             *
0538:             * @throws IllegalArgumentException if <code>isBinary()</code> returns
0539:             * <code>false</code> with the <code>SampleModel</code> of the
0540:             * supplied <code>Raster</code> as argument.
0541:             */
0542:            public static void setPackedBinaryData(byte[] binaryDataArray,
0543:                    WritableRaster raster, Rectangle rect) {
0544:                SampleModel sm = raster.getSampleModel();
0545:                if (!isBinary(sm)) {
0546:                    throw new IllegalArgumentException(I18N
0547:                            .getString("ImageUtil0"));
0548:                }
0549:
0550:                int rectX = rect.x;
0551:                int rectY = rect.y;
0552:                int rectWidth = rect.width;
0553:                int rectHeight = rect.height;
0554:
0555:                DataBuffer dataBuffer = raster.getDataBuffer();
0556:
0557:                int dx = rectX - raster.getSampleModelTranslateX();
0558:                int dy = rectY - raster.getSampleModelTranslateY();
0559:
0560:                MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
0561:                int lineStride = mpp.getScanlineStride();
0562:                int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
0563:                int bitOffset = mpp.getBitOffset(dx);
0564:
0565:                int b = 0;
0566:
0567:                if (bitOffset == 0) {
0568:                    if (dataBuffer instanceof  DataBufferByte) {
0569:                        byte[] data = ((DataBufferByte) dataBuffer).getData();
0570:                        if (data == binaryDataArray) {
0571:                            // Optimal case: simply return.
0572:                            return;
0573:                        }
0574:                        int stride = (rectWidth + 7) / 8;
0575:                        int offset = 0;
0576:                        for (int y = 0; y < rectHeight; y++) {
0577:                            System.arraycopy(binaryDataArray, offset, data,
0578:                                    eltOffset, stride);
0579:                            offset += stride;
0580:                            eltOffset += lineStride;
0581:                        }
0582:                    } else if (dataBuffer instanceof  DataBufferShort
0583:                            || dataBuffer instanceof  DataBufferUShort) {
0584:                        short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0585:                                .getData()
0586:                                : ((DataBufferUShort) dataBuffer).getData();
0587:
0588:                        for (int y = 0; y < rectHeight; y++) {
0589:                            int xRemaining = rectWidth;
0590:                            int i = eltOffset;
0591:                            while (xRemaining > 8) {
0592:                                data[i++] = (short) (((binaryDataArray[b++] & 0xFF) << 8) | (binaryDataArray[b++] & 0xFF));
0593:                                xRemaining -= 16;
0594:                            }
0595:                            if (xRemaining > 0) {
0596:                                data[i++] = (short) ((binaryDataArray[b++] & 0xFF) << 8);
0597:                            }
0598:                            eltOffset += lineStride;
0599:                        }
0600:                    } else if (dataBuffer instanceof  DataBufferInt) {
0601:                        int[] data = ((DataBufferInt) dataBuffer).getData();
0602:
0603:                        for (int y = 0; y < rectHeight; y++) {
0604:                            int xRemaining = rectWidth;
0605:                            int i = eltOffset;
0606:                            while (xRemaining > 24) {
0607:                                data[i++] = (int) (((binaryDataArray[b++] & 0xFF) << 24)
0608:                                        | ((binaryDataArray[b++] & 0xFF) << 16)
0609:                                        | ((binaryDataArray[b++] & 0xFF) << 8) | (binaryDataArray[b++] & 0xFF));
0610:                                xRemaining -= 32;
0611:                            }
0612:                            int shift = 24;
0613:                            while (xRemaining > 0) {
0614:                                data[i] |= (int) ((binaryDataArray[b++] & 0xFF) << shift);
0615:                                shift -= 8;
0616:                                xRemaining -= 8;
0617:                            }
0618:                            eltOffset += lineStride;
0619:                        }
0620:                    }
0621:                } else { // bitOffset != 0
0622:                    int stride = (rectWidth + 7) / 8;
0623:                    int offset = 0;
0624:                    if (dataBuffer instanceof  DataBufferByte) {
0625:                        byte[] data = ((DataBufferByte) dataBuffer).getData();
0626:
0627:                        if ((bitOffset & 7) == 0) {
0628:                            for (int y = 0; y < rectHeight; y++) {
0629:                                System.arraycopy(binaryDataArray, offset, data,
0630:                                        eltOffset, stride);
0631:                                offset += stride;
0632:                                eltOffset += lineStride;
0633:                            }
0634:                        } else { // bitOffset % 8 != 0
0635:                            int rightShift = bitOffset & 7;
0636:                            int leftShift = 8 - rightShift;
0637:                            int leftShift8 = 8 + leftShift;
0638:                            int mask = (byte) (255 << leftShift);
0639:                            int mask1 = (byte) ~mask;
0640:
0641:                            for (int y = 0; y < rectHeight; y++) {
0642:                                int i = eltOffset;
0643:                                int xRemaining = rectWidth;
0644:                                while (xRemaining > 0) {
0645:                                    byte datum = binaryDataArray[b++];
0646:
0647:                                    if (xRemaining > leftShift8) {
0648:                                        // when all the bits in this BYTE will be set
0649:                                        // into the data buffer.
0650:                                        data[i] = (byte) ((data[i] & mask) | ((datum & 0xFF) >>> rightShift));
0651:                                        data[++i] = (byte) ((datum & 0xFF) << leftShift);
0652:                                    } else if (xRemaining > leftShift) {
0653:                                        // All the "leftShift" high bits will be set
0654:                                        // into the data buffer.  But not all the
0655:                                        // "rightShift" low bits will be set.
0656:                                        data[i] = (byte) ((data[i] & mask) | ((datum & 0xFF) >>> rightShift));
0657:                                        i++;
0658:                                        data[i] = (byte) ((data[i] & mask1) | ((datum & 0xFF) << leftShift));
0659:                                    } else {
0660:                                        // Less than "leftShift" high bits will be set.
0661:                                        int remainMask = (1 << leftShift
0662:                                                - xRemaining) - 1;
0663:                                        data[i] = (byte) ((data[i] & (mask | remainMask)) | (datum & 0xFF) >>> rightShift
0664:                                                & ~remainMask);
0665:                                    }
0666:                                    xRemaining -= 8;
0667:                                }
0668:                                eltOffset += lineStride;
0669:                            }
0670:                        }
0671:                    } else if (dataBuffer instanceof  DataBufferShort
0672:                            || dataBuffer instanceof  DataBufferUShort) {
0673:                        short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0674:                                .getData()
0675:                                : ((DataBufferUShort) dataBuffer).getData();
0676:
0677:                        int rightShift = bitOffset & 7;
0678:                        int leftShift = 8 - rightShift;
0679:                        int leftShift16 = 16 + leftShift;
0680:                        int mask = (short) (~(255 << leftShift));
0681:                        int mask1 = (short) (65535 << leftShift);
0682:                        int mask2 = (short) ~mask1;
0683:
0684:                        for (int y = 0; y < rectHeight; y++) {
0685:                            int bOffset = bitOffset;
0686:                            int xRemaining = rectWidth;
0687:                            for (int x = 0; x < rectWidth; x += 8, bOffset += 8, xRemaining -= 8) {
0688:                                int i = eltOffset + (bOffset >> 4);
0689:                                int mod = bOffset & 15;
0690:                                int datum = binaryDataArray[b++] & 0xFF;
0691:                                if (mod <= 8) {
0692:                                    // This BYTE is set into one SHORT
0693:                                    if (xRemaining < 8) {
0694:                                        // Mask the bits to be set.
0695:                                        datum &= 255 << 8 - xRemaining;
0696:                                    }
0697:                                    data[i] = (short) ((data[i] & mask) | (datum << leftShift));
0698:                                } else if (xRemaining > leftShift16) {
0699:                                    // This BYTE will be set into two SHORTs
0700:                                    data[i] = (short) ((data[i] & mask1) | ((datum >>> rightShift) & 0xFFFF));
0701:                                    data[++i] = (short) ((datum << leftShift) & 0xFFFF);
0702:                                } else if (xRemaining > leftShift) {
0703:                                    // This BYTE will be set into two SHORTs;
0704:                                    // But not all the low bits will be set into SHORT
0705:                                    data[i] = (short) ((data[i] & mask1) | ((datum >>> rightShift) & 0xFFFF));
0706:                                    i++;
0707:                                    data[i] = (short) ((data[i] & mask2) | ((datum << leftShift) & 0xFFFF));
0708:                                } else {
0709:                                    // Only some of the high bits will be set into
0710:                                    // SHORTs
0711:                                    int remainMask = (1 << leftShift
0712:                                            - xRemaining) - 1;
0713:                                    data[i] = (short) ((data[i] & (mask1 | remainMask)) | ((datum >>> rightShift) & 0xFFFF & ~remainMask));
0714:                                }
0715:                            }
0716:                            eltOffset += lineStride;
0717:                        }
0718:                    } else if (dataBuffer instanceof  DataBufferInt) {
0719:                        int[] data = ((DataBufferInt) dataBuffer).getData();
0720:                        int rightShift = bitOffset & 7;
0721:                        int leftShift = 8 - rightShift;
0722:                        int leftShift32 = 32 + leftShift;
0723:                        int mask = 0xFFFFFFFF << leftShift;
0724:                        int mask1 = ~mask;
0725:
0726:                        for (int y = 0; y < rectHeight; y++) {
0727:                            int bOffset = bitOffset;
0728:                            int xRemaining = rectWidth;
0729:                            for (int x = 0; x < rectWidth; x += 8, bOffset += 8, xRemaining -= 8) {
0730:                                int i = eltOffset + (bOffset >> 5);
0731:                                int mod = bOffset & 31;
0732:                                int datum = binaryDataArray[b++] & 0xFF;
0733:                                if (mod <= 24) {
0734:                                    // This BYTE is set into one INT
0735:                                    int shift = 24 - mod;
0736:                                    if (xRemaining < 8) {
0737:                                        // Mask the bits to be set.
0738:                                        datum &= 255 << 8 - xRemaining;
0739:                                    }
0740:                                    data[i] = (data[i] & (~(255 << shift)))
0741:                                            | (datum << shift);
0742:                                } else if (xRemaining > leftShift32) {
0743:                                    // All the bits of this BYTE will be set into two INTs
0744:                                    data[i] = (data[i] & mask)
0745:                                            | (datum >>> rightShift);
0746:                                    data[++i] = datum << leftShift;
0747:                                } else if (xRemaining > leftShift) {
0748:                                    // This BYTE will be set into two INTs;
0749:                                    // But not all the low bits will be set into INT
0750:                                    data[i] = (data[i] & mask)
0751:                                            | (datum >>> rightShift);
0752:                                    i++;
0753:                                    data[i] = (data[i] & mask1)
0754:                                            | (datum << leftShift);
0755:                                } else {
0756:                                    // Only some of the high bits will be set into INT
0757:                                    int remainMask = (1 << leftShift
0758:                                            - xRemaining) - 1;
0759:                                    data[i] = (data[i] & (mask | remainMask))
0760:                                            | (datum >>> rightShift & ~remainMask);
0761:                                }
0762:                            }
0763:                            eltOffset += lineStride;
0764:                        }
0765:                    }
0766:                }
0767:            }
0768:
0769:            /**
0770:             * Copies data into the packed array of the <code>Raster</code>
0771:             * from an array of unpacked data of the form returned by
0772:             * <code>getUnpackedBinaryData()</code>.
0773:             *
0774:             * <p> If the data are binary, then the target bit will be set if
0775:             * and only if the corresponding byte is non-zero.
0776:             *
0777:             * @throws IllegalArgumentException if <code>isBinary()</code> returns
0778:             * <code>false</code> with the <code>SampleModel</code> of the
0779:             * supplied <code>Raster</code> as argument.
0780:             */
0781:            public static void setUnpackedBinaryData(byte[] bdata,
0782:                    WritableRaster raster, Rectangle rect) {
0783:                SampleModel sm = raster.getSampleModel();
0784:                if (!isBinary(sm)) {
0785:                    throw new IllegalArgumentException(I18N
0786:                            .getString("ImageUtil0"));
0787:                }
0788:
0789:                int rectX = rect.x;
0790:                int rectY = rect.y;
0791:                int rectWidth = rect.width;
0792:                int rectHeight = rect.height;
0793:
0794:                DataBuffer dataBuffer = raster.getDataBuffer();
0795:
0796:                int dx = rectX - raster.getSampleModelTranslateX();
0797:                int dy = rectY - raster.getSampleModelTranslateY();
0798:
0799:                MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
0800:                int lineStride = mpp.getScanlineStride();
0801:                int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
0802:                int bitOffset = mpp.getBitOffset(dx);
0803:
0804:                int k = 0;
0805:
0806:                if (dataBuffer instanceof  DataBufferByte) {
0807:                    byte[] data = ((DataBufferByte) dataBuffer).getData();
0808:                    for (int y = 0; y < rectHeight; y++) {
0809:                        int bOffset = eltOffset * 8 + bitOffset;
0810:                        for (int x = 0; x < rectWidth; x++) {
0811:                            if (bdata[k++] != (byte) 0) {
0812:                                data[bOffset / 8] |= (byte) (0x00000001 << (7 - bOffset & 7));
0813:                            }
0814:                            bOffset++;
0815:                        }
0816:                        eltOffset += lineStride;
0817:                    }
0818:                } else if (dataBuffer instanceof  DataBufferShort
0819:                        || dataBuffer instanceof  DataBufferUShort) {
0820:                    short[] data = dataBuffer instanceof  DataBufferShort ? ((DataBufferShort) dataBuffer)
0821:                            .getData()
0822:                            : ((DataBufferUShort) dataBuffer).getData();
0823:                    for (int y = 0; y < rectHeight; y++) {
0824:                        int bOffset = eltOffset * 16 + bitOffset;
0825:                        for (int x = 0; x < rectWidth; x++) {
0826:                            if (bdata[k++] != (byte) 0) {
0827:                                data[bOffset / 16] |= (short) (0x00000001 << (15 - bOffset % 16));
0828:                            }
0829:                            bOffset++;
0830:                        }
0831:                        eltOffset += lineStride;
0832:                    }
0833:                } else if (dataBuffer instanceof  DataBufferInt) {
0834:                    int[] data = ((DataBufferInt) dataBuffer).getData();
0835:                    for (int y = 0; y < rectHeight; y++) {
0836:                        int bOffset = eltOffset * 32 + bitOffset;
0837:                        for (int x = 0; x < rectWidth; x++) {
0838:                            if (bdata[k++] != (byte) 0) {
0839:                                data[bOffset / 32] |= (int) (0x00000001 << (31 - bOffset % 32));
0840:                            }
0841:                            bOffset++;
0842:                        }
0843:                        eltOffset += lineStride;
0844:                    }
0845:                }
0846:            }
0847:
0848:            public static boolean isBinary(SampleModel sm) {
0849:                return sm instanceof  MultiPixelPackedSampleModel
0850:                        && ((MultiPixelPackedSampleModel) sm)
0851:                                .getPixelBitStride() == 1
0852:                        && sm.getNumBands() == 1;
0853:            }
0854:
0855:            public static ColorModel createColorModel(ColorSpace colorSpace,
0856:                    SampleModel sampleModel) {
0857:                ColorModel colorModel = null;
0858:
0859:                if (sampleModel == null) {
0860:                    throw new IllegalArgumentException(I18N
0861:                            .getString("ImageUtil1"));
0862:                }
0863:
0864:                int numBands = sampleModel.getNumBands();
0865:                if (numBands < 1 || numBands > 4) {
0866:                    return null;
0867:                }
0868:
0869:                int dataType = sampleModel.getDataType();
0870:                if (sampleModel instanceof  ComponentSampleModel) {
0871:                    if (dataType < DataBuffer.TYPE_BYTE ||
0872:                    //dataType == DataBuffer.TYPE_SHORT ||
0873:                            dataType > DataBuffer.TYPE_DOUBLE) {
0874:                        return null;
0875:                    }
0876:
0877:                    if (colorSpace == null)
0878:                        colorSpace = numBands <= 2 ? ColorSpace
0879:                                .getInstance(ColorSpace.CS_GRAY) : ColorSpace
0880:                                .getInstance(ColorSpace.CS_sRGB);
0881:
0882:                    boolean useAlpha = (numBands == 2) || (numBands == 4);
0883:                    int transparency = useAlpha ? Transparency.TRANSLUCENT
0884:                            : Transparency.OPAQUE;
0885:
0886:                    boolean premultiplied = false;
0887:
0888:                    int dataTypeSize = DataBuffer.getDataTypeSize(dataType);
0889:                    int[] bits = new int[numBands];
0890:                    for (int i = 0; i < numBands; i++) {
0891:                        bits[i] = dataTypeSize;
0892:                    }
0893:
0894:                    colorModel = new ComponentColorModel(colorSpace, bits,
0895:                            useAlpha, premultiplied, transparency, dataType);
0896:                } else if (sampleModel instanceof  SinglePixelPackedSampleModel) {
0897:                    SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sampleModel;
0898:
0899:                    int[] bitMasks = sppsm.getBitMasks();
0900:                    int rmask = 0;
0901:                    int gmask = 0;
0902:                    int bmask = 0;
0903:                    int amask = 0;
0904:
0905:                    numBands = bitMasks.length;
0906:                    if (numBands <= 2) {
0907:                        rmask = gmask = bmask = bitMasks[0];
0908:                        if (numBands == 2) {
0909:                            amask = bitMasks[1];
0910:                        }
0911:                    } else {
0912:                        rmask = bitMasks[0];
0913:                        gmask = bitMasks[1];
0914:                        bmask = bitMasks[2];
0915:                        if (numBands == 4) {
0916:                            amask = bitMasks[3];
0917:                        }
0918:                    }
0919:
0920:                    int[] sampleSize = sppsm.getSampleSize();
0921:                    int bits = 0;
0922:                    for (int i = 0; i < sampleSize.length; i++) {
0923:                        bits += sampleSize[i];
0924:                    }
0925:
0926:                    if (colorSpace == null)
0927:                        colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
0928:
0929:                    colorModel = new DirectColorModel(colorSpace, bits, rmask,
0930:                            gmask, bmask, amask, false, sampleModel
0931:                                    .getDataType());
0932:                } else if (sampleModel instanceof  MultiPixelPackedSampleModel) {
0933:                    int bits = ((MultiPixelPackedSampleModel) sampleModel)
0934:                            .getPixelBitStride();
0935:                    int size = 1 << bits;
0936:                    byte[] comp = new byte[size];
0937:
0938:                    for (int i = 0; i < size; i++)
0939:                        comp[i] = (byte) (255 * i / (size - 1));
0940:
0941:                    colorModel = new IndexColorModel(bits, size, comp, comp,
0942:                            comp);
0943:                }
0944:
0945:                return colorModel;
0946:            }
0947:
0948:            public static int getElementSize(SampleModel sm) {
0949:                int elementSize = DataBuffer.getDataTypeSize(sm.getDataType());
0950:
0951:                if (sm instanceof  MultiPixelPackedSampleModel) {
0952:                    MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sm;
0953:                    return mppsm.getSampleSize(0) * mppsm.getNumBands();
0954:                } else if (sm instanceof  ComponentSampleModel) {
0955:                    return sm.getNumBands() * elementSize;
0956:                } else if (sm instanceof  SinglePixelPackedSampleModel) {
0957:                    return elementSize;
0958:                }
0959:
0960:                return elementSize * sm.getNumBands();
0961:
0962:            }
0963:
0964:            public static long getTileSize(SampleModel sm) {
0965:                int elementSize = DataBuffer.getDataTypeSize(sm.getDataType());
0966:
0967:                if (sm instanceof  MultiPixelPackedSampleModel) {
0968:                    MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sm;
0969:                    return (mppsm.getScanlineStride() * mppsm.getHeight() + (mppsm
0970:                            .getDataBitOffset()
0971:                            + elementSize - 1)
0972:                            / elementSize)
0973:                            * ((elementSize + 7) / 8);
0974:                } else if (sm instanceof  ComponentSampleModel) {
0975:                    ComponentSampleModel csm = (ComponentSampleModel) sm;
0976:                    int[] bandOffsets = csm.getBandOffsets();
0977:                    int maxBandOff = bandOffsets[0];
0978:                    for (int i = 1; i < bandOffsets.length; i++)
0979:                        maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
0980:
0981:                    long size = 0;
0982:                    int pixelStride = csm.getPixelStride();
0983:                    int scanlineStride = csm.getScanlineStride();
0984:                    if (maxBandOff >= 0)
0985:                        size += maxBandOff + 1;
0986:                    if (pixelStride > 0)
0987:                        size += pixelStride * (sm.getWidth() - 1);
0988:                    if (scanlineStride > 0)
0989:                        size += scanlineStride * (sm.getHeight() - 1);
0990:
0991:                    int[] bankIndices = csm.getBankIndices();
0992:                    maxBandOff = bankIndices[0];
0993:                    for (int i = 1; i < bankIndices.length; i++)
0994:                        maxBandOff = Math.max(maxBandOff, bankIndices[i]);
0995:                    return size * (maxBandOff + 1) * ((elementSize + 7) / 8);
0996:                } else if (sm instanceof  SinglePixelPackedSampleModel) {
0997:                    SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
0998:                    long size = sppsm.getScanlineStride()
0999:                            * (sppsm.getHeight() - 1) + sppsm.getWidth();
1000:                    return size * ((elementSize + 7) / 8);
1001:                }
1002:
1003:                return 0;
1004:            }
1005:
1006:            public static long getBandSize(SampleModel sm) {
1007:                int elementSize = DataBuffer.getDataTypeSize(sm.getDataType());
1008:
1009:                if (sm instanceof  ComponentSampleModel) {
1010:                    ComponentSampleModel csm = (ComponentSampleModel) sm;
1011:                    int pixelStride = csm.getPixelStride();
1012:                    int scanlineStride = csm.getScanlineStride();
1013:                    long size = Math.min(pixelStride, scanlineStride);
1014:
1015:                    if (pixelStride > 0)
1016:                        size += pixelStride * (sm.getWidth() - 1);
1017:                    if (scanlineStride > 0)
1018:                        size += scanlineStride * (sm.getHeight() - 1);
1019:                    return size * ((elementSize + 7) / 8);
1020:                } else
1021:                    return getTileSize(sm);
1022:            }
1023:
1024:            /**
1025:             * Tests whether the color indices represent a gray-scale image with
1026:             * the indicated number of bits over the color component range [0,255].
1027:             * The grayscale mapping may be inverted, i.e., 0 -> 255 and
1028:             * mapSize -> 0.
1029:             *
1030:             * @param icm The gray-to-color mapping.
1031:             * @return Whether the <code>IndexColorModel</code> maps index
1032:             *         <code>i</code> to <code>((255*i)/icm.getMapSize()-1)</code>.
1033:             * @throws IllegalArgumentException if <code>icm</code> is
1034:             *         <code>null</code>.
1035:             */
1036:            public static boolean isGrayscaleMapping(IndexColorModel icm) {
1037:                if (icm == null) {
1038:                    throw new IllegalArgumentException("icm == null!");
1039:                }
1040:
1041:                // Get colormap size and contents.
1042:                int mapSize = icm.getMapSize();
1043:
1044:                byte[] r = new byte[mapSize];
1045:                byte[] g = new byte[mapSize];
1046:                byte[] b = new byte[mapSize];
1047:
1048:                icm.getReds(r);
1049:                icm.getGreens(g);
1050:                icm.getBlues(b);
1051:
1052:                boolean isGrayToColor = true;
1053:
1054:                // Check ascending ramp.
1055:                for (int i = 0; i < mapSize; i++) {
1056:                    byte temp = (byte) (i * 255 / (mapSize - 1));
1057:
1058:                    if (r[i] != temp || g[i] != temp || b[i] != temp) {
1059:                        isGrayToColor = false;
1060:                        break;
1061:                    }
1062:                }
1063:
1064:                if (!isGrayToColor) {
1065:                    isGrayToColor = true;
1066:
1067:                    // Check descending ramp.
1068:                    for (int i = 0, j = mapSize - 1; i < mapSize; i++, j--) {
1069:                        byte temp = (byte) (j * 255 / (mapSize - 1));
1070:
1071:                        if (r[i] != temp || g[i] != temp || b[i] != temp) {
1072:                            isGrayToColor = false;
1073:                            break;
1074:                        }
1075:                    }
1076:                }
1077:
1078:                return isGrayToColor;
1079:            }
1080:
1081:            /**
1082:             * Tests whether the color indices represent a gray-scale image.
1083:             *
1084:             * @param r The red channel color indices.
1085:             * @param g The green channel color indices.
1086:             * @param b The blue channel color indices.
1087:             * @return If all the indices have 256 entries, and are identical mappings,
1088:             *         return <code>true</code>; otherwise, return <code>false</code>.
1089:             */
1090:            public static boolean isIndicesForGrayscale(byte[] r, byte[] g,
1091:                    byte[] b) {
1092:                if (r.length != g.length || r.length != b.length)
1093:                    return false;
1094:
1095:                int size = r.length;
1096:
1097:                if (size != 256)
1098:                    return false;
1099:
1100:                for (int i = 0; i < size; i++) {
1101:                    byte temp = (byte) i;
1102:
1103:                    if (r[i] != temp || g[i] != temp || b[i] != temp)
1104:                        return false;
1105:                }
1106:
1107:                return true;
1108:            }
1109:
1110:            /** Converts the provided object to <code>String</code> */
1111:            public static String convertObjectToString(Object obj) {
1112:                if (obj == null)
1113:                    return "";
1114:
1115:                String s = "";
1116:                if (obj instanceof  byte[]) {
1117:                    byte[] bArray = (byte[]) obj;
1118:                    for (int i = 0; i < bArray.length; i++)
1119:                        s += bArray[i] + " ";
1120:                    return s;
1121:                }
1122:
1123:                if (obj instanceof  int[]) {
1124:                    int[] iArray = (int[]) obj;
1125:                    for (int i = 0; i < iArray.length; i++)
1126:                        s += iArray[i] + " ";
1127:                    return s;
1128:                }
1129:
1130:                if (obj instanceof  short[]) {
1131:                    short[] sArray = (short[]) obj;
1132:                    for (int i = 0; i < sArray.length; i++)
1133:                        s += sArray[i] + " ";
1134:                    return s;
1135:                }
1136:
1137:                return obj.toString();
1138:
1139:            }
1140:
1141:            /** Checks that the provided <code>ImageWriter</code> can encode
1142:             * the provided <code>ImageTypeSpecifier</code> or not.  If not, an
1143:             * <code>IIOException</code> will be thrown.
1144:             * @param writer The provided <code>ImageWriter</code>.
1145:             * @param type The image to be tested.
1146:             * @throws IIOException If the writer cannot encoded the provided image.
1147:             */
1148:            public static final void canEncodeImage(ImageWriter writer,
1149:                    ImageTypeSpecifier type) throws IIOException {
1150:                ImageWriterSpi spi = writer.getOriginatingProvider();
1151:
1152:                if (type != null && spi != null && !spi.canEncodeImage(type)) {
1153:                    throw new IIOException(I18N.getString("ImageUtil2") + " "
1154:                            + writer.getClass().getName());
1155:                }
1156:            }
1157:
1158:            /** Checks that the provided <code>ImageWriter</code> can encode
1159:             * the provided <code>ColorModel</code> and <code>SampleModel</code>.
1160:             * If not, an <code>IIOException</code> will be thrown.
1161:             * @param writer The provided <code>ImageWriter</code>.
1162:             * @param colorModel The provided <code>ColorModel</code>.
1163:             * @param sampleModel The provided <code>SampleModel</code>.
1164:             * @throws IIOException If the writer cannot encoded the provided image.
1165:             */
1166:            public static final void canEncodeImage(ImageWriter writer,
1167:                    ColorModel colorModel, SampleModel sampleModel)
1168:                    throws IIOException {
1169:                ImageTypeSpecifier type = null;
1170:                if (colorModel != null && sampleModel != null)
1171:                    type = new ImageTypeSpecifier(colorModel, sampleModel);
1172:                canEncodeImage(writer, type);
1173:            }
1174:
1175:            /**
1176:             * Returns whether the image has contiguous data across rows.
1177:             */
1178:            public static final boolean imageIsContiguous(RenderedImage image) {
1179:                SampleModel sm;
1180:                if (image instanceof  BufferedImage) {
1181:                    WritableRaster ras = ((BufferedImage) image).getRaster();
1182:                    sm = ras.getSampleModel();
1183:                } else {
1184:                    sm = image.getSampleModel();
1185:                }
1186:
1187:                if (sm instanceof  ComponentSampleModel) {
1188:                    // Ensure image rows samples are stored contiguously
1189:                    // in a single bank.
1190:                    ComponentSampleModel csm = (ComponentSampleModel) sm;
1191:
1192:                    if (csm.getPixelStride() != csm.getNumBands()) {
1193:                        return false;
1194:                    }
1195:
1196:                    int[] bandOffsets = csm.getBandOffsets();
1197:                    for (int i = 0; i < bandOffsets.length; i++) {
1198:                        if (bandOffsets[i] != i) {
1199:                            return false;
1200:                        }
1201:                    }
1202:
1203:                    int[] bankIndices = csm.getBankIndices();
1204:                    for (int i = 0; i < bandOffsets.length; i++) {
1205:                        if (bankIndices[i] != 0) {
1206:                            return false;
1207:                        }
1208:                    }
1209:
1210:                    return true;
1211:                }
1212:
1213:                // Otherwise true if and only if it's a bilevel image with
1214:                // a MultiPixelPackedSampleModel, 1 bit per pixel, and 1 bit
1215:                // pixel stride.
1216:                return ImageUtil.isBinary(sm);
1217:            }
1218:
1219:            /**
1220:             * Gets the destination image type.
1221:             */
1222:            // NOTE: Code shamelessly copied from ImageReader.getDestination().
1223:            public static final ImageTypeSpecifier getDestinationType(
1224:                    ImageReadParam param, Iterator imageTypes)
1225:                    throws IIOException {
1226:
1227:                if (imageTypes == null || !imageTypes.hasNext()) {
1228:                    throw new IllegalArgumentException(
1229:                            "imageTypes null or empty!");
1230:                }
1231:
1232:                ImageTypeSpecifier imageType = null;
1233:
1234:                // If param is non-null, use it
1235:                if (param != null) {
1236:                    imageType = param.getDestinationType();
1237:                }
1238:
1239:                // No info from param, use fallback image type
1240:                if (imageType == null) {
1241:                    Object o = imageTypes.next();
1242:                    if (!(o instanceof  ImageTypeSpecifier)) {
1243:                        throw new IllegalArgumentException(
1244:                                "Non-ImageTypeSpecifier retrieved from imageTypes!");
1245:                    }
1246:                    imageType = (ImageTypeSpecifier) o;
1247:                } else {
1248:                    boolean foundIt = false;
1249:                    while (imageTypes.hasNext()) {
1250:                        ImageTypeSpecifier type = (ImageTypeSpecifier) imageTypes
1251:                                .next();
1252:                        if (type.equals(imageType)) {
1253:                            foundIt = true;
1254:                            break;
1255:                        }
1256:                    }
1257:
1258:                    if (!foundIt) {
1259:                        throw new IIOException(
1260:                                "Destination type from ImageReadParam does not match!");
1261:                    }
1262:                }
1263:
1264:                return imageType;
1265:            }
1266:
1267:            /**
1268:             * Returns <code>true</code> if the given <code>ColorSpace</code> object
1269:             * is an instance of <code>ICC_ColorSpace</code> but is not one of the
1270:             * standard <code>ColorSpace</code>s returned by
1271:             * <code>ColorSpace.getInstance()</code>.
1272:             *
1273:             * @param cs The <code>ColorSpace</code> to test.
1274:             */
1275:            public static boolean isNonStandardICCColorSpace(ColorSpace cs) {
1276:                boolean retval = false;
1277:
1278:                try {
1279:                    // Check the standard ColorSpaces in decreasing order of
1280:                    // likelihood except check CS_PYCC last as in some JREs
1281:                    // PYCC.pf used not to be installed.
1282:                    retval = (cs instanceof  ICC_ColorSpace)
1283:                            && !(cs.isCS_sRGB()
1284:                                    || cs
1285:                                            .equals(ColorSpace
1286:                                                    .getInstance(ColorSpace.CS_LINEAR_RGB))
1287:                                    || cs.equals(ColorSpace
1288:                                            .getInstance(ColorSpace.CS_GRAY))
1289:                                    || cs.equals(ColorSpace
1290:                                            .getInstance(ColorSpace.CS_CIEXYZ)) || cs
1291:                                    .equals(ColorSpace
1292:                                            .getInstance(ColorSpace.CS_PYCC)));
1293:                } catch (IllegalArgumentException e) {
1294:                    // PYCC.pf not installed: ignore it - 'retval' is still 'false'.
1295:                }
1296:
1297:                return retval;
1298:            }
1299:
1300:            // Method to return JDK core ImageReaderSPI/ImageWriterSPI for a 
1301:            // given formatName.
1302:            public static List getJDKImageReaderWriterSPI(
1303:                    ServiceRegistry registry, String formatName,
1304:                    boolean isReader) {
1305:
1306:                IIORegistry iioRegistry = (IIORegistry) registry;
1307:
1308:                Class spiClass;
1309:                String descPart;
1310:                if (isReader) {
1311:                    spiClass = ImageReaderSpi.class;
1312:                    descPart = " image reader";
1313:                } else {
1314:                    spiClass = ImageWriterSpi.class;
1315:                    descPart = " image writer";
1316:                }
1317:
1318:                Iterator iter = iioRegistry.getServiceProviders(spiClass, true); // useOrdering
1319:
1320:                String formatNames[];
1321:                ImageReaderWriterSpi provider;
1322:                String desc = "standard " + formatName + descPart;
1323:                String jiioPath = "com.sun.media.imageioimpl";
1324:                Locale locale = Locale.getDefault();
1325:                ArrayList list = new ArrayList();
1326:                while (iter.hasNext()) {
1327:                    provider = (ImageReaderWriterSpi) iter.next();
1328:
1329:                    // Look for JDK core ImageWriterSpi's
1330:                    if (provider.getVendorName().startsWith("Sun Microsystems")
1331:                            && desc.equalsIgnoreCase(provider
1332:                                    .getDescription(locale)) &&
1333:                            // not JAI Image I/O plugins
1334:                            !provider.getPluginClassName().startsWith(jiioPath)) {
1335:
1336:                        // Get the formatNames supported by this Spi
1337:                        formatNames = provider.getFormatNames();
1338:                        for (int i = 0; i < formatNames.length; i++) {
1339:                            if (formatNames[i].equalsIgnoreCase(formatName)) {
1340:                                // Must be a JDK provided ImageReader/ImageWriter
1341:                                list.add(provider);
1342:                                break;
1343:                            }
1344:                        }
1345:                    }
1346:                }
1347:
1348:                return list;
1349:            }
1350:
1351:            public static void processOnRegistration(ServiceRegistry registry,
1352:                    Class category, String formatName,
1353:                    ImageReaderWriterSpi spi, int deregisterJvmVersion,
1354:                    int priorityJvmVersion) {
1355:
1356:                // Check which JVM we are running on
1357:                String jvmVendor = System.getProperty("java.vendor");
1358:                String jvmVersionString = System
1359:                        .getProperty("java.specification.version");
1360:                int verIndex = jvmVersionString.indexOf("1.");
1361:                // Skip the "1." part to get to the part of the version number that
1362:                // actually changes from version to version
1363:                // The assumption here is that "java.specification.version" is 
1364:                // always of the format "x.y" and not "x.y.z" since that is what has
1365:                // been practically observed in all JDKs to-date, an examination of
1366:                // the code returning this property bears this out. However this does
1367:                // not guarantee that the format won't change in the future, 
1368:                // though that seems unlikely.
1369:                jvmVersionString = jvmVersionString.substring(verIndex + 2);
1370:
1371:                int jvmVersion = Integer.parseInt(jvmVersionString);
1372:
1373:                if (jvmVendor.equals("Sun Microsystems Inc.")) {
1374:
1375:                    List list;
1376:                    if (spi instanceof  ImageReaderSpi)
1377:                        list = getJDKImageReaderWriterSPI(registry, formatName,
1378:                                true);
1379:                    else
1380:                        list = getJDKImageReaderWriterSPI(registry, formatName,
1381:                                false);
1382:
1383:                    if (jvmVersion >= deregisterJvmVersion && list.size() != 0) {
1384:                        // De-register JIIO's plug-in
1385:                        registry.deregisterServiceProvider(spi, category);
1386:                    } else {
1387:                        for (int i = 0; i < list.size(); i++) {
1388:                            if (jvmVersion >= priorityJvmVersion) {
1389:                                // Set JIIO plug-in to lower priority
1390:                                registry
1391:                                        .setOrdering(category, list.get(i), spi);
1392:                            } else {
1393:                                // Set JIIO plug-in to higher priority
1394:                                registry
1395:                                        .setOrdering(category, spi, list.get(i));
1396:                            }
1397:                        }
1398:                    }
1399:                }
1400:            }
1401:
1402:            public static int readMultiByteInteger(ImageInputStream iis)
1403:                    throws IOException {
1404:                int value = iis.readByte();
1405:                int result = value & 0x7f;
1406:                while ((value & 0x80) == 0x80) {
1407:                    result <<= 7;
1408:                    value = iis.readByte();
1409:                    result |= (value & 0x7f);
1410:                }
1411:                return result;
1412:            }
1413:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.