Source Code Cross Referenced for BmpImage.java in  » PDF » pdf-itext » com » lowagie » text » pdf » codec » 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 » PDF » pdf itext » com.lowagie.text.pdf.codec 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003 by Paulo Soares.
0003:         *
0004:         * The contents of this file are subject to the Mozilla Public License Version 1.1
0005:         * (the "License"); you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0007:         *
0008:         * Software distributed under the License is distributed on an "AS IS" basis,
0009:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0010:         * for the specific language governing rights and limitations under the License.
0011:         *
0012:         * The Original Code is 'iText, a free JAVA-PDF library'.
0013:         *
0014:         * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
0015:         * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
0016:         * All Rights Reserved.
0017:         * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
0018:         * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
0019:         *
0020:         * Contributor(s): all the names of the contributors are added in the source code
0021:         * where applicable.
0022:         *
0023:         * Alternatively, the contents of this file may be used under the terms of the
0024:         * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
0025:         * provisions of LGPL are applicable instead of those above.  If you wish to
0026:         * allow use of your version of this file only under the terms of the LGPL
0027:         * License and not to allow others to use your version of this file under
0028:         * the MPL, indicate your decision by deleting the provisions above and
0029:         * replace them with the notice and other provisions required by the LGPL.
0030:         * If you do not delete the provisions above, a recipient may use your version
0031:         * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
0032:         *
0033:         * This library is free software; you can redistribute it and/or modify it
0034:         * under the terms of the MPL as stated above or under the terms of the GNU
0035:         * Library General Public License as published by the Free Software Foundation;
0036:         * either version 2 of the License, or any later version.
0037:         *
0038:         * This library is distributed in the hope that it will be useful, but WITHOUT
0039:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0040:         * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
0041:         * details.
0042:         *
0043:         * If you didn't download this code from the following link, you should check if
0044:         * you aren't using an obsolete version:
0045:         * http://www.lowagie.com/iText/
0046:         *
0047:         *
0048:         * The original JAI codecs have the following license
0049:         *
0050:         * Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved.
0051:         *
0052:         * Redistribution and use in source and binary forms, with or without
0053:         * modification, are permitted provided that the following conditions are met:
0054:         *
0055:         * -Redistributions of source code must retain the above copyright notice, this
0056:         * list of conditions and the following disclaimer.
0057:         *
0058:         * -Redistribution in binary form must reproduct the above copyright notice,
0059:         * this list of conditions and the following disclaimer in the documentation
0060:         * and/or other materials provided with the distribution.
0061:         *
0062:         * Neither the name of Sun Microsystems, Inc. or the names of contributors may
0063:         * be used to endorse or promote products derived from this software without
0064:         * specific prior written permission.
0065:         *
0066:         * This software is provided "AS IS," without a warranty of any kind. ALL
0067:         * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
0068:         * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
0069:         * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
0070:         * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
0071:         * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
0072:         * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
0073:         * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
0074:         * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
0075:         * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
0076:         * POSSIBILITY OF SUCH DAMAGES.
0077:         *
0078:         * You acknowledge that Software is not designed,licensed or intended for use in
0079:         * the design, construction, operation or maintenance of any nuclear facility.
0080:         */
0081:        package com.lowagie.text.pdf.codec;
0082:
0083:        import java.io.BufferedInputStream;
0084:        import java.io.ByteArrayInputStream;
0085:        import java.io.IOException;
0086:        import java.io.InputStream;
0087:        import java.net.URL;
0088:        import java.util.HashMap;
0089:
0090:        import com.lowagie.text.BadElementException;
0091:        import com.lowagie.text.ExceptionConverter;
0092:        import com.lowagie.text.Image;
0093:        import com.lowagie.text.ImgRaw;
0094:        import com.lowagie.text.Utilities;
0095:        import com.lowagie.text.pdf.PdfArray;
0096:        import com.lowagie.text.pdf.PdfDictionary;
0097:        import com.lowagie.text.pdf.PdfName;
0098:        import com.lowagie.text.pdf.PdfNumber;
0099:        import com.lowagie.text.pdf.PdfString;
0100:
0101:        /** Reads a BMP image. All types of BMP can be read.
0102:         * <p>
0103:         * It is based in the JAI codec.
0104:         *
0105:         * @author  Paulo Soares (psoares@consiste.pt)
0106:         */
0107:        public class BmpImage {
0108:
0109:            // BMP variables
0110:            private InputStream inputStream;
0111:            private long bitmapFileSize;
0112:            private long bitmapOffset;
0113:            private long compression;
0114:            private long imageSize;
0115:            private byte palette[];
0116:            private int imageType;
0117:            private int numBands;
0118:            private boolean isBottomUp;
0119:            private int bitsPerPixel;
0120:            private int redMask, greenMask, blueMask, alphaMask;
0121:            public HashMap properties = new HashMap();
0122:            private long xPelsPerMeter;
0123:            private long yPelsPerMeter;
0124:            // BMP Image types
0125:            private static final int VERSION_2_1_BIT = 0;
0126:            private static final int VERSION_2_4_BIT = 1;
0127:            private static final int VERSION_2_8_BIT = 2;
0128:            private static final int VERSION_2_24_BIT = 3;
0129:
0130:            private static final int VERSION_3_1_BIT = 4;
0131:            private static final int VERSION_3_4_BIT = 5;
0132:            private static final int VERSION_3_8_BIT = 6;
0133:            private static final int VERSION_3_24_BIT = 7;
0134:
0135:            private static final int VERSION_3_NT_16_BIT = 8;
0136:            private static final int VERSION_3_NT_32_BIT = 9;
0137:
0138:            private static final int VERSION_4_1_BIT = 10;
0139:            private static final int VERSION_4_4_BIT = 11;
0140:            private static final int VERSION_4_8_BIT = 12;
0141:            private static final int VERSION_4_16_BIT = 13;
0142:            private static final int VERSION_4_24_BIT = 14;
0143:            private static final int VERSION_4_32_BIT = 15;
0144:
0145:            // Color space types
0146:            private static final int LCS_CALIBRATED_RGB = 0;
0147:            private static final int LCS_sRGB = 1;
0148:            private static final int LCS_CMYK = 2;
0149:
0150:            // Compression Types
0151:            private static final int BI_RGB = 0;
0152:            private static final int BI_RLE8 = 1;
0153:            private static final int BI_RLE4 = 2;
0154:            private static final int BI_BITFIELDS = 3;
0155:
0156:            int width;
0157:            int height;
0158:
0159:            BmpImage(InputStream is, boolean noHeader, int size)
0160:                    throws IOException {
0161:                bitmapFileSize = size;
0162:                bitmapOffset = 0;
0163:                process(is, noHeader);
0164:            }
0165:
0166:            /** Reads a BMP from an url.
0167:             * @param url the url
0168:             * @throws IOException on error
0169:             * @return the image
0170:             */
0171:            public static Image getImage(URL url) throws IOException {
0172:                InputStream is = null;
0173:                try {
0174:                    is = url.openStream();
0175:                    Image img = getImage(is);
0176:                    img.setUrl(url);
0177:                    return img;
0178:                } finally {
0179:                    if (is != null) {
0180:                        is.close();
0181:                    }
0182:                }
0183:            }
0184:
0185:            /** Reads a BMP from a stream. The stream is not closed.
0186:             * @param is the stream
0187:             * @throws IOException on error
0188:             * @return the image
0189:             */
0190:            public static Image getImage(InputStream is) throws IOException {
0191:                return getImage(is, false, 0);
0192:            }
0193:
0194:            /** Reads a BMP from a stream. The stream is not closed.
0195:             * The BMP may not have a header and be considered as a plain DIB.
0196:             * @param is the stream
0197:             * @param noHeader true to process a plain DIB
0198:             * @param size the size of the DIB. Not used for a BMP
0199:             * @throws IOException on error
0200:             * @return the image
0201:             */
0202:            public static Image getImage(InputStream is, boolean noHeader,
0203:                    int size) throws IOException {
0204:                BmpImage bmp = new BmpImage(is, noHeader, size);
0205:                try {
0206:                    Image img = bmp.getImage();
0207:                    img.setDpi(
0208:                            (int) ((double) bmp.xPelsPerMeter * 0.0254 + 0.5),
0209:                            (int) ((double) bmp.yPelsPerMeter * 0.0254 + 0.5));
0210:                    img.setOriginalType(Image.ORIGINAL_BMP);
0211:                    return img;
0212:                } catch (BadElementException be) {
0213:                    throw new ExceptionConverter(be);
0214:                }
0215:            }
0216:
0217:            /** Reads a BMP from a file.
0218:             * @param file the file
0219:             * @throws IOException on error
0220:             * @return the image
0221:             */
0222:            public static Image getImage(String file) throws IOException {
0223:                return getImage(Utilities.toURL(file));
0224:            }
0225:
0226:            /** Reads a BMP from a byte array.
0227:             * @param data the byte array
0228:             * @throws IOException on error
0229:             * @return the image
0230:             */
0231:            public static Image getImage(byte data[]) throws IOException {
0232:                ByteArrayInputStream is = new ByteArrayInputStream(data);
0233:                Image img = getImage(is);
0234:                img.setOriginalData(data);
0235:                return img;
0236:            }
0237:
0238:            protected void process(InputStream stream, boolean noHeader)
0239:                    throws IOException {
0240:                if (noHeader || stream instanceof  BufferedInputStream) {
0241:                    inputStream = stream;
0242:                } else {
0243:                    inputStream = new BufferedInputStream(stream);
0244:                }
0245:                if (!noHeader) {
0246:                    // Start File Header
0247:                    if (!(readUnsignedByte(inputStream) == 'B' && readUnsignedByte(inputStream) == 'M')) {
0248:                        throw new RuntimeException(
0249:                                "Invalid magic value for BMP file.");
0250:                    }
0251:
0252:                    // Read file size
0253:                    bitmapFileSize = readDWord(inputStream);
0254:
0255:                    // Read the two reserved fields
0256:                    readWord(inputStream);
0257:                    readWord(inputStream);
0258:
0259:                    // Offset to the bitmap from the beginning
0260:                    bitmapOffset = readDWord(inputStream);
0261:
0262:                    // End File Header
0263:                }
0264:                // Start BitmapCoreHeader
0265:                long size = readDWord(inputStream);
0266:
0267:                if (size == 12) {
0268:                    width = readWord(inputStream);
0269:                    height = readWord(inputStream);
0270:                } else {
0271:                    width = readLong(inputStream);
0272:                    height = readLong(inputStream);
0273:                }
0274:
0275:                int planes = readWord(inputStream);
0276:                bitsPerPixel = readWord(inputStream);
0277:
0278:                properties.put("color_planes", new Integer(planes));
0279:                properties.put("bits_per_pixel", new Integer(bitsPerPixel));
0280:
0281:                // As BMP always has 3 rgb bands, except for Version 5,
0282:                // which is bgra
0283:                numBands = 3;
0284:                if (bitmapOffset == 0)
0285:                    bitmapOffset = size;
0286:                if (size == 12) {
0287:                    // Windows 2.x and OS/2 1.x
0288:                    properties.put("bmp_version", "BMP v. 2.x");
0289:
0290:                    // Classify the image type
0291:                    if (bitsPerPixel == 1) {
0292:                        imageType = VERSION_2_1_BIT;
0293:                    } else if (bitsPerPixel == 4) {
0294:                        imageType = VERSION_2_4_BIT;
0295:                    } else if (bitsPerPixel == 8) {
0296:                        imageType = VERSION_2_8_BIT;
0297:                    } else if (bitsPerPixel == 24) {
0298:                        imageType = VERSION_2_24_BIT;
0299:                    }
0300:
0301:                    // Read in the palette
0302:                    int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 3);
0303:                    int sizeOfPalette = numberOfEntries * 3;
0304:                    if (bitmapOffset == size) {
0305:                        switch (imageType) {
0306:                        case VERSION_2_1_BIT:
0307:                            sizeOfPalette = 2 * 3;
0308:                            break;
0309:                        case VERSION_2_4_BIT:
0310:                            sizeOfPalette = 16 * 3;
0311:                            break;
0312:                        case VERSION_2_8_BIT:
0313:                            sizeOfPalette = 256 * 3;
0314:                            break;
0315:                        case VERSION_2_24_BIT:
0316:                            sizeOfPalette = 0;
0317:                            break;
0318:                        }
0319:                        bitmapOffset = size + sizeOfPalette;
0320:                    }
0321:                    readPalette(sizeOfPalette);
0322:                } else {
0323:
0324:                    compression = readDWord(inputStream);
0325:                    imageSize = readDWord(inputStream);
0326:                    xPelsPerMeter = readLong(inputStream);
0327:                    yPelsPerMeter = readLong(inputStream);
0328:                    long colorsUsed = readDWord(inputStream);
0329:                    long colorsImportant = readDWord(inputStream);
0330:
0331:                    switch ((int) compression) {
0332:                    case BI_RGB:
0333:                        properties.put("compression", "BI_RGB");
0334:                        break;
0335:
0336:                    case BI_RLE8:
0337:                        properties.put("compression", "BI_RLE8");
0338:                        break;
0339:
0340:                    case BI_RLE4:
0341:                        properties.put("compression", "BI_RLE4");
0342:                        break;
0343:
0344:                    case BI_BITFIELDS:
0345:                        properties.put("compression", "BI_BITFIELDS");
0346:                        break;
0347:                    }
0348:
0349:                    properties.put("x_pixels_per_meter",
0350:                            new Long(xPelsPerMeter));
0351:                    properties.put("y_pixels_per_meter",
0352:                            new Long(yPelsPerMeter));
0353:                    properties.put("colors_used", new Long(colorsUsed));
0354:                    properties.put("colors_important",
0355:                            new Long(colorsImportant));
0356:
0357:                    if (size == 40) {
0358:                        // Windows 3.x and Windows NT
0359:                        switch ((int) compression) {
0360:
0361:                        case BI_RGB: // No compression
0362:                        case BI_RLE8: // 8-bit RLE compression
0363:                        case BI_RLE4: // 4-bit RLE compression
0364:
0365:                            if (bitsPerPixel == 1) {
0366:                                imageType = VERSION_3_1_BIT;
0367:                            } else if (bitsPerPixel == 4) {
0368:                                imageType = VERSION_3_4_BIT;
0369:                            } else if (bitsPerPixel == 8) {
0370:                                imageType = VERSION_3_8_BIT;
0371:                            } else if (bitsPerPixel == 24) {
0372:                                imageType = VERSION_3_24_BIT;
0373:                            } else if (bitsPerPixel == 16) {
0374:                                imageType = VERSION_3_NT_16_BIT;
0375:                                redMask = 0x7C00;
0376:                                greenMask = 0x3E0;
0377:                                blueMask = 0x1F;
0378:                                properties
0379:                                        .put("red_mask", new Integer(redMask));
0380:                                properties.put("green_mask", new Integer(
0381:                                        greenMask));
0382:                                properties.put("blue_mask", new Integer(
0383:                                        blueMask));
0384:                            } else if (bitsPerPixel == 32) {
0385:                                imageType = VERSION_3_NT_32_BIT;
0386:                                redMask = 0x00FF0000;
0387:                                greenMask = 0x0000FF00;
0388:                                blueMask = 0x000000FF;
0389:                                properties
0390:                                        .put("red_mask", new Integer(redMask));
0391:                                properties.put("green_mask", new Integer(
0392:                                        greenMask));
0393:                                properties.put("blue_mask", new Integer(
0394:                                        blueMask));
0395:                            }
0396:
0397:                            // Read in the palette
0398:                            int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
0399:                            int sizeOfPalette = numberOfEntries * 4;
0400:                            if (bitmapOffset == size) {
0401:                                switch (imageType) {
0402:                                case VERSION_3_1_BIT:
0403:                                    sizeOfPalette = (int) (colorsUsed == 0 ? 2
0404:                                            : colorsUsed) * 4;
0405:                                    break;
0406:                                case VERSION_3_4_BIT:
0407:                                    sizeOfPalette = (int) (colorsUsed == 0 ? 16
0408:                                            : colorsUsed) * 4;
0409:                                    break;
0410:                                case VERSION_3_8_BIT:
0411:                                    sizeOfPalette = (int) (colorsUsed == 0 ? 256
0412:                                            : colorsUsed) * 4;
0413:                                    break;
0414:                                default:
0415:                                    sizeOfPalette = 0;
0416:                                    break;
0417:                                }
0418:                                bitmapOffset = size + sizeOfPalette;
0419:                            }
0420:                            readPalette(sizeOfPalette);
0421:
0422:                            properties.put("bmp_version", "BMP v. 3.x");
0423:                            break;
0424:
0425:                        case BI_BITFIELDS:
0426:
0427:                            if (bitsPerPixel == 16) {
0428:                                imageType = VERSION_3_NT_16_BIT;
0429:                            } else if (bitsPerPixel == 32) {
0430:                                imageType = VERSION_3_NT_32_BIT;
0431:                            }
0432:
0433:                            // BitsField encoding
0434:                            redMask = (int) readDWord(inputStream);
0435:                            greenMask = (int) readDWord(inputStream);
0436:                            blueMask = (int) readDWord(inputStream);
0437:
0438:                            properties.put("red_mask", new Integer(redMask));
0439:                            properties
0440:                                    .put("green_mask", new Integer(greenMask));
0441:                            properties.put("blue_mask", new Integer(blueMask));
0442:
0443:                            if (colorsUsed != 0) {
0444:                                // there is a palette
0445:                                sizeOfPalette = (int) colorsUsed * 4;
0446:                                readPalette(sizeOfPalette);
0447:                            }
0448:
0449:                            properties.put("bmp_version", "BMP v. 3.x NT");
0450:                            break;
0451:
0452:                        default:
0453:                            throw new RuntimeException(
0454:                                    "Invalid compression specified in BMP file.");
0455:                        }
0456:                    } else if (size == 108) {
0457:                        // Windows 4.x BMP
0458:
0459:                        properties.put("bmp_version", "BMP v. 4.x");
0460:
0461:                        // rgb masks, valid only if comp is BI_BITFIELDS
0462:                        redMask = (int) readDWord(inputStream);
0463:                        greenMask = (int) readDWord(inputStream);
0464:                        blueMask = (int) readDWord(inputStream);
0465:                        // Only supported for 32bpp BI_RGB argb
0466:                        alphaMask = (int) readDWord(inputStream);
0467:                        long csType = readDWord(inputStream);
0468:                        int redX = readLong(inputStream);
0469:                        int redY = readLong(inputStream);
0470:                        int redZ = readLong(inputStream);
0471:                        int greenX = readLong(inputStream);
0472:                        int greenY = readLong(inputStream);
0473:                        int greenZ = readLong(inputStream);
0474:                        int blueX = readLong(inputStream);
0475:                        int blueY = readLong(inputStream);
0476:                        int blueZ = readLong(inputStream);
0477:                        long gammaRed = readDWord(inputStream);
0478:                        long gammaGreen = readDWord(inputStream);
0479:                        long gammaBlue = readDWord(inputStream);
0480:
0481:                        if (bitsPerPixel == 1) {
0482:                            imageType = VERSION_4_1_BIT;
0483:                        } else if (bitsPerPixel == 4) {
0484:                            imageType = VERSION_4_4_BIT;
0485:                        } else if (bitsPerPixel == 8) {
0486:                            imageType = VERSION_4_8_BIT;
0487:                        } else if (bitsPerPixel == 16) {
0488:                            imageType = VERSION_4_16_BIT;
0489:                            if ((int) compression == BI_RGB) {
0490:                                redMask = 0x7C00;
0491:                                greenMask = 0x3E0;
0492:                                blueMask = 0x1F;
0493:                            }
0494:                        } else if (bitsPerPixel == 24) {
0495:                            imageType = VERSION_4_24_BIT;
0496:                        } else if (bitsPerPixel == 32) {
0497:                            imageType = VERSION_4_32_BIT;
0498:                            if ((int) compression == BI_RGB) {
0499:                                redMask = 0x00FF0000;
0500:                                greenMask = 0x0000FF00;
0501:                                blueMask = 0x000000FF;
0502:                            }
0503:                        }
0504:
0505:                        properties.put("red_mask", new Integer(redMask));
0506:                        properties.put("green_mask", new Integer(greenMask));
0507:                        properties.put("blue_mask", new Integer(blueMask));
0508:                        properties.put("alpha_mask", new Integer(alphaMask));
0509:
0510:                        // Read in the palette
0511:                        int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
0512:                        int sizeOfPalette = numberOfEntries * 4;
0513:                        if (bitmapOffset == size) {
0514:                            switch (imageType) {
0515:                            case VERSION_4_1_BIT:
0516:                                sizeOfPalette = (int) (colorsUsed == 0 ? 2
0517:                                        : colorsUsed) * 4;
0518:                                break;
0519:                            case VERSION_4_4_BIT:
0520:                                sizeOfPalette = (int) (colorsUsed == 0 ? 16
0521:                                        : colorsUsed) * 4;
0522:                                break;
0523:                            case VERSION_4_8_BIT:
0524:                                sizeOfPalette = (int) (colorsUsed == 0 ? 256
0525:                                        : colorsUsed) * 4;
0526:                                break;
0527:                            default:
0528:                                sizeOfPalette = 0;
0529:                                break;
0530:                            }
0531:                            bitmapOffset = size + sizeOfPalette;
0532:                        }
0533:                        readPalette(sizeOfPalette);
0534:
0535:                        switch ((int) csType) {
0536:                        case LCS_CALIBRATED_RGB:
0537:                            // All the new fields are valid only for this case
0538:                            properties.put("color_space", "LCS_CALIBRATED_RGB");
0539:                            properties.put("redX", new Integer(redX));
0540:                            properties.put("redY", new Integer(redY));
0541:                            properties.put("redZ", new Integer(redZ));
0542:                            properties.put("greenX", new Integer(greenX));
0543:                            properties.put("greenY", new Integer(greenY));
0544:                            properties.put("greenZ", new Integer(greenZ));
0545:                            properties.put("blueX", new Integer(blueX));
0546:                            properties.put("blueY", new Integer(blueY));
0547:                            properties.put("blueZ", new Integer(blueZ));
0548:                            properties.put("gamma_red", new Long(gammaRed));
0549:                            properties.put("gamma_green", new Long(gammaGreen));
0550:                            properties.put("gamma_blue", new Long(gammaBlue));
0551:
0552:                            // break;
0553:                            throw new RuntimeException("Not implemented yet.");
0554:
0555:                        case LCS_sRGB:
0556:                            // Default Windows color space
0557:                            properties.put("color_space", "LCS_sRGB");
0558:                            break;
0559:
0560:                        case LCS_CMYK:
0561:                            properties.put("color_space", "LCS_CMYK");
0562:                            //		    break;
0563:                            throw new RuntimeException("Not implemented yet.");
0564:                        }
0565:
0566:                    } else {
0567:                        properties.put("bmp_version", "BMP v. 5.x");
0568:                        throw new RuntimeException(
0569:                                "BMP version 5 not implemented yet.");
0570:                    }
0571:                }
0572:
0573:                if (height > 0) {
0574:                    // bottom up image
0575:                    isBottomUp = true;
0576:                } else {
0577:                    // top down image
0578:                    isBottomUp = false;
0579:                    height = Math.abs(height);
0580:                }
0581:                // When number of bitsPerPixel is <= 8, we use IndexColorModel.
0582:                if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) {
0583:
0584:                    numBands = 1;
0585:
0586:                    // Create IndexColorModel from the palette.
0587:                    byte r[], g[], b[];
0588:                    int sizep;
0589:                    if (imageType == VERSION_2_1_BIT
0590:                            || imageType == VERSION_2_4_BIT
0591:                            || imageType == VERSION_2_8_BIT) {
0592:
0593:                        sizep = palette.length / 3;
0594:
0595:                        if (sizep > 256) {
0596:                            sizep = 256;
0597:                        }
0598:
0599:                        int off;
0600:                        r = new byte[sizep];
0601:                        g = new byte[sizep];
0602:                        b = new byte[sizep];
0603:                        for (int i = 0; i < sizep; i++) {
0604:                            off = 3 * i;
0605:                            b[i] = palette[off];
0606:                            g[i] = palette[off + 1];
0607:                            r[i] = palette[off + 2];
0608:                        }
0609:                    } else {
0610:                        sizep = palette.length / 4;
0611:
0612:                        if (sizep > 256) {
0613:                            sizep = 256;
0614:                        }
0615:
0616:                        int off;
0617:                        r = new byte[sizep];
0618:                        g = new byte[sizep];
0619:                        b = new byte[sizep];
0620:                        for (int i = 0; i < sizep; i++) {
0621:                            off = 4 * i;
0622:                            b[i] = palette[off];
0623:                            g[i] = palette[off + 1];
0624:                            r[i] = palette[off + 2];
0625:                        }
0626:                    }
0627:
0628:                } else if (bitsPerPixel == 16) {
0629:                    numBands = 3;
0630:                } else if (bitsPerPixel == 32) {
0631:                    numBands = alphaMask == 0 ? 3 : 4;
0632:
0633:                    // The number of bands in the SampleModel is determined by
0634:                    // the length of the mask array passed in.
0635:                } else {
0636:                    numBands = 3;
0637:                }
0638:            }
0639:
0640:            private byte[] getPalette(int group) {
0641:                if (palette == null)
0642:                    return null;
0643:                byte np[] = new byte[palette.length / group * 3];
0644:                int e = palette.length / group;
0645:                for (int k = 0; k < e; ++k) {
0646:                    int src = k * group;
0647:                    int dest = k * 3;
0648:                    np[dest + 2] = palette[src++];
0649:                    np[dest + 1] = palette[src++];
0650:                    np[dest] = palette[src];
0651:                }
0652:                return np;
0653:            }
0654:
0655:            private Image getImage() throws IOException, BadElementException {
0656:                byte bdata[] = null; // buffer for byte data
0657:
0658:                //	if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE)
0659:                //	    bdata = (byte[])((DataBufferByte)tile.getDataBuffer()).getData();
0660:                //	else if (sampleModel.getDataType() == DataBuffer.TYPE_USHORT)
0661:                //	    sdata = (short[])((DataBufferUShort)tile.getDataBuffer()).getData();
0662:                //	else if (sampleModel.getDataType() == DataBuffer.TYPE_INT)
0663:                //	    idata = (int[])((DataBufferInt)tile.getDataBuffer()).getData();
0664:
0665:                // There should only be one tile.
0666:                switch (imageType) {
0667:
0668:                case VERSION_2_1_BIT:
0669:                    // no compression
0670:                    return read1Bit(3);
0671:
0672:                case VERSION_2_4_BIT:
0673:                    // no compression
0674:                    return read4Bit(3);
0675:
0676:                case VERSION_2_8_BIT:
0677:                    // no compression
0678:                    return read8Bit(3);
0679:
0680:                case VERSION_2_24_BIT:
0681:                    // no compression
0682:                    bdata = new byte[width * height * 3];
0683:                    read24Bit(bdata);
0684:                    return new ImgRaw(width, height, 3, 8, bdata);
0685:
0686:                case VERSION_3_1_BIT:
0687:                    // 1-bit images cannot be compressed.
0688:                    return read1Bit(4);
0689:
0690:                case VERSION_3_4_BIT:
0691:                    switch ((int) compression) {
0692:                    case BI_RGB:
0693:                        return read4Bit(4);
0694:
0695:                    case BI_RLE4:
0696:                        return readRLE4();
0697:
0698:                    default:
0699:                        throw new RuntimeException(
0700:                                "Invalid compression specified for BMP file.");
0701:                    }
0702:
0703:                case VERSION_3_8_BIT:
0704:                    switch ((int) compression) {
0705:                    case BI_RGB:
0706:                        return read8Bit(4);
0707:
0708:                    case BI_RLE8:
0709:                        return readRLE8();
0710:
0711:                    default:
0712:                        throw new RuntimeException(
0713:                                "Invalid compression specified for BMP file.");
0714:                    }
0715:
0716:                case VERSION_3_24_BIT:
0717:                    // 24-bit images are not compressed
0718:                    bdata = new byte[width * height * 3];
0719:                    read24Bit(bdata);
0720:                    return new ImgRaw(width, height, 3, 8, bdata);
0721:
0722:                case VERSION_3_NT_16_BIT:
0723:                    return read1632Bit(false);
0724:
0725:                case VERSION_3_NT_32_BIT:
0726:                    return read1632Bit(true);
0727:
0728:                case VERSION_4_1_BIT:
0729:                    return read1Bit(4);
0730:
0731:                case VERSION_4_4_BIT:
0732:                    switch ((int) compression) {
0733:
0734:                    case BI_RGB:
0735:                        return read4Bit(4);
0736:
0737:                    case BI_RLE4:
0738:                        return readRLE4();
0739:
0740:                    default:
0741:                        throw new RuntimeException(
0742:                                "Invalid compression specified for BMP file.");
0743:                    }
0744:
0745:                case VERSION_4_8_BIT:
0746:                    switch ((int) compression) {
0747:
0748:                    case BI_RGB:
0749:                        return read8Bit(4);
0750:
0751:                    case BI_RLE8:
0752:                        return readRLE8();
0753:
0754:                    default:
0755:                        throw new RuntimeException(
0756:                                "Invalid compression specified for BMP file.");
0757:                    }
0758:
0759:                case VERSION_4_16_BIT:
0760:                    return read1632Bit(false);
0761:
0762:                case VERSION_4_24_BIT:
0763:                    bdata = new byte[width * height * 3];
0764:                    read24Bit(bdata);
0765:                    return new ImgRaw(width, height, 3, 8, bdata);
0766:
0767:                case VERSION_4_32_BIT:
0768:                    return read1632Bit(true);
0769:                }
0770:                return null;
0771:            }
0772:
0773:            private Image indexedModel(byte bdata[], int bpc, int paletteEntries)
0774:                    throws BadElementException {
0775:                Image img = new ImgRaw(width, height, 1, bpc, bdata);
0776:                PdfArray colorspace = new PdfArray();
0777:                colorspace.add(PdfName.INDEXED);
0778:                colorspace.add(PdfName.DEVICERGB);
0779:                byte np[] = getPalette(paletteEntries);
0780:                int len = np.length;
0781:                colorspace.add(new PdfNumber(len / 3 - 1));
0782:                colorspace.add(new PdfString(np));
0783:                PdfDictionary ad = new PdfDictionary();
0784:                ad.put(PdfName.COLORSPACE, colorspace);
0785:                img.setAdditional(ad);
0786:                return img;
0787:            }
0788:
0789:            private void readPalette(int sizeOfPalette) throws IOException {
0790:                if (sizeOfPalette == 0) {
0791:                    return;
0792:                }
0793:
0794:                palette = new byte[sizeOfPalette];
0795:                int bytesRead = 0;
0796:                while (bytesRead < sizeOfPalette) {
0797:                    int r = inputStream.read(palette, bytesRead, sizeOfPalette
0798:                            - bytesRead);
0799:                    if (r < 0) {
0800:                        throw new RuntimeException("incomplete palette");
0801:                    }
0802:                    bytesRead += r;
0803:                }
0804:                properties.put("palette", palette);
0805:            }
0806:
0807:            // Deal with 1 Bit images using IndexColorModels
0808:            private Image read1Bit(int paletteEntries) throws IOException,
0809:                    BadElementException {
0810:                byte bdata[] = new byte[((width + 7) / 8) * height];
0811:                int padding = 0;
0812:                int bytesPerScanline = (int) Math.ceil((double) width / 8.0);
0813:
0814:                int remainder = bytesPerScanline % 4;
0815:                if (remainder != 0) {
0816:                    padding = 4 - remainder;
0817:                }
0818:
0819:                int imSize = (bytesPerScanline + padding) * height;
0820:
0821:                // Read till we have the whole image
0822:                byte values[] = new byte[imSize];
0823:                int bytesRead = 0;
0824:                while (bytesRead < imSize) {
0825:                    bytesRead += inputStream.read(values, bytesRead, imSize
0826:                            - bytesRead);
0827:                }
0828:
0829:                if (isBottomUp) {
0830:
0831:                    // Convert the bottom up image to a top down format by copying
0832:                    // one scanline from the bottom to the top at a time.
0833:
0834:                    for (int i = 0; i < height; i++) {
0835:                        System.arraycopy(values, imSize - (i + 1)
0836:                                * (bytesPerScanline + padding), bdata, i
0837:                                * bytesPerScanline, bytesPerScanline);
0838:                    }
0839:                } else {
0840:
0841:                    for (int i = 0; i < height; i++) {
0842:                        System.arraycopy(values, i
0843:                                * (bytesPerScanline + padding), bdata, i
0844:                                * bytesPerScanline, bytesPerScanline);
0845:                    }
0846:                }
0847:                return indexedModel(bdata, 1, paletteEntries);
0848:            }
0849:
0850:            // Method to read a 4 bit BMP image data
0851:            private Image read4Bit(int paletteEntries) throws IOException,
0852:                    BadElementException {
0853:                byte bdata[] = new byte[((width + 1) / 2) * height];
0854:
0855:                // Padding bytes at the end of each scanline
0856:                int padding = 0;
0857:
0858:                int bytesPerScanline = (int) Math.ceil((double) width / 2.0);
0859:                int remainder = bytesPerScanline % 4;
0860:                if (remainder != 0) {
0861:                    padding = 4 - remainder;
0862:                }
0863:
0864:                int imSize = (bytesPerScanline + padding) * height;
0865:
0866:                // Read till we have the whole image
0867:                byte values[] = new byte[imSize];
0868:                int bytesRead = 0;
0869:                while (bytesRead < imSize) {
0870:                    bytesRead += inputStream.read(values, bytesRead, imSize
0871:                            - bytesRead);
0872:                }
0873:
0874:                if (isBottomUp) {
0875:
0876:                    // Convert the bottom up image to a top down format by copying
0877:                    // one scanline from the bottom to the top at a time.
0878:                    for (int i = 0; i < height; i++) {
0879:                        System.arraycopy(values, imSize - (i + 1)
0880:                                * (bytesPerScanline + padding), bdata, i
0881:                                * bytesPerScanline, bytesPerScanline);
0882:                    }
0883:                } else {
0884:                    for (int i = 0; i < height; i++) {
0885:                        System.arraycopy(values, i
0886:                                * (bytesPerScanline + padding), bdata, i
0887:                                * bytesPerScanline, bytesPerScanline);
0888:                    }
0889:                }
0890:                return indexedModel(bdata, 4, paletteEntries);
0891:            }
0892:
0893:            // Method to read 8 bit BMP image data
0894:            private Image read8Bit(int paletteEntries) throws IOException,
0895:                    BadElementException {
0896:                byte bdata[] = new byte[width * height];
0897:                // Padding bytes at the end of each scanline
0898:                int padding = 0;
0899:
0900:                // width * bitsPerPixel should be divisible by 32
0901:                int bitsPerScanline = width * 8;
0902:                if (bitsPerScanline % 32 != 0) {
0903:                    padding = (bitsPerScanline / 32 + 1) * 32 - bitsPerScanline;
0904:                    padding = (int) Math.ceil(padding / 8.0);
0905:                }
0906:
0907:                int imSize = (width + padding) * height;
0908:
0909:                // Read till we have the whole image
0910:                byte values[] = new byte[imSize];
0911:                int bytesRead = 0;
0912:                while (bytesRead < imSize) {
0913:                    bytesRead += inputStream.read(values, bytesRead, imSize
0914:                            - bytesRead);
0915:                }
0916:
0917:                if (isBottomUp) {
0918:
0919:                    // Convert the bottom up image to a top down format by copying
0920:                    // one scanline from the bottom to the top at a time.
0921:                    for (int i = 0; i < height; i++) {
0922:                        System.arraycopy(values, imSize - (i + 1)
0923:                                * (width + padding), bdata, i * width, width);
0924:                    }
0925:                } else {
0926:                    for (int i = 0; i < height; i++) {
0927:                        System.arraycopy(values, i * (width + padding), bdata,
0928:                                i * width, width);
0929:                    }
0930:                }
0931:                return indexedModel(bdata, 8, paletteEntries);
0932:            }
0933:
0934:            // Method to read 24 bit BMP image data
0935:            private void read24Bit(byte[] bdata) {
0936:                // Padding bytes at the end of each scanline
0937:                int padding = 0;
0938:
0939:                // width * bitsPerPixel should be divisible by 32
0940:                int bitsPerScanline = width * 24;
0941:                if (bitsPerScanline % 32 != 0) {
0942:                    padding = (bitsPerScanline / 32 + 1) * 32 - bitsPerScanline;
0943:                    padding = (int) Math.ceil(padding / 8.0);
0944:                }
0945:
0946:                int imSize = ((width * 3 + 3) / 4 * 4) * height;
0947:                // Read till we have the whole image
0948:                byte values[] = new byte[imSize];
0949:                try {
0950:                    int bytesRead = 0;
0951:                    while (bytesRead < imSize) {
0952:                        int r = inputStream.read(values, bytesRead, imSize
0953:                                - bytesRead);
0954:                        if (r < 0)
0955:                            break;
0956:                        bytesRead += r;
0957:                    }
0958:                } catch (IOException ioe) {
0959:                    throw new ExceptionConverter(ioe);
0960:                }
0961:
0962:                int l = 0, count;
0963:
0964:                if (isBottomUp) {
0965:                    int max = width * height * 3 - 1;
0966:
0967:                    count = -padding;
0968:                    for (int i = 0; i < height; i++) {
0969:                        l = max - (i + 1) * width * 3 + 1;
0970:                        count += padding;
0971:                        for (int j = 0; j < width; j++) {
0972:                            bdata[l + 2] = values[count++];
0973:                            bdata[l + 1] = values[count++];
0974:                            bdata[l] = values[count++];
0975:                            l += 3;
0976:                        }
0977:                    }
0978:                } else {
0979:                    count = -padding;
0980:                    for (int i = 0; i < height; i++) {
0981:                        count += padding;
0982:                        for (int j = 0; j < width; j++) {
0983:                            bdata[l + 2] = values[count++];
0984:                            bdata[l + 1] = values[count++];
0985:                            bdata[l] = values[count++];
0986:                            l += 3;
0987:                        }
0988:                    }
0989:                }
0990:            }
0991:
0992:            private int findMask(int mask) {
0993:                int k = 0;
0994:                for (; k < 32; ++k) {
0995:                    if ((mask & 1) == 1)
0996:                        break;
0997:                    mask >>>= 1;
0998:                }
0999:                return mask;
1000:            }
1001:
1002:            private int findShift(int mask) {
1003:                int k = 0;
1004:                for (; k < 32; ++k) {
1005:                    if ((mask & 1) == 1)
1006:                        break;
1007:                    mask >>>= 1;
1008:                }
1009:                return k;
1010:            }
1011:
1012:            private Image read1632Bit(boolean is32) throws IOException,
1013:                    BadElementException {
1014:
1015:                int red_mask = findMask(redMask);
1016:                int red_shift = findShift(redMask);
1017:                int red_factor = red_mask + 1;
1018:                int green_mask = findMask(greenMask);
1019:                int green_shift = findShift(greenMask);
1020:                int green_factor = green_mask + 1;
1021:                int blue_mask = findMask(blueMask);
1022:                int blue_shift = findShift(blueMask);
1023:                int blue_factor = blue_mask + 1;
1024:                byte bdata[] = new byte[width * height * 3];
1025:                // Padding bytes at the end of each scanline
1026:                int padding = 0;
1027:
1028:                if (!is32) {
1029:                    // width * bitsPerPixel should be divisible by 32
1030:                    int bitsPerScanline = width * 16;
1031:                    if (bitsPerScanline % 32 != 0) {
1032:                        padding = (bitsPerScanline / 32 + 1) * 32
1033:                                - bitsPerScanline;
1034:                        padding = (int) Math.ceil(padding / 8.0);
1035:                    }
1036:                }
1037:
1038:                int imSize = (int) imageSize;
1039:                if (imSize == 0) {
1040:                    imSize = (int) (bitmapFileSize - bitmapOffset);
1041:                }
1042:
1043:                int l = 0;
1044:                int v;
1045:                if (isBottomUp) {
1046:                    for (int i = height - 1; i >= 0; --i) {
1047:                        l = width * 3 * i;
1048:                        for (int j = 0; j < width; j++) {
1049:                            if (is32)
1050:                                v = (int) readDWord(inputStream);
1051:                            else
1052:                                v = readWord(inputStream);
1053:                            bdata[l++] = (byte) (((v >>> red_shift) & red_mask) * 256 / red_factor);
1054:                            bdata[l++] = (byte) (((v >>> green_shift) & green_mask) * 256 / green_factor);
1055:                            bdata[l++] = (byte) (((v >>> blue_shift) & blue_mask) * 256 / blue_factor);
1056:                        }
1057:                        for (int m = 0; m < padding; m++) {
1058:                            inputStream.read();
1059:                        }
1060:                    }
1061:                } else {
1062:                    for (int i = 0; i < height; i++) {
1063:                        for (int j = 0; j < width; j++) {
1064:                            if (is32)
1065:                                v = (int) readDWord(inputStream);
1066:                            else
1067:                                v = readWord(inputStream);
1068:                            bdata[l++] = (byte) (((v >>> red_shift) & red_mask) * 256 / red_factor);
1069:                            bdata[l++] = (byte) (((v >>> green_shift) & green_mask) * 256 / green_factor);
1070:                            bdata[l++] = (byte) (((v >>> blue_shift) & blue_mask) * 256 / blue_factor);
1071:                        }
1072:                        for (int m = 0; m < padding; m++) {
1073:                            inputStream.read();
1074:                        }
1075:                    }
1076:                }
1077:                return new ImgRaw(width, height, 3, 8, bdata);
1078:            }
1079:
1080:            private Image readRLE8() throws IOException, BadElementException {
1081:
1082:                // If imageSize field is not provided, calculate it.
1083:                int imSize = (int) imageSize;
1084:                if (imSize == 0) {
1085:                    imSize = (int) (bitmapFileSize - bitmapOffset);
1086:                }
1087:
1088:                // Read till we have the whole image
1089:                byte values[] = new byte[imSize];
1090:                int bytesRead = 0;
1091:                while (bytesRead < imSize) {
1092:                    bytesRead += inputStream.read(values, bytesRead, imSize
1093:                            - bytesRead);
1094:                }
1095:
1096:                // Since data is compressed, decompress it
1097:                byte val[] = decodeRLE(true, values);
1098:
1099:                // Uncompressed data does not have any padding
1100:                imSize = width * height;
1101:
1102:                if (isBottomUp) {
1103:
1104:                    // Convert the bottom up image to a top down format by copying
1105:                    // one scanline from the bottom to the top at a time.
1106:                    // int bytesPerScanline = (int)Math.ceil((double)width/8.0);
1107:                    byte temp[] = new byte[val.length];
1108:                    int bytesPerScanline = width;
1109:                    for (int i = 0; i < height; i++) {
1110:                        System.arraycopy(val, imSize - (i + 1)
1111:                                * (bytesPerScanline), temp, i
1112:                                * bytesPerScanline, bytesPerScanline);
1113:                    }
1114:                    val = temp;
1115:                }
1116:                return indexedModel(val, 8, 4);
1117:            }
1118:
1119:            private Image readRLE4() throws IOException, BadElementException {
1120:
1121:                // If imageSize field is not specified, calculate it.
1122:                int imSize = (int) imageSize;
1123:                if (imSize == 0) {
1124:                    imSize = (int) (bitmapFileSize - bitmapOffset);
1125:                }
1126:
1127:                // Read till we have the whole image
1128:                byte values[] = new byte[imSize];
1129:                int bytesRead = 0;
1130:                while (bytesRead < imSize) {
1131:                    bytesRead += inputStream.read(values, bytesRead, imSize
1132:                            - bytesRead);
1133:                }
1134:
1135:                // Decompress the RLE4 compressed data.
1136:                byte val[] = decodeRLE(false, values);
1137:
1138:                // Invert it as it is bottom up format.
1139:                if (isBottomUp) {
1140:
1141:                    byte inverted[] = val;
1142:                    val = new byte[width * height];
1143:                    int l = 0, index, lineEnd;
1144:
1145:                    for (int i = height - 1; i >= 0; i--) {
1146:                        index = i * width;
1147:                        lineEnd = l + width;
1148:                        while (l != lineEnd) {
1149:                            val[l++] = inverted[index++];
1150:                        }
1151:                    }
1152:                }
1153:                int stride = ((width + 1) / 2);
1154:                byte bdata[] = new byte[stride * height];
1155:                int ptr = 0;
1156:                int sh = 0;
1157:                for (int h = 0; h < height; ++h) {
1158:                    for (int w = 0; w < width; ++w) {
1159:                        if ((w & 1) == 0)
1160:                            bdata[sh + w / 2] = (byte) (val[ptr++] << 4);
1161:                        else
1162:                            bdata[sh + w / 2] |= (byte) (val[ptr++] & 0x0f);
1163:                    }
1164:                    sh += stride;
1165:                }
1166:                return indexedModel(bdata, 4, 4);
1167:            }
1168:
1169:            private byte[] decodeRLE(boolean is8, byte values[]) {
1170:                byte val[] = new byte[width * height];
1171:                try {
1172:                    int ptr = 0;
1173:                    int x = 0;
1174:                    int q = 0;
1175:                    for (int y = 0; y < height && ptr < values.length;) {
1176:                        int count = values[ptr++] & 0xff;
1177:                        if (count != 0) {
1178:                            // encoded mode
1179:                            int bt = values[ptr++] & 0xff;
1180:                            if (is8) {
1181:                                for (int i = count; i != 0; --i) {
1182:                                    val[q++] = (byte) bt;
1183:                                }
1184:                            } else {
1185:                                for (int i = 0; i < count; ++i) {
1186:                                    val[q++] = (byte) ((i & 1) == 1 ? (bt & 0x0f)
1187:                                            : ((bt >>> 4) & 0x0f));
1188:                                }
1189:                            }
1190:                            x += count;
1191:                        } else {
1192:                            // escape mode
1193:                            count = values[ptr++] & 0xff;
1194:                            if (count == 1)
1195:                                break;
1196:                            switch (count) {
1197:                            case 0:
1198:                                x = 0;
1199:                                ++y;
1200:                                q = y * width;
1201:                                break;
1202:                            case 2:
1203:                                // delta mode
1204:                                x += values[ptr++] & 0xff;
1205:                                y += values[ptr++] & 0xff;
1206:                                q = y * width + x;
1207:                                break;
1208:                            default:
1209:                                // absolute mode
1210:                                if (is8) {
1211:                                    for (int i = count; i != 0; --i)
1212:                                        val[q++] = (byte) (values[ptr++] & 0xff);
1213:                                } else {
1214:                                    int bt = 0;
1215:                                    for (int i = 0; i < count; ++i) {
1216:                                        if ((i & 1) == 0)
1217:                                            bt = values[ptr++] & 0xff;
1218:                                        val[q++] = (byte) ((i & 1) == 1 ? (bt & 0x0f)
1219:                                                : ((bt >>> 4) & 0x0f));
1220:                                    }
1221:                                }
1222:                                x += count;
1223:                                // read pad byte
1224:                                if (is8) {
1225:                                    if ((count & 1) == 1)
1226:                                        ++ptr;
1227:                                } else {
1228:                                    if ((count & 3) == 1 || (count & 3) == 2)
1229:                                        ++ptr;
1230:                                }
1231:                                break;
1232:                            }
1233:                        }
1234:                    }
1235:                } catch (RuntimeException e) {
1236:                    //empty on purpose
1237:                }
1238:
1239:                return val;
1240:            }
1241:
1242:            // Windows defined data type reading methods - everything is little endian
1243:
1244:            // Unsigned 8 bits
1245:            private int readUnsignedByte(InputStream stream) throws IOException {
1246:                return (stream.read() & 0xff);
1247:            }
1248:
1249:            // Unsigned 2 bytes
1250:            private int readUnsignedShort(InputStream stream)
1251:                    throws IOException {
1252:                int b1 = readUnsignedByte(stream);
1253:                int b2 = readUnsignedByte(stream);
1254:                return ((b2 << 8) | b1) & 0xffff;
1255:            }
1256:
1257:            // Signed 16 bits
1258:            private int readShort(InputStream stream) throws IOException {
1259:                int b1 = readUnsignedByte(stream);
1260:                int b2 = readUnsignedByte(stream);
1261:                return (b2 << 8) | b1;
1262:            }
1263:
1264:            // Unsigned 16 bits
1265:            private int readWord(InputStream stream) throws IOException {
1266:                return readUnsignedShort(stream);
1267:            }
1268:
1269:            // Unsigned 4 bytes
1270:            private long readUnsignedInt(InputStream stream) throws IOException {
1271:                int b1 = readUnsignedByte(stream);
1272:                int b2 = readUnsignedByte(stream);
1273:                int b3 = readUnsignedByte(stream);
1274:                int b4 = readUnsignedByte(stream);
1275:                long l = (long) ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
1276:                return l & 0xffffffff;
1277:            }
1278:
1279:            // Signed 4 bytes
1280:            private int readInt(InputStream stream) throws IOException {
1281:                int b1 = readUnsignedByte(stream);
1282:                int b2 = readUnsignedByte(stream);
1283:                int b3 = readUnsignedByte(stream);
1284:                int b4 = readUnsignedByte(stream);
1285:                return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
1286:            }
1287:
1288:            // Unsigned 4 bytes
1289:            private long readDWord(InputStream stream) throws IOException {
1290:                return readUnsignedInt(stream);
1291:            }
1292:
1293:            // 32 bit signed value
1294:            private int readLong(InputStream stream) throws IOException {
1295:                return readInt(stream);
1296:            }
1297:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.