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


0001:        /*
0002:         * $RCSfile: IIPResolutionOpImage.java,v $
0003:         *
0004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Use is subject to license terms.
0007:         *
0008:         * $Revision: 1.1 $
0009:         * $Date: 2005/02/11 04:56:28 $
0010:         * $State: Exp $
0011:         */
0012:        package com.sun.media.jai.opimage;
0013:
0014:        import java.awt.Point;
0015:        import java.awt.Rectangle;
0016:        import java.awt.RenderingHints;
0017:        import java.awt.Transparency;
0018:        import java.awt.color.ColorSpace;
0019:        import java.awt.geom.AffineTransform;
0020:        import java.awt.geom.Rectangle2D;
0021:        import java.awt.image.ColorModel;
0022:        import java.awt.image.ComponentColorModel;
0023:        import java.awt.image.DataBuffer;
0024:        import java.awt.image.DataBufferByte;
0025:        import java.awt.image.Raster;
0026:        import java.awt.image.RenderedImage;
0027:        import java.awt.image.SampleModel;
0028:        import java.awt.image.WritableRaster;
0029:        import java.io.InputStream;
0030:        import java.io.ByteArrayInputStream;
0031:        import java.net.URL;
0032:        import java.util.Vector;
0033:        import javax.media.jai.ImageLayout;
0034:        import javax.media.jai.JAI;
0035:        import javax.media.jai.OpImage;
0036:        import javax.media.jai.RasterFactory;
0037:        import javax.media.jai.util.ImagingException;
0038:        import javax.media.jai.util.ImagingListener;
0039:        import java.util.Map;
0040:        import com.sun.image.codec.jpeg.JPEGCodec;
0041:        import com.sun.image.codec.jpeg.JPEGDecodeParam;
0042:        import com.sun.image.codec.jpeg.JPEGImageDecoder;
0043:        import com.sun.media.jai.util.ImageUtil;
0044:
0045:        /**
0046:         * An OpImage class to generate an image from an IIP connection. A single
0047:         * resolution level of the remote IIP image is retrieved.
0048:         *
0049:         * @see javax.media.jai.operator.IIPDescriptor
0050:         * @since 1.0
0051:         */
0052:        public class IIPResolutionOpImage extends OpImage {
0053:            // Tile dimension are fixed at 64x64.
0054:            private static final int TILE_SIZE = 64;
0055:
0056:            // Default dimensions in tiles of block of tiles to retrieve.
0057:            private static final int TILE_BLOCK_WIDTH = 8;
0058:            private static final int TILE_BLOCK_HEIGHT = 2;
0059:
0060:            // Significant delimiters in responses.
0061:            private static final char BLANK = ' ';
0062:            private static final char COLON = ':';
0063:            private static final char SLASH = '/';
0064:            private static final char CR = 0x0d;
0065:            private static final char LF = 0x0a;
0066:
0067:            // Colorspace information
0068:            private static final int CS_COLORLESS = 0x0;
0069:            private static final int CS_MONOCHROME = 0x1;
0070:            private static final int CS_PHOTOYCC = 0x2;
0071:            private static final int CS_NIFRGB = 0x3;
0072:            private static final int CS_PLANE_ALPHA = 0x7ffe;
0073:
0074:            // Compression types
0075:            private static final int TILE_UNCOMPRESSED = 0x0;
0076:            private static final int TILE_SINGLE_COLOR = 0x1;
0077:            private static final int TILE_JPEG = 0x2;
0078:            private static final int TILE_INVALID = 0xffffffff;
0079:
0080:            // cache the ImagingListener
0081:            private static ImagingListener listener = JAI.getDefaultInstance()
0082:                    .getImagingListener();
0083:
0084:            /* The base URL string of the IIP server and image. */
0085:            private String URLString;
0086:
0087:            /* The desired resolution in IIP order: 0 is lowest resolution. */
0088:            private int resolution;
0089:
0090:            /* The desired sub-image. */
0091:            private int subImage;
0092:
0093:            /* The colorspace type. */
0094:            private int colorSpaceType;
0095:
0096:            /* Flag indicating whether the image has an opacity channel. */
0097:            private boolean hasAlpha;
0098:
0099:            /* Flag indicating whether the opacity channel is premultiplied. */
0100:            private boolean isAlphaPremultilpied;
0101:
0102:            /* The minimum tile in the X direction. */
0103:            private int minTileX;
0104:
0105:            /* The minimum tile in the Y direction. */
0106:            private int minTileY;
0107:
0108:            /* The number of tiles in the X direction. */
0109:            private int numXTiles;
0110:
0111:            /* The JPEGDecodeParam cache */
0112:            private JPEGDecodeParam[] decodeParamCache = new JPEGDecodeParam[255];
0113:
0114:            /* Property initialization flag. */
0115:            private boolean arePropertiesInitialized = false;
0116:
0117:            /* Tile block dimensions eventually used. */
0118:            private int tileBlockWidth = TILE_BLOCK_WIDTH;
0119:            private int tileBlockHeight = TILE_BLOCK_HEIGHT;
0120:
0121:            /** cache to extract the ImagingListener. */
0122:            private RenderingHints renderHints;
0123:
0124:            /*
0125:             * Convert YCbCr to NIF RGB using the appropriate algorithm.
0126:             */
0127:            private static final void YCbCrToNIFRGB(Raster raster) {
0128:                byte[] data = ((DataBufferByte) raster.getDataBuffer())
0129:                        .getData();
0130:
0131:                int offset = 0;
0132:                int length = data.length;
0133:                int MASK1 = 0x000000ff;
0134:                int MASK2 = 0x0000ff00;
0135:                if (raster.getSampleModel().getNumBands() == 3) {
0136:                    while (offset < length) {
0137:                        float Y = data[offset] & 0xff;
0138:                        float Cb = data[offset + 1] & 0xff;
0139:                        float Cr = data[offset + 2] & 0xff;
0140:
0141:                        int R = (int) (Y + 1.40200F * Cr - 178.255F);
0142:                        int G = (int) (Y - 0.34414F * Cb - 0.71414F * Cr + 135.4307F);
0143:                        int B = (int) (Y + 1.77200F * Cb - 225.43F);
0144:
0145:                        int imask = (R >> 5) & 0x18;
0146:                        data[offset++] = (byte) (((R & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0147:
0148:                        imask = (G >> 5) & 0x18;
0149:                        data[offset++] = (byte) (((G & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0150:
0151:                        imask = (B >> 5) & 0x18;
0152:                        data[offset++] = (byte) (((B & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0153:                    }
0154:                } else { // numBands == 4 (premultiplied NIFRGB with opacity)
0155:                    while (offset < length) {
0156:                        float Y = data[offset] & 0xff;
0157:                        float Cb = data[offset + 1] & 0xff;
0158:                        float Cr = data[offset + 2] & 0xff;
0159:
0160:                        int R = (int) (-Y - 1.40200F * Cr - 433.255F);
0161:                        int G = (int) (-Y + 0.34414F * Cb + 0.71414F * Cr + 119.5693F);
0162:                        int B = (int) (-Y - 1.77200F * Cb - 480.43F);
0163:
0164:                        int imask = (R >> 5) & 0x18;
0165:                        data[offset++] = (byte) (((R & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0166:
0167:                        imask = (G >> 5) & 0x18;
0168:                        data[offset++] = (byte) (((G & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0169:
0170:                        imask = (B >> 5) & 0x18;
0171:                        data[offset++] = (byte) (((B & (MASK1 >> imask)) | (MASK2 >> imask)) & 0xff);
0172:
0173:                        offset++; // skip the opacity
0174:                    }
0175:                }
0176:            }
0177:
0178:            /*
0179:             * Post one or more IIP commands using the HTTP protocol and return a
0180:             * stream from which the response(s) may be read. The "commands" parameter
0181:             * may be null.
0182:             */
0183:            private static InputStream postCommands(String URLSpec,
0184:                    String[] commands) {
0185:                // Construct the initial command by appending OBJ=IIP,1.0
0186:                StringBuffer spec = new StringBuffer(URLSpec + "&OBJ=iip,1.0");
0187:
0188:                if (commands != null) {
0189:                    // Append the commands to the string.
0190:                    for (int i = 0; i < commands.length; i++) {
0191:                        spec.append("&" + commands[i]);
0192:                    }
0193:                }
0194:
0195:                // Construct the URL and open a stream to read from it.
0196:                InputStream stream = null;
0197:                try {
0198:                    URL url = new URL(spec.toString());
0199:                    stream = url.openStream();
0200:                } catch (Exception e) {
0201:                    String message = JaiI18N.getString("IIPResolution4")
0202:                            + spec.toString();
0203:                    listener.errorOccurred(message, new ImagingException(
0204:                            message, e), IIPResolutionOpImage.class, false);
0205:                    //            throw new RuntimeException(e.getClass()+" "+e.getMessage());
0206:                }
0207:
0208:                return stream;
0209:            }
0210:
0211:            /*
0212:             * Retrieve the label of the IIP server response. The label is defined
0213:             * to be the bytes in the stream up to the first SLASH or COLON. The
0214:             * returned value will be null if an EOS is reached before any characters
0215:             * which are neither a SLASH or a COLON. If the returned String is non-null
0216:             * it will be lower case.
0217:             */
0218:            private static String getLabel(InputStream stream) {
0219:                boolean charsAppended = false;
0220:                StringBuffer buf = new StringBuffer(16);
0221:                try {
0222:                    int i;
0223:                    while ((i = stream.read()) != -1) {
0224:                        char c = (char) (0x000000ff & i);
0225:                        if (c == SLASH || c == COLON) {
0226:                            break;
0227:                        }
0228:                        buf.append(c);
0229:                        charsAppended = true;
0230:                    }
0231:                } catch (Exception e) {
0232:                    String message = JaiI18N.getString("IIPResolution5");
0233:                    listener.errorOccurred(message, new ImagingException(
0234:                            message, e), IIPResolutionOpImage.class, false);
0235:                    //            throw new RuntimeException(e.getClass()+" "+e.getMessage());
0236:                }
0237:
0238:                return charsAppended ? buf.toString().toLowerCase() : null;
0239:            }
0240:
0241:            /*
0242:             * Retrieve the length of the data stream. This length is assumed to
0243:             * be the an INT derived from the portion of the stream before the
0244:             * first COLON.
0245:             */
0246:            private static int getLength(InputStream stream) {
0247:                return Integer.valueOf(getLabel(stream)).intValue();
0248:            }
0249:
0250:            /*
0251:             * Throw or print a RuntimeException in response to an error returned by
0252:             * the IIP server. If no error was returned do nothing. Also grab and
0253:             * discard the response to the "OBJ=iip" command which is always present.
0254:             */
0255:            private static InputStream checkError(String label,
0256:                    InputStream stream, boolean throwException) {
0257:                if (label.equals("error")) {
0258:                    int length = Integer.valueOf(getLabel(stream)).intValue();
0259:                    byte[] b = new byte[length];
0260:                    try {
0261:                        stream.read(b);
0262:                    } catch (Exception e) {
0263:                        String message = JaiI18N.getString("IIPResolution6");
0264:                        listener.errorOccurred(message, new ImagingException(
0265:                                message, e), IIPResolutionOpImage.class, false);
0266:                        //                throw new RuntimeException(e.getClass()+" "+e.getMessage());
0267:                    }
0268:                    String msg = new String(b);
0269:                    if (throwException) {
0270:                        throwIIPException(msg);
0271:                    } else {
0272:                        printIIPException(msg);
0273:                    }
0274:                } else if (label.startsWith("iip")) {
0275:                    // Ignore this response.
0276:                    String iipObjectResponse = getDataAsString(stream, false);
0277:                }
0278:
0279:                return stream;
0280:            }
0281:
0282:            /*
0283:             * Returns the next segment of the stream until EOS or CRLF as a byte[].
0284:             * The length of the data must be available as an INT in the stream before
0285:             * the COLON.
0286:             */
0287:            private static byte[] getDataAsByteArray(InputStream stream) {
0288:                int length = getLength(stream);
0289:                byte[] b = new byte[length];
0290:
0291:                try {
0292:                    stream.read(b);
0293:                    stream.read(); // CR
0294:                    stream.read(); // LF
0295:                } catch (Exception e) {
0296:                    String message = JaiI18N.getString("IIPResolution7");
0297:                    listener.errorOccurred(message, new ImagingException(
0298:                            message, e), IIPResolutionOpImage.class, false);
0299:                    //            throw new RuntimeException(e.getClass()+" "+e.getMessage());
0300:                }
0301:
0302:                return b;
0303:            }
0304:
0305:            /*
0306:             * Returns the next segment of the stream until EOS or CRLF as a String.
0307:             */
0308:            private static String getDataAsString(InputStream stream,
0309:                    boolean hasLength) {
0310:                String str = null;
0311:                if (hasLength) {
0312:                    try {
0313:                        int length = getLength(stream);
0314:                        byte[] b = new byte[length];
0315:                        stream.read(b);
0316:                        stream.read(); // CR
0317:                        stream.read(); // LF
0318:                        str = new String(b);
0319:                    } catch (Exception e) {
0320:                        String message = JaiI18N.getString("IIPResolution7");
0321:                        listener.errorOccurred(message, new ImagingException(
0322:                                message, e), IIPResolutionOpImage.class, false);
0323:                        //                throw new RuntimeException(e.getClass()+" "+e.getMessage());
0324:                    }
0325:                } else {
0326:                    StringBuffer buf = new StringBuffer(16);
0327:                    try {
0328:                        int i;
0329:                        while ((i = stream.read()) != -1) {
0330:                            char c = (char) (0x000000ff & i);
0331:                            if (c == CR) { // if last byte was CR
0332:                                stream.read(); // LF
0333:                                break;
0334:                            }
0335:                            buf.append(c);
0336:                        }
0337:                        str = buf.toString();
0338:                    } catch (Exception e) {
0339:                        String message = JaiI18N.getString("IIPResolution7");
0340:                        listener.errorOccurred(message, new ImagingException(
0341:                                message, e), IIPResolutionOpImage.class, false);
0342:                        //                throw new RuntimeException(e.getClass()+" "+e.getMessage());
0343:                    }
0344:                }
0345:
0346:                return str;
0347:            }
0348:
0349:            /*
0350:             * Flush the next segment of the stream until EOS or CRLF.
0351:             */
0352:            private static void flushData(InputStream stream, boolean hasLength) {
0353:                if (hasLength) {
0354:                    try {
0355:                        int length = getLength(stream);
0356:                        long numSkipped = stream.skip(length);
0357:                        if (numSkipped == length) {
0358:                            stream.read(); // CR
0359:                            stream.read(); // LF
0360:                        }
0361:                    } catch (Exception e) {
0362:                        String message = JaiI18N.getString("IIPResolution8");
0363:                        listener.errorOccurred(message, new ImagingException(
0364:                                message, e), IIPResolutionOpImage.class, false);
0365:                        //                throw new RuntimeException(e.getClass()+" "+e.getMessage());
0366:                    }
0367:                } else {
0368:                    try {
0369:                        int i;
0370:                        while ((i = stream.read()) != -1) {
0371:                            if ((char) (0x000000ff & i) == CR) { // if last byte was CR
0372:                                stream.read(); // LF
0373:                                break;
0374:                            }
0375:                        }
0376:                    } catch (Exception e) {
0377:                        String message = JaiI18N.getString("IIPResolution8");
0378:                        listener.errorOccurred(message, new ImagingException(
0379:                                message, e), IIPResolutionOpImage.class, false);
0380:                        //                throw new RuntimeException(e.getClass()+" "+e.getMessage());
0381:                    }
0382:                }
0383:            }
0384:
0385:            /*
0386:             * Convert a string containing BLANK-seprated INTs into an int[].
0387:             */
0388:            private static int[] stringToIntArray(String s) {
0389:                // Parse string into a Vector.
0390:                Vector v = new Vector();
0391:                int lastBlank = 0;
0392:                int nextBlank = s.indexOf(BLANK, 0);
0393:                do {
0394:                    v.add(Integer.valueOf(s.substring(lastBlank, nextBlank)));
0395:                    lastBlank = nextBlank + 1;
0396:                    nextBlank = s.indexOf(BLANK, lastBlank);
0397:                } while (nextBlank != -1);
0398:                v.add(Integer.valueOf(s.substring(lastBlank)));
0399:
0400:                // Convert the Vector to a int[].
0401:                int length = v.size();
0402:                int[] intArray = new int[length];
0403:                for (int i = 0; i < length; i++) {
0404:                    intArray[i] = ((Integer) v.get(i)).intValue();
0405:                }
0406:
0407:                return intArray;
0408:            }
0409:
0410:            /*
0411:             * Convert a string containing BLANK-seprated FLOATs into a float[].
0412:             */
0413:            private static float[] stringToFloatArray(String s) {
0414:                // Parse string into a Vector.
0415:                Vector v = new Vector();
0416:                int lastBlank = 0;
0417:                int nextBlank = s.indexOf(BLANK, 0);
0418:                do {
0419:                    v.add(Float.valueOf(s.substring(lastBlank, nextBlank)));
0420:                    lastBlank = nextBlank + 1;
0421:                    nextBlank = s.indexOf(BLANK, lastBlank);
0422:                } while (nextBlank != -1);
0423:                v.add(Float.valueOf(s.substring(lastBlank)));
0424:
0425:                // Convert the Vector to a float[].
0426:                int length = v.size();
0427:                float[] floatArray = new float[length];
0428:                for (int i = 0; i < length; i++) {
0429:                    floatArray[i] = ((Float) v.get(i)).floatValue();
0430:                }
0431:
0432:                return floatArray;
0433:            }
0434:
0435:            /*
0436:             * Format the argument into a generic IIP error message.
0437:             */
0438:            private static String formatIIPErrorMessage(String msg) {
0439:                return new String(JaiI18N.getString("IIPResolutionOpImage0")
0440:                        + " " + msg);
0441:            }
0442:
0443:            /*
0444:             * Throw a RuntimeException with the indicated message.
0445:             */
0446:            private static void throwIIPException(String msg) {
0447:                throw new RuntimeException(formatIIPErrorMessage(msg));
0448:            }
0449:
0450:            /*
0451:             * Print the supplied message to the standard error stream.
0452:             */
0453:            private static void printIIPException(String msg) {
0454:                System.err.println(formatIIPErrorMessage(msg));
0455:            }
0456:
0457:            /*
0458:             * Close the supplied stream ignoring any exceptions.
0459:             */
0460:            private static void closeStream(InputStream stream) {
0461:                try {
0462:                    stream.close();
0463:                } catch (Exception e) {
0464:                    // Ignore
0465:                }
0466:            }
0467:
0468:            /*
0469:             * Derive the image layout (tile grid, image bounds, ColorModel, and
0470:             * SampleModel) by querying the IIP server.
0471:             */
0472:            private static ImageLayout layoutHelper(String URLSpec, int level,
0473:                    int subImage) {
0474:                // Create an ImageLayout by construction or cloning.
0475:                ImageLayout il = new ImageLayout();
0476:
0477:                // Set the tile offsets to (0,0).
0478:                il.setTileGridXOffset(0);
0479:                il.setTileGridYOffset(0);
0480:
0481:                // Set the tile dimensions.
0482:                il.setTileWidth(TILE_SIZE);
0483:                il.setTileHeight(TILE_SIZE);
0484:
0485:                // Set the image origin to (0,0).
0486:                il.setMinX(0);
0487:                il.setMinY(0);
0488:
0489:                // Retrieve the number of resolutions available and the maximum
0490:                // width and height (the dimensions of resolution numRes - 1).
0491:                int maxWidth = -1;
0492:                int maxHeight = -1;
0493:                int numRes = -1;
0494:                int resolution = -1;
0495:                String[] cmd = new String[] { "OBJ=Max-size",
0496:                        "OBJ=Resolution-number" };
0497:                InputStream stream = postCommands(URLSpec, cmd);
0498:                String label = null;
0499:                while ((label = getLabel(stream)) != null) {
0500:                    if (label.equals("max-size")) {
0501:                        String data = getDataAsString(stream, false);
0502:                        int[] wh = stringToIntArray(data);
0503:                        maxWidth = wh[0];
0504:                        maxHeight = wh[1];
0505:                    } else if (label.equals("resolution-number")) {
0506:                        String data = getDataAsString(stream, false);
0507:                        numRes = Integer.valueOf(data).intValue();
0508:                        if (level < 0) {
0509:                            resolution = 0;
0510:                        } else if (level >= numRes) {
0511:                            resolution = numRes - 1;
0512:                        } else {
0513:                            resolution = level;
0514:                        }
0515:                    } else {
0516:                        checkError(label, stream, true);
0517:                    }
0518:                }
0519:                closeStream(stream);
0520:
0521:                // Derive the width and height for this resolution level.
0522:                int w = maxWidth;
0523:                int h = maxHeight;
0524:                for (int i = numRes - 1; i > resolution; i--) {
0525:                    w = (w + 1) / 2;
0526:                    h = (h + 1) / 2;
0527:                }
0528:                il.setWidth(w);
0529:                il.setHeight(h);
0530:
0531:                // Determine image opacity attributes.
0532:                boolean hasAlpha = false;
0533:                boolean isAlphaPremultiplied = false;
0534:                cmd = new String[] { "OBJ=Colorspace," + resolution + ","
0535:                        + subImage };
0536:                stream = postCommands(URLSpec, cmd);
0537:                int colorSpaceIndex = 0;
0538:                int numBands = 0;
0539:                while ((label = getLabel(stream)) != null) {
0540:                    if (label.startsWith("colorspace")) {
0541:                        int[] ia = stringToIntArray(getDataAsString(stream,
0542:                                false));
0543:                        numBands = ia[3];
0544:                        switch (ia[2]) {
0545:                        case CS_MONOCHROME:
0546:                            colorSpaceIndex = ColorSpace.CS_GRAY;
0547:                            break;
0548:                        case CS_PHOTOYCC:
0549:                            colorSpaceIndex = ColorSpace.CS_PYCC;
0550:                            break;
0551:                        case CS_NIFRGB:
0552:                            colorSpaceIndex = ColorSpace.CS_sRGB;
0553:                            break;
0554:                        default:
0555:                            colorSpaceIndex = numBands < 3 ? ColorSpace.CS_GRAY
0556:                                    : ColorSpace.CS_sRGB;
0557:                        }
0558:                        for (int j = 1; j <= numBands; j++) {
0559:                            if (ia[3 + j] == CS_PLANE_ALPHA) {
0560:                                hasAlpha = true;
0561:                            }
0562:                        }
0563:                        isAlphaPremultiplied = ia[1] == 1;
0564:                    } else {
0565:                        checkError(label, stream, true);
0566:                    }
0567:                }
0568:                closeStream(stream);
0569:
0570:                // Set the ColorModel.
0571:                ColorSpace cs = ColorSpace.getInstance(colorSpaceIndex);
0572:                int dtSize = DataBuffer.getDataTypeSize(DataBuffer.TYPE_BYTE);
0573:                int[] bits = new int[numBands];
0574:                for (int i = 0; i < numBands; i++) {
0575:                    bits[i] = dtSize;
0576:                }
0577:                int transparency = hasAlpha ? Transparency.TRANSLUCENT
0578:                        : Transparency.OPAQUE;
0579:                ColorModel cm = new ComponentColorModel(cs, bits, hasAlpha,
0580:                        isAlphaPremultiplied, transparency,
0581:                        DataBuffer.TYPE_BYTE);
0582:                il.setColorModel(cm);
0583:
0584:                // Set the SampleModel.
0585:                int[] bandOffsets = new int[numBands];
0586:                for (int i = 0; i < numBands; i++) {
0587:                    bandOffsets[i] = i;
0588:                }
0589:                il.setSampleModel(RasterFactory
0590:                        .createPixelInterleavedSampleModel(
0591:                                DataBuffer.TYPE_BYTE, TILE_SIZE, TILE_SIZE,
0592:                                numBands, numBands * TILE_SIZE, bandOffsets));
0593:
0594:                return il;
0595:            }
0596:
0597:            /**
0598:             * Construct an OpImage given a String representation of a URL,
0599:             * a resolution, and a sub-image index.
0600:             *
0601:             * @param URLSpec The URL of the IIP image including the FIF cimmand
0602:             * if needed and possibly an SDS command.
0603:             * @param level The resolution level with 0 as the lowest resolution.
0604:             * @param subImage The subimage number.
0605:
0606:             * @param layout The layout hint; may be null.
0607:             */
0608:            public IIPResolutionOpImage(Map config, String URLSpec, int level,
0609:                    int subImage) {
0610:                super ((Vector) null, // the image is sourceless
0611:                        layoutHelper(URLSpec, level, subImage), config, false);
0612:
0613:                this .renderHints = (RenderingHints) config;
0614:
0615:                // Cache the constructor parameters.
0616:                URLString = URLSpec;
0617:                this .subImage = subImage;
0618:
0619:                // Retrieve required parameters from server.
0620:                String[] cmd = new String[] { "OBJ=Resolution-number" };
0621:                InputStream stream = postCommands(cmd);
0622:                String label = null;
0623:                while ((label = getLabel(stream)) != null) {
0624:                    if (label.equals("resolution-number")) {
0625:                        String data = getDataAsString(stream, false);
0626:                        int numRes = Integer.valueOf(data).intValue();
0627:                        if (level < 0) {
0628:                            resolution = 0;
0629:                        } else if (level >= numRes) {
0630:                            resolution = numRes - 1;
0631:                        } else {
0632:                            resolution = level;
0633:                        }
0634:                    } else {
0635:                        checkError(label, stream, true);
0636:                    }
0637:                }
0638:                endResponse(stream);
0639:
0640:                // Cache some values which will be used repetitively.
0641:                ColorSpace cs = colorModel.getColorSpace();
0642:                if (cs.isCS_sRGB()) {
0643:                    colorSpaceType = CS_NIFRGB;
0644:                } else if (cs
0645:                        .equals(ColorSpace.getInstance(ColorSpace.CS_GRAY))) {
0646:                    colorSpaceType = CS_MONOCHROME;
0647:                } else {
0648:                    colorSpaceType = CS_PHOTOYCC;
0649:                }
0650:                hasAlpha = colorModel.hasAlpha();
0651:                isAlphaPremultilpied = colorModel.isAlphaPremultiplied();
0652:                minTileX = getMinTileX();
0653:                minTileY = getMinTileY();
0654:                numXTiles = getNumXTiles();
0655:            }
0656:
0657:            /*
0658:             * Post the array of commands to the IIP server.
0659:             */
0660:            private InputStream postCommands(String[] commands) {
0661:                return postCommands(URLString, commands);
0662:            }
0663:
0664:            /*
0665:             * End reading the server response.
0666:             */
0667:            private void endResponse(InputStream stream) {
0668:                // Add if-then block and handle socket connection.
0669:                closeStream(stream);
0670:            }
0671:
0672:            /*
0673:             * Compute the tile with the specified position in the tile grid.
0674:             * Either a block of tiles or a single tile is retrieved depending
0675:             * on where the requested tile false in the tile grid with respect
0676:             * to the upper left tile in the image. All tiles except that returned
0677:             * are stored in the TileCache.
0678:             */
0679:            public Raster computeTile(int tileX, int tileY) {
0680:                Raster raster = null;
0681:
0682:                // If the tile is the upper left tile of a block of tiles
0683:                // where the blocks are counted from the upper left corner
0684:                // of the image then retrieve a block of tiles.
0685:                if ((tileX - minTileX) % tileBlockWidth == 0
0686:                        && (tileY - minTileY) % tileBlockHeight == 0) {
0687:                    int endTileX = tileX + tileBlockWidth - 1;
0688:                    if (endTileX > getMaxTileX()) {
0689:                        endTileX = getMaxTileX();
0690:                    }
0691:                    int endTileY = tileY + tileBlockHeight - 1;
0692:                    if (endTileY > getMaxTileY()) {
0693:                        endTileY = getMaxTileY();
0694:                    }
0695:                    raster = getTileBlock(tileX, tileY, endTileX, endTileY);
0696:                } else if ((raster = getTileFromCache(tileX, tileY)) == null) {
0697:                    raster = getTileBlock(tileX, tileY, tileX, tileY);
0698:                }
0699:
0700:                return raster;
0701:            }
0702:
0703:            /*
0704:             * Extract from the IIP response label the coordinates in the tile grid
0705:             * of the tile returned by the IIP server.
0706:             *
0707:             * @param label The IIP response label.
0708:             * @param xy The tile grid coordinates; may be null.
0709:             */
0710:            private Point getTileXY(String label, Point xy) {
0711:                // Get the tile number from the IIP response label.
0712:                int beginIndex = label.indexOf(",", label.indexOf(",") + 1) + 1;
0713:                int endIndex = label.lastIndexOf(",");
0714:                int tile = Integer.valueOf(
0715:                        label.substring(beginIndex, endIndex)).intValue();
0716:
0717:                // Calculate the tile coordinates.
0718:                int tileX = (tile + minTileX) % numXTiles;
0719:                int tileY = (tile + minTileX - tileX) / numXTiles + minTileY;
0720:
0721:                // Create or set the location.
0722:                if (xy == null) {
0723:                    xy = new Point(tileX, tileY);
0724:                } else {
0725:                    xy.setLocation(tileX, tileY);
0726:                }
0727:
0728:                return xy;
0729:            }
0730:
0731:            /*
0732:             * Retrieve a block of tiles from the IIP server. All tiles except
0733:             * the upper left tile are stored in the TileCache wheareas the upper
0734:             * left tile is returned.
0735:             */
0736:            private Raster getTileBlock(int upperLeftTileX, int upperLeftTileY,
0737:                    int lowerRightTileX, int lowerRightTileY) {
0738:                int startTile = (upperLeftTileY - minTileY) * numXTiles
0739:                        + upperLeftTileX - minTileX;
0740:                int endTile = (lowerRightTileY - minTileY) * numXTiles
0741:                        + lowerRightTileX - minTileX;
0742:
0743:                String cmd = null;
0744:                if (startTile == endTile) { // single tile
0745:                    cmd = new String("til=" + resolution + "," + startTile
0746:                            + "," + subImage);
0747:                } else { // range of tiles
0748:                    cmd = new String("til=" + resolution + "," + startTile
0749:                            + "-" + endTile + "," + subImage);
0750:                }
0751:                InputStream stream = postCommands(new String[] { cmd });
0752:                int compressionType = -1;
0753:                int compressionSubType = -1;
0754:                byte[] data = null;
0755:                String label = null;
0756:                Raster upperLeftTile = null;
0757:                Point tileXY = new Point();
0758:                while ((label = getLabel(stream)) != null) {
0759:                    if (label.startsWith("tile")) {
0760:                        int length = getLength(stream);
0761:
0762:                        byte[] header = new byte[8];
0763:                        try {
0764:                            stream.read(header);
0765:                        } catch (Exception e) {
0766:                            throwIIPException(JaiI18N
0767:                                    .getString("IIPResolutionOpImage1"));
0768:                        }
0769:
0770:                        length -= 8;
0771:
0772:                        compressionType = (int) ((header[3] << 24)
0773:                                | (header[2] << 16) | (header[1] << 8) | header[0]);
0774:                        compressionSubType = (int) ((header[7] << 24)
0775:                                | (header[6] << 16) | (header[5] << 8) | header[4]);
0776:
0777:                        if (length != 0) {
0778:                            data = new byte[length];
0779:                            try {
0780:                                int numBytesRead = 0;
0781:                                int offset = 0;
0782:                                do {
0783:                                    numBytesRead = stream.read(data, offset,
0784:                                            length - offset);
0785:                                    offset += numBytesRead;
0786:                                } while (offset < length && numBytesRead != -1);
0787:                                if (numBytesRead != -1) {
0788:                                    stream.read(); // CR
0789:                                    stream.read(); // LF
0790:                                }
0791:                            } catch (Exception e) {
0792:                                throwIIPException(JaiI18N
0793:                                        .getString("IIPResolutionOpImage2"));
0794:                            }
0795:                        }
0796:
0797:                        getTileXY(label, tileXY);
0798:                        int tileX = (int) tileXY.getX();
0799:                        int tileY = (int) tileXY.getY();
0800:                        int tx = tileXToX(tileX);
0801:                        int ty = tileYToY(tileY);
0802:
0803:                        Raster raster = null;
0804:
0805:                        switch (compressionType) {
0806:                        case TILE_UNCOMPRESSED:
0807:                            raster = getUncompressedTile(tx, ty, data);
0808:                            break;
0809:                        case TILE_SINGLE_COLOR:
0810:                            raster = getSingleColorTile(tx, ty,
0811:                                    compressionSubType);
0812:                            break;
0813:                        case TILE_JPEG:
0814:                            raster = getJPEGTile(tx, ty, compressionSubType,
0815:                                    data);
0816:                            break;
0817:                        case TILE_INVALID:
0818:                        default:
0819:                            raster = createWritableRaster(sampleModel,
0820:                                    new Point(tx, ty));
0821:                            break;
0822:                        }
0823:
0824:                        if (tileX == upperLeftTileX && tileY == upperLeftTileY) {
0825:                            upperLeftTile = raster;
0826:                        } else {
0827:                            //System.out.println("Caching "+label);
0828:                            addTileToCache(tileX, tileY, raster);
0829:                        }
0830:                    } else {
0831:                        checkError(label, stream, true);
0832:                    }
0833:                }
0834:
0835:                endResponse(stream);
0836:
0837:                return upperLeftTile;
0838:            }
0839:
0840:            /*
0841:             * Create a Raster from the data of an uncompressed tile.
0842:             */
0843:            private Raster getUncompressedTile(int tx, int ty, byte[] data) {
0844:                DataBuffer dataBuffer = new DataBufferByte(data, data.length);
0845:
0846:                return Raster.createRaster(sampleModel, dataBuffer, new Point(
0847:                        tx, ty));
0848:            }
0849:
0850:            /*
0851:             * Create a Raster of a single color.
0852:             */
0853:            private Raster getSingleColorTile(int tx, int ty, int color) {
0854:                byte R = (byte) (color & 0x000000ff);
0855:                byte G = (byte) ((color >> 8) & 0x000000ff);
0856:                byte B = (byte) ((color >> 16) & 0x000000ff);
0857:                byte A = (byte) ((color >> 24) & 0x000000ff);
0858:
0859:                int numBands = sampleModel.getNumBands();
0860:                int length = tileWidth * tileHeight * numBands;
0861:                byte[] data = new byte[length];
0862:                int i = 0;
0863:                switch (numBands) {
0864:                case 1:
0865:                    while (i < length) {
0866:                        data[i++] = R;
0867:                    }
0868:                    break;
0869:                case 2:
0870:                    while (i < length) {
0871:                        data[i++] = R;
0872:                        data[i++] = A;
0873:                    }
0874:                    break;
0875:                case 3:
0876:                    while (i < length) {
0877:                        data[i++] = R;
0878:                        data[i++] = G;
0879:                        data[i++] = B;
0880:                    }
0881:                case 4:
0882:                default:
0883:                    while (i < length) {
0884:                        data[i++] = R;
0885:                        data[i++] = G;
0886:                        data[i++] = B;
0887:                        data[i++] = A;
0888:                    }
0889:                }
0890:
0891:                DataBuffer dataBuffer = new DataBufferByte(data, data.length);
0892:
0893:                return Raster.createRaster(sampleModel, dataBuffer, new Point(
0894:                        tx, ty));
0895:            }
0896:
0897:            /*
0898:             * Create a Raster from a JPEG-compressed data stream.
0899:             */
0900:            private Raster getJPEGTile(int tx, int ty, int subType, byte[] data) {
0901:                int tableIndex = (subType >> 24) & 0x000000ff;
0902:                ;
0903:                boolean colorConversion = (subType & 0x00ff0000) != 0;
0904:                JPEGDecodeParam decodeParam = null;
0905:                if (tableIndex != 0) {
0906:                    decodeParam = getJPEGDecodeParam(tableIndex);
0907:                }
0908:
0909:                ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
0910:                JPEGImageDecoder decoder = decodeParam == null ? JPEGCodec
0911:                        .createJPEGDecoder(byteStream) : JPEGCodec
0912:                        .createJPEGDecoder(byteStream, decodeParam);
0913:
0914:                Raster raster = null;
0915:                try {
0916:                    raster = decoder.decodeAsRaster().createTranslatedChild(tx,
0917:                            ty);
0918:                } catch (Exception e) {
0919:
0920:                    ImagingListener listener = ImageUtil
0921:                            .getImagingListener(renderHints);
0922:                    listener.errorOccurred(JaiI18N
0923:                            .getString("IIPResolutionOpImage3"),
0924:                            new ImagingException(e), this , false);
0925:                    /*
0926:                     String msg = JaiI18N.getString("IIPResolutionOpImage3")+" "+
0927:                     e.getMessage();
0928:                     throw new RuntimeException(msg);
0929:                     */
0930:                }
0931:                closeStream(byteStream);
0932:
0933:                if (colorSpaceType == CS_NIFRGB && colorConversion) {
0934:                    YCbCrToNIFRGB(raster);
0935:                }
0936:
0937:                return raster;
0938:            }
0939:
0940:            /*
0941:             * Retrieve the JPEGDecodeParam object for the indicated table. If the
0942:             * object is available in the config, use it; otherwise retrieve it from
0943:             * the server. An ArrayIndexOutOfBoundsException will be thrown if
0944:             * the parameter is not in the range [1,256].
0945:             */
0946:            private synchronized JPEGDecodeParam getJPEGDecodeParam(
0947:                    int tableIndex) {
0948:                JPEGDecodeParam decodeParam = decodeParamCache[tableIndex - 1];
0949:
0950:                if (decodeParam == null) {
0951:                    String cmd = new String("OBJ=Comp-group," + TILE_JPEG + ","
0952:                            + tableIndex);
0953:                    InputStream stream = postCommands(new String[] { cmd });
0954:                    String label = null;
0955:                    while ((label = getLabel(stream)) != null) {
0956:                        if (label.startsWith("comp-group")) {
0957:                            byte[] table = getDataAsByteArray(stream);
0958:                            ByteArrayInputStream tableStream = new ByteArrayInputStream(
0959:                                    table);
0960:                            JPEGImageDecoder decoder = JPEGCodec
0961:                                    .createJPEGDecoder(tableStream);
0962:                            try {
0963:                                // This call is necessary.
0964:                                decoder.decodeAsRaster();
0965:                            } catch (Exception e) {
0966:                                // Ignore.
0967:                            }
0968:                            decodeParam = decoder.getJPEGDecodeParam();
0969:                        } else {
0970:                            checkError(label, stream, true);
0971:                        }
0972:                    }
0973:
0974:                    endResponse(stream);
0975:
0976:                    if (decodeParam != null) {
0977:                        decodeParamCache[tableIndex - 1] = decodeParam;
0978:                    }
0979:                }
0980:
0981:                return decodeParam;
0982:            }
0983:
0984:            /*
0985:             * Obtain valid properties from IIP server and use
0986:             * setProperty() to store the name/value pairs.
0987:             */
0988:            private synchronized void initializeIIPProperties() {
0989:                if (!arePropertiesInitialized) {
0990:                    String[] cmd = new String[] { "OBJ=IIP", "OBJ=Basic-info",
0991:                            "OBJ=View-info", "OBJ=Summary-info",
0992:                            "OBJ=Copyright" };
0993:                    InputStream stream = postCommands(cmd);
0994:                    String label = null;
0995:                    while ((label = getLabel(stream)) != null) {
0996:                        String name = label;
0997:                        Object value = null;
0998:                        if (label.equals("error")) {
0999:                            flushData(stream, true);
1000:                        } else if (label.startsWith("colorspace")
1001:                                || label.equals("max-size")) {
1002:                            if (label.startsWith("colorspace")) {
1003:                                name = "colorspace";
1004:                            }
1005:                            value = stringToIntArray(getDataAsString(stream,
1006:                                    false));
1007:                        } else if (label.equals("resolution-number")) {
1008:                            value = Integer.valueOf(getDataAsString(stream,
1009:                                    false));
1010:                        } else if (label.equals("aspect-ratio")
1011:                                || label.equals("contrast-adjust")
1012:                                || label.equals("filtering-value")) {
1013:                            value = Float
1014:                                    .valueOf(getDataAsString(stream, false));
1015:                        } else if (label.equals("affine-transform")) {
1016:                            float[] a = (float[]) stringToFloatArray(getDataAsString(
1017:                                    stream, false));
1018:                            value = new AffineTransform(a[0], a[1], a[3], a[4],
1019:                                    a[5], a[7]);
1020:                        } else if (label.equals("color-twist")) {
1021:                            value = stringToFloatArray(getDataAsString(stream,
1022:                                    false));
1023:                        } else if (label.equals("roi")) {
1024:                            name = "roi-iip";
1025:                            float[] rect = stringToFloatArray(getDataAsString(
1026:                                    stream, false));
1027:                            value = new Rectangle2D.Float(rect[0], rect[1],
1028:                                    rect[2], rect[3]);
1029:                        } else if (label.equals("copyright")
1030:                                || label.equals("title")
1031:                                || label.equals("subject")
1032:                                || label.equals("author")
1033:                                || label.equals("keywords")
1034:                                || label.equals("comment")
1035:                                || label.equals("last-author")
1036:                                || label.equals("rev-number")
1037:                                || label.equals("app-name")) {
1038:                            value = getDataAsString(stream, true);
1039:                        } else if (label.equals("iip")
1040:                                || label.equals("iip-server")
1041:                                || label.equals("edit-time")
1042:                                || label.equals("last-printed")
1043:                                || label.equals("create-dtm")
1044:                                || label.equals("last-save-dtm")) {
1045:                            value = getDataAsString(stream, false);
1046:                        } else { // Ignore unknown objects
1047:                            flushData(stream, false);
1048:                        }
1049:                        if (name != null && value != null) {
1050:                            setProperty(name, value);
1051:                        }
1052:                    }
1053:                    endResponse(stream);
1054:                    arePropertiesInitialized = true;
1055:                }
1056:            }
1057:
1058:            /*
1059:             * Forward to superclass after lazy initialization of IIP properties.
1060:             */
1061:            public String[] getPropertyNames() {
1062:                initializeIIPProperties();
1063:                return super .getPropertyNames();
1064:            }
1065:
1066:            /*
1067:             * Forward to superclass after lazy initialization of IIP properties.
1068:             */
1069:            public Object getProperty(String name) {
1070:                initializeIIPProperties();
1071:                return super .getProperty(name);
1072:            }
1073:
1074:            /**
1075:             * Throws an IllegalArgumentException since the image has no image
1076:             * sources.
1077:             *
1078:             * @param sourceRect ignored.
1079:             * @param sourceIndex ignored.
1080:             * @throws IllegalArgumentException since the image has no image sources.
1081:             */
1082:            public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
1083:                throw new IllegalArgumentException(JaiI18N
1084:                        .getString("AreaOpImage0"));
1085:            }
1086:
1087:            /**
1088:             * Throws an IllegalArgumentException since the image has no image
1089:             * sources.
1090:             *
1091:             * @param destRect ignored.
1092:             * @param sourceIndex ignored.
1093:             * @throws IllegalArgumentException since the image has no image sources.
1094:             */
1095:            public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
1096:                throw new IllegalArgumentException(JaiI18N
1097:                        .getString("AreaOpImage0"));
1098:            }
1099:
1100:            /**
1101:             * Dispose of any allocated resources.
1102:             */
1103:            protected void finalize() throws Throwable {
1104:                super.finalize();
1105:            }
1106:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.