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


001:        /*
002:         * $RCSfile: FPXImage.java,v $
003:         *
004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * Use is subject to license terms.
007:         *
008:         * $Revision: 1.2 $
009:         * $Date: 2005/05/12 18:24:31 $
010:         * $State: Exp $
011:         */
012:        package com.sun.media.jai.codecimpl.fpx;
013:
014:        import java.awt.Point;
015:        import java.awt.RenderingHints;
016:        import java.awt.Transparency;
017:        import java.awt.color.ColorSpace;
018:        import java.awt.image.ColorModel;
019:        import java.awt.image.ComponentColorModel;
020:        import java.awt.image.DataBuffer;
021:        import java.awt.image.DataBufferByte;
022:        import java.awt.image.Raster;
023:        import java.awt.image.SampleModel;
024:        import java.awt.image.WritableRaster;
025:        import java.io.ByteArrayInputStream;
026:        import java.io.InputStream;
027:        import java.io.IOException;
028:        import java.util.Enumeration;
029:        import java.util.Hashtable;
030:        import com.sun.media.jai.codec.ImageCodec;
031:        import com.sun.media.jai.codec.FPXDecodeParam;
032:        import com.sun.media.jai.codec.SeekableStream;
033:        import com.sun.media.jai.codecimpl.SimpleRenderedImage;
034:        import com.sun.media.jai.codecimpl.util.RasterFactory;
035:
036:        import com.sun.image.codec.jpeg.JPEGCodec;
037:        import com.sun.image.codec.jpeg.JPEGDecodeParam;
038:        import com.sun.image.codec.jpeg.JPEGEncodeParam;
039:        import com.sun.image.codec.jpeg.JPEGImageDecoder;
040:        import com.sun.media.jai.codecimpl.ImagingListenerProxy;
041:        import com.sun.media.jai.codecimpl.util.ImagingException;
042:
043:        public class FPXImage extends SimpleRenderedImage {
044:
045:            private static final int SUBIMAGE_COLOR_SPACE_COLORLESS = 0;
046:            private static final int SUBIMAGE_COLOR_SPACE_MONOCHROME = 0;
047:            private static final int SUBIMAGE_COLOR_SPACE_PHOTOYCC = 0;
048:            private static final int SUBIMAGE_COLOR_SPACE_NIFRGB = 0;
049:            private static final String[] COLORSPACE_NAME = { "Colorless",
050:                    "Monochrome", "PhotoYCC", "NIF RGB" };
051:
052:            StructuredStorage storage;
053:
054:            int numResolutions;
055:            int highestResWidth;
056:            int highestResHeight;
057:            float defaultDisplayHeight;
058:            float defaultDisplayWidth;
059:            int displayHeightWidthUnits;
060:
061:            boolean[] subimageValid;
062:            int[] subimageWidth;
063:            int[] subimageHeight;
064:
065:            int[][] subimageColor;
066:
067:            // subimageNumericalFormat
068:            int[] decimationMethod;
069:            float[] decimationPrefilterWidth;
070:            // subimage ICC profile
071:
072:            int highestResolution = -1;
073:
074:            int maxJPEGTableIndex;
075:            byte[][] JPEGTable;
076:
077:            // Values from "Subimage 0000 Header" stream
078:            int numChannels;
079:            int tileHeaderTableOffset;
080:            int tileHeaderEntryLength;
081:
082:            // int[] tileOffset;
083:            // int[] tileSize;
084:            // int[] compressionType;
085:            // int[] compressionSubtype;
086:
087:            // The "Subimage 0000 Header" stream
088:            SeekableStream subimageHeaderStream;
089:
090:            // The "Subimage 0000 Data" stream
091:            SeekableStream subimageDataStream;
092:
093:            int resolution;
094:
095:            // Derived values
096:            int tilesAcross;
097:
098:            int[] bandOffsets = { 0, 1, 2 };
099:
100:            private static final int[] RGBBits8 = { 8, 8, 8 };
101:            private static final ComponentColorModel colorModelRGB8 = new ComponentColorModel(
102:                    ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), RGBBits8,
103:                    false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
104:
105:            public FPXImage(SeekableStream stream, FPXDecodeParam param)
106:                    throws IOException {
107:
108:                this .storage = new StructuredStorage(stream);
109:
110:                readImageContents();
111:                if (param == null) {
112:                    param = new FPXDecodeParam();
113:                }
114:                this .resolution = param.getResolution();
115:                readResolution();
116:
117:                bandOffsets = new int[numChannels];
118:                for (int i = 0; i < numChannels; i++) {
119:                    bandOffsets[i] = i;
120:                }
121:
122:                this .minX = 0;
123:                this .minY = 0;
124:
125:                this .sampleModel = RasterFactory
126:                        .createPixelInterleavedSampleModel(
127:                                DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
128:                                numChannels, numChannels * tileWidth,
129:                                bandOffsets);
130:                this .colorModel = ImageCodec
131:                        .createComponentColorModel(sampleModel);
132:            }
133:
134:            private void readImageContents() throws IOException {
135:                storage.changeDirectoryToRoot();
136:                storage.changeDirectory("Data Object Store 000001");
137:                SeekableStream imageContents = storage
138:                        .getStream("Image Contents");
139:
140:                PropertySet icps = new PropertySet(imageContents);
141:                this .numResolutions = (int) icps.getUI4(0x01000000);
142:                this .highestResWidth = (int) icps.getUI4(0x01000002);
143:                this .highestResHeight = (int) icps.getUI4(0x01000003);
144:                // this.defaultDisplayHeight = icps.getR4(0x01000004);
145:                // this.defaultDisplayWidth = icps.getR4(0x01000005);
146:
147:                this .displayHeightWidthUnits = (int) icps
148:                        .getUI4(0x01000006, 0L);
149:
150:                /*
151:                System.out.println("\nImage Contents Property Set:\n");
152:                System.out.println("  numResolutions = " + numResolutions);
153:                System.out.println("  highestResWidth = " + highestResWidth);
154:                System.out.println("  highestResHeight = " + highestResHeight);
155:                System.out.println();
156:                 */
157:
158:                this .subimageValid = new boolean[numResolutions];
159:                this .subimageWidth = new int[numResolutions];
160:                this .subimageHeight = new int[numResolutions];
161:                this .subimageColor = new int[numResolutions][];
162:                // subimageNumericalFormat
163:                this .decimationMethod = new int[numResolutions];
164:                this .decimationPrefilterWidth = new float[numResolutions];
165:                // subimage ICC profile
166:
167:                for (int i = 0; i < numResolutions; i++) {
168:                    int index = i << 16;
169:                    if (!icps.hasProperty(0x02000000 | index)) {
170:                        break;
171:                    }
172:
173:                    this .highestResolution = i;
174:                    subimageValid[i] = true;
175:                    subimageWidth[i] = (int) icps.getUI4(0x02000000 | index);
176:                    subimageHeight[i] = (int) icps.getUI4(0x02000001 | index);
177:                    byte[] subimageColorBlob = icps.getBlob(0x02000002 | index);
178:                    decimationMethod[i] = icps.getI4(0x02000004 | index);
179:                    // decimationPrefilterWidth[i] = icps.getR4(0x02000005 | index);
180:
181:                    int numSubImages = FPXUtils.getIntLE(subimageColorBlob, 0);
182:                    int numChannels = FPXUtils.getIntLE(subimageColorBlob, 4);
183:
184:                    // System.out.println("  subimageWidth[" + i + "] = " +
185:                    //                    subimageWidth[i]);
186:                    // System.out.println("  subimageHeight[" + i + "] = " +
187:                    //                    subimageHeight[i]);
188:                    // System.out.println("  subimageColor[" + i + "] = ");
189:                    // System.out.println("    numSubimages = " + numSubImages);
190:
191:                    subimageColor[i] = new int[numChannels];
192:                    for (int c = 0; c < numChannels; c++) {
193:                        int color = FPXUtils.getIntLE(subimageColorBlob,
194:                                8 + 4 * c);
195:                        //
196:                        // Mask off the most significant bit as the FlashPix
197:                        // specification states that:
198:                        //
199:                        // "If the most significant bit of the color space subfield
200:                        // is set, then the image channel definitions are that of the
201:                        // color space, but the image is not calibrated. [...] the
202:                        // setting of the uncalibrated bit shall not imply any
203:                        // different processing path."
204:                        //
205:                        subimageColor[i][c] = (color & 0x7fffffff);
206:                        // System.out.println("    channel " + c + " color space " +
207:                        //                    (color >> 16) +
208:                        //                    " (" + COLORSPACE_NAME[color >> 16] +")");
209:
210:                        // System.out.println("    channel " + c + " color type " +
211:                        //                    (color & 0x7fff));
212:                        // if ((color & 0x8000) != 0) {
213:                        //     System.out.println("    channel " + c + " has premultiplied opacity");
214:                        // }
215:                    }
216:
217:                    // System.out.println("  decimationMethod[" + i + "] = " +
218:                    //                    decimationMethod[i]);
219:                    // System.out.println();
220:                }
221:
222:                this .maxJPEGTableIndex = (int) icps.getUI4(0x03000002, -1L);
223:                // System.out.println("maxJPEGTableIndex = " + maxJPEGTableIndex);
224:                this .JPEGTable = new byte[maxJPEGTableIndex + 1][];
225:                for (int i = 0; i <= maxJPEGTableIndex; i++) {
226:                    int index = i << 16;
227:                    if (icps.hasProperty(0x03000001 | index)) {
228:                        // System.out.println("Found a table at index " + i);
229:                        this .JPEGTable[i] = icps.getBlob(0x03000001 | index);
230:                    } else {
231:                        // System.out.println("No table at index " + i);
232:                        this .JPEGTable[i] = null;
233:                    }
234:                }
235:            }
236:
237:            private void readResolution() throws IOException {
238:                if (resolution == -1) {
239:                    resolution = this .highestResolution;
240:                }
241:
242:                // System.out.println("Reading resolution " + resolution);
243:
244:                storage.changeDirectoryToRoot();
245:                storage.changeDirectory("Data Object Store 000001");
246:                storage.changeDirectory("Resolution 000" + resolution); // FIX
247:
248:                this .subimageHeaderStream = storage
249:                        .getStream("Subimage 0000 Header");
250:                subimageHeaderStream.skip(28);
251:                int headerLength = subimageHeaderStream.readIntLE();
252:                this .width = subimageHeaderStream.readIntLE();
253:                this .height = subimageHeaderStream.readIntLE();
254:                int numTiles = subimageHeaderStream.readIntLE();
255:                this .tileWidth = subimageHeaderStream.readIntLE();
256:                this .tileHeight = subimageHeaderStream.readIntLE();
257:                this .numChannels = subimageHeaderStream.readIntLE();
258:                this .tileHeaderTableOffset = subimageHeaderStream.readIntLE() + 28;
259:                this .tileHeaderEntryLength = subimageHeaderStream.readIntLE();
260:
261:                // System.out.println("\nResolution 000" + resolution + "\n");
262:                // System.out.println("Subimage 0000 Header:\n");
263:                // System.out.println("  headerLength = " + headerLength);
264:                // System.out.println("  width = " + width);
265:                // System.out.println("  height = " + height);
266:                // System.out.println("  numTiles = " + numTiles);
267:                // System.out.println("  tileWidth = " + tileWidth);
268:                // System.out.println("  tileHeight = " + tileHeight);
269:                // System.out.println("  numChannels = " + numChannels);
270:                // System.out.println("  tileHeaderTableOffset = " +
271:                //                    tileHeaderTableOffset);
272:                // System.out.println("  tileHeaderEntryLength = " +
273:                //                    tileHeaderEntryLength);
274:
275:                this .subimageDataStream = storage
276:                        .getStream("Subimage 0000 Data");
277:
278:                // Compute derived values
279:                tilesAcross = (width + tileWidth - 1) / tileWidth;
280:            }
281:
282:            private int getTileOffset(int tileIndex) throws IOException {
283:                // return tileOffset[tileIndex];
284:
285:                subimageHeaderStream.seek(tileHeaderTableOffset + 16
286:                        * tileIndex);
287:                return subimageHeaderStream.readIntLE() + 28;
288:            }
289:
290:            private int getTileSize(int tileIndex) throws IOException {
291:                // return tileSize[tileIndex];
292:
293:                subimageHeaderStream.seek(tileHeaderTableOffset + 16
294:                        * tileIndex + 4);
295:                return subimageHeaderStream.readIntLE();
296:            }
297:
298:            private int getCompressionType(int tileIndex) throws IOException {
299:                // return compressionType[tileIndex];
300:
301:                subimageHeaderStream.seek(tileHeaderTableOffset + 16
302:                        * tileIndex + 8);
303:                return subimageHeaderStream.readIntLE();
304:            }
305:
306:            private int getCompressionSubtype(int tileIndex) throws IOException {
307:                // return compressionSubtype[tileIndex];
308:
309:                subimageHeaderStream.seek(tileHeaderTableOffset + 16
310:                        * tileIndex + 12);
311:                return subimageHeaderStream.readIntLE();
312:            }
313:
314:            private static final byte[] PhotoYCCToRGBLUT = { (byte) 0,
315:                    (byte) 1, (byte) 1, (byte) 2, (byte) 2, (byte) 3, (byte) 4,
316:                    (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9,
317:                    (byte) 10, (byte) 11, (byte) 12, (byte) 13, (byte) 14,
318:                    (byte) 15, (byte) 16, (byte) 17, (byte) 18, (byte) 19,
319:                    (byte) 20, (byte) 22, (byte) 23, (byte) 24, (byte) 25,
320:                    (byte) 26, (byte) 28, (byte) 29, (byte) 30, (byte) 31,
321:
322:                    (byte) 33, (byte) 34, (byte) 35, (byte) 36, (byte) 38,
323:                    (byte) 39, (byte) 40, (byte) 41, (byte) 43, (byte) 44,
324:                    (byte) 45, (byte) 47, (byte) 48, (byte) 49, (byte) 51,
325:                    (byte) 52, (byte) 53, (byte) 55, (byte) 56, (byte) 57,
326:                    (byte) 59, (byte) 60, (byte) 61, (byte) 63, (byte) 64,
327:                    (byte) 65, (byte) 67, (byte) 68, (byte) 70, (byte) 71,
328:                    (byte) 72, (byte) 74,
329:
330:                    (byte) 75, (byte) 76, (byte) 78, (byte) 79, (byte) 81,
331:                    (byte) 82, (byte) 83, (byte) 85, (byte) 86, (byte) 88,
332:                    (byte) 89, (byte) 91, (byte) 92, (byte) 93, (byte) 95,
333:                    (byte) 96, (byte) 98, (byte) 99, (byte) 101, (byte) 102,
334:                    (byte) 103, (byte) 105, (byte) 106, (byte) 108, (byte) 109,
335:                    (byte) 111, (byte) 112, (byte) 113, (byte) 115, (byte) 116,
336:                    (byte) 118, (byte) 119,
337:
338:                    (byte) 121, (byte) 122, (byte) 123, (byte) 125, (byte) 126,
339:                    (byte) 128, (byte) 129, (byte) 130, (byte) 132, (byte) 133,
340:                    (byte) 134, (byte) 136, (byte) 137, (byte) 138, (byte) 140,
341:                    (byte) 141, (byte) 142, (byte) 144, (byte) 145, (byte) 146,
342:                    (byte) 148, (byte) 149, (byte) 150, (byte) 152, (byte) 153,
343:                    (byte) 154, (byte) 155, (byte) 157, (byte) 158, (byte) 159,
344:                    (byte) 160, (byte) 162,
345:
346:                    (byte) 163, (byte) 164, (byte) 165, (byte) 166, (byte) 168,
347:                    (byte) 169, (byte) 170, (byte) 171, (byte) 172, (byte) 174,
348:                    (byte) 175, (byte) 176, (byte) 177, (byte) 178, (byte) 179,
349:                    (byte) 180, (byte) 182, (byte) 183, (byte) 184, (byte) 185,
350:                    (byte) 186, (byte) 187, (byte) 188, (byte) 189, (byte) 190,
351:                    (byte) 191, (byte) 192, (byte) 194, (byte) 195, (byte) 196,
352:                    (byte) 197, (byte) 198,
353:
354:                    (byte) 199, (byte) 200, (byte) 201, (byte) 202, (byte) 203,
355:                    (byte) 204, (byte) 204, (byte) 205, (byte) 206, (byte) 207,
356:                    (byte) 208, (byte) 209, (byte) 210, (byte) 211, (byte) 212,
357:                    (byte) 213, (byte) 213, (byte) 214, (byte) 215, (byte) 216,
358:                    (byte) 217, (byte) 217, (byte) 218, (byte) 219, (byte) 220,
359:                    (byte) 221, (byte) 221, (byte) 222, (byte) 223, (byte) 223,
360:                    (byte) 224, (byte) 225,
361:
362:                    (byte) 225, (byte) 226, (byte) 227, (byte) 227, (byte) 228,
363:                    (byte) 229, (byte) 229, (byte) 230, (byte) 230, (byte) 231,
364:                    (byte) 231, (byte) 232, (byte) 233, (byte) 233, (byte) 234,
365:                    (byte) 234, (byte) 235, (byte) 235, (byte) 236, (byte) 236,
366:                    (byte) 236, (byte) 237, (byte) 237, (byte) 238, (byte) 238,
367:                    (byte) 238, (byte) 239, (byte) 239, (byte) 240, (byte) 240,
368:                    (byte) 240, (byte) 241,
369:
370:                    (byte) 241, (byte) 241, (byte) 242, (byte) 242, (byte) 242,
371:                    (byte) 242, (byte) 243, (byte) 243, (byte) 243, (byte) 244,
372:                    (byte) 244, (byte) 244, (byte) 244, (byte) 245, (byte) 245,
373:                    (byte) 245, (byte) 245, (byte) 245, (byte) 246, (byte) 246,
374:                    (byte) 246, (byte) 246, (byte) 246, (byte) 247, (byte) 247,
375:                    (byte) 247, (byte) 247, (byte) 247, (byte) 247, (byte) 248,
376:                    (byte) 248, (byte) 248,
377:
378:                    (byte) 248, (byte) 248, (byte) 248, (byte) 249, (byte) 249,
379:                    (byte) 249, (byte) 249, (byte) 249, (byte) 249, (byte) 249,
380:                    (byte) 249, (byte) 249, (byte) 250, (byte) 250, (byte) 250,
381:                    (byte) 250, (byte) 250, (byte) 250, (byte) 250, (byte) 250,
382:                    (byte) 250, (byte) 250, (byte) 251, (byte) 251, (byte) 251,
383:                    (byte) 251, (byte) 251, (byte) 251, (byte) 251, (byte) 251,
384:                    (byte) 251, (byte) 251,
385:
386:                    (byte) 251, (byte) 251, (byte) 251, (byte) 251, (byte) 252,
387:                    (byte) 252, (byte) 252, (byte) 252, (byte) 252, (byte) 252,
388:                    (byte) 252, (byte) 252, (byte) 252, (byte) 252, (byte) 252,
389:                    (byte) 252, (byte) 252, (byte) 252, (byte) 252, (byte) 252,
390:                    (byte) 252, (byte) 253, (byte) 253, (byte) 253, (byte) 253,
391:                    (byte) 253, (byte) 253, (byte) 253, (byte) 253, (byte) 253,
392:                    (byte) 253, (byte) 253,
393:
394:                    (byte) 253, (byte) 253, (byte) 253, (byte) 253, (byte) 253,
395:                    (byte) 253, (byte) 253, (byte) 254, (byte) 254, (byte) 254,
396:                    (byte) 254, (byte) 254, (byte) 254, (byte) 254, (byte) 254,
397:                    (byte) 254, (byte) 254, (byte) 254, (byte) 254, (byte) 254,
398:                    (byte) 254, (byte) 254, (byte) 255, (byte) 255, (byte) 255,
399:                    (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
400:                    (byte) 255, (byte) 255,
401:
402:                    (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
403:                    (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
404:
405:            private final byte PhotoYCCToNIFRed(float scaledY, float Cb,
406:                    float Cr) {
407:                float red = scaledY + 1.8215F * Cr - 249.55F;
408:                if (red < 0.0F) {
409:                    return (byte) 0;
410:                } else if (red > 360.0F) {
411:                    return (byte) 255;
412:                } else {
413:                    byte r = PhotoYCCToRGBLUT[(int) red];
414:                    return r;
415:                }
416:            }
417:
418:            private final byte PhotoYCCToNIFGreen(float scaledY, float Cb,
419:                    float Cr) {
420:                float green = scaledY - .43031F * Cb - .9271F * Cr + 194.14F;
421:                if (green < 0.0F) {
422:                    return (byte) 0;
423:                } else if (green > 360.0F) {
424:                    return (byte) 255;
425:                } else {
426:                    byte g = PhotoYCCToRGBLUT[(int) green];
427:                    return g;
428:                }
429:            }
430:
431:            private final byte PhotoYCCToNIFBlue(float scaledY, float Cb,
432:                    float Cr) {
433:                float blue = scaledY + 2.2179F * Cb - 345.99F;
434:                if (blue < 0.0F) {
435:                    return (byte) 0;
436:                } else if (blue > 360.0F) {
437:                    return (byte) 255;
438:                } else {
439:                    byte b = PhotoYCCToRGBLUT[(int) blue];
440:                    return b;
441:                }
442:            }
443:
444:            private final byte YCCToNIFRed(float Y, float Cb, float Cr) {
445:                float red = Y + 1.402F * Cr - (255.0F * .701F);
446:                if (red < 0.0F) {
447:                    return (byte) 0;
448:                } else if (red > 255.0F) {
449:                    return (byte) 255;
450:                } else {
451:                    return (byte) red;
452:                }
453:            }
454:
455:            private final byte YCCToNIFGreen(float Y, float Cb, float Cr) {
456:                float green = Y - .34414F * Cb - .71414F * Cr
457:                        + (255.0F * .52914F);
458:                if (green < 0.0F) {
459:                    return (byte) 0;
460:                } else if (green > 255.0F) {
461:                    return (byte) 255;
462:                } else {
463:                    return (byte) green;
464:                }
465:            }
466:
467:            private final byte YCCToNIFBlue(float Y, float Cb, float Cr) {
468:                float blue = Y + 1.772F * Cb - (255.0F * .886F);
469:                if (blue < 0.0F) {
470:                    return (byte) 0;
471:                } else if (blue > 255.0F) {
472:                    return (byte) 255;
473:                } else {
474:                    return (byte) blue;
475:                }
476:            }
477:
478:            private Raster getUncompressedTile(int tileX, int tileY)
479:                    throws IOException {
480:                int tx = tileXToX(tileX);
481:                int ty = tileYToY(tileY);
482:                Raster ras = RasterFactory.createInterleavedRaster(
483:                        DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
484:                        numChannels * tileWidth, numChannels, bandOffsets,
485:                        new Point(tx, ty));
486:                // System.out.println("Uncompressed tile.");
487:
488:                DataBufferByte dataBuffer = (DataBufferByte) ras
489:                        .getDataBuffer();
490:                byte[] data = dataBuffer.getData();
491:
492:                int tileIndex = tileY * tilesAcross + tileX;
493:                subimageDataStream.seek(getTileOffset(tileIndex));
494:                subimageDataStream.readFully(data, 0, numChannels * tileWidth
495:                        * tileHeight);
496:
497:                // Color convert if subimage is in PhotoYCC format
498:                if (subimageColor[resolution][0] >> 16 == 2) {
499:                    int size = tileWidth * tileHeight;
500:                    for (int i = 0; i < size; i++) {
501:                        float Y = data[3 * i] & 0xff;
502:                        float Cb = data[3 * i + 1] & 0xff;
503:                        float Cr = data[3 * i + 2] & 0xff;
504:
505:                        float scaledY = Y * 1.3584F;
506:                        byte red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
507:                        byte green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
508:                        byte blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
509:
510:                        data[3 * i] = red;
511:                        data[3 * i + 1] = green;
512:                        data[3 * i + 2] = blue;
513:                    }
514:                }
515:
516:                return ras;
517:            }
518:
519:            private Raster getSingleColorCompressedTile(int tileX, int tileY)
520:                    throws IOException {
521:                // System.out.println("Single color compressed tile.");
522:
523:                int tx = tileXToX(tileX);
524:                int ty = tileYToY(tileY);
525:                Raster ras = RasterFactory.createInterleavedRaster(
526:                        DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
527:                        numChannels * tileWidth, numChannels, bandOffsets,
528:                        new Point(tx, ty));
529:
530:                int subimageColorType = subimageColor[resolution][0] >> 16;
531:
532:                DataBufferByte dataBuffer = (DataBufferByte) ras
533:                        .getDataBuffer();
534:                byte[] data = dataBuffer.getData();
535:
536:                int tileIndex = tileY * tilesAcross + tileX;
537:                int color = getCompressionSubtype(tileIndex);
538:                byte c0 = (byte) ((color >> 0) & 0xff);
539:                byte c1 = (byte) ((color >> 8) & 0xff);
540:                byte c2 = (byte) ((color >> 16) & 0xff);
541:                byte alpha = (byte) ((color >> 24) & 0xff);
542:
543:                byte red, green, blue;
544:
545:                // Color convert if subimage is in PhotoYCC format
546:                if (subimageColor[resolution][0] >> 16 == 2) {
547:                    float Y = c0 & 0xff;
548:                    float Cb = c1 & 0xff;
549:                    float Cr = c2 & 0xff;
550:
551:                    float scaledY = Y * 1.3584F;
552:                    red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
553:                    green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
554:                    blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
555:                } else {
556:                    red = c0;
557:                    green = c1;
558:                    blue = c2;
559:                }
560:
561:                int index = 0;
562:                int pixels = tileWidth * tileHeight;
563:
564:                if (numChannels == 1) {
565:                } else if (numChannels == 2) {
566:                } else if (numChannels == 3) {
567:                    for (int i = 0; i < pixels; i++) {
568:                        data[index + 0] = red;
569:                        data[index + 1] = green;
570:                        data[index + 2] = blue;
571:
572:                        index += 3;
573:                    }
574:                } else if (numChannels == 4) {
575:                    for (int i = 0; i < pixels; i++) {
576:                        data[index + 0] = red;
577:                        data[index + 1] = green;
578:                        data[index + 2] = blue;
579:                        data[index + 3] = alpha;
580:
581:                        index += 4;
582:                    }
583:                }
584:
585:                return ras;
586:            }
587:
588:            private Raster getJPEGCompressedTile(int tileX, int tileY)
589:                    throws IOException {
590:                // System.out.println("JPEG compressed tile.");
591:
592:                int tileIndex = tileY * tilesAcross + tileX;
593:
594:                int tx = tileXToX(tileX);
595:                int ty = tileYToY(tileY);
596:
597:                int subtype = getCompressionSubtype(tileIndex);
598:                int interleave = (subtype >> 0) & 0xff;
599:                int chroma = (subtype >> 8) & 0xff;
600:                int conversion = (subtype >> 16) & 0xff;
601:                int table = (subtype >> 24) & 0xff;
602:
603:                JPEGImageDecoder dec;
604:                JPEGDecodeParam param = null;
605:
606:                if (table != 0) {
607:                    InputStream tableStream = new ByteArrayInputStream(
608:                            JPEGTable[table]);
609:                    dec = JPEGCodec.createJPEGDecoder(tableStream);
610:                    Raster junk = dec.decodeAsRaster();
611:                    param = dec.getJPEGDecodeParam();
612:                }
613:
614:                subimageDataStream.seek(getTileOffset(tileIndex));
615:                if (param != null) {
616:                    dec = JPEGCodec
617:                            .createJPEGDecoder(subimageDataStream, param);
618:                } else {
619:                    dec = JPEGCodec.createJPEGDecoder(subimageDataStream);
620:                }
621:                Raster ras = dec.decodeAsRaster().createTranslatedChild(tx, ty);
622:
623:                DataBufferByte dataBuffer = (DataBufferByte) ras
624:                        .getDataBuffer();
625:                byte[] data = dataBuffer.getData();
626:
627:                int subimageColorType = subimageColor[resolution][0] >> 16;
628:
629:                int size = tileWidth * tileHeight;
630:                if ((conversion == 0) && (subimageColorType == 2)) {
631:                    // System.out.println("Converting PhotoYCC to NIFRGB");
632:                    int offset = 0;
633:                    for (int i = 0; i < size; i++) {
634:                        float Y = data[offset] & 0xff;
635:                        float Cb = data[offset + 1] & 0xff;
636:                        float Cr = data[offset + 2] & 0xff;
637:
638:                        float scaledY = Y * 1.3584F;
639:                        byte red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
640:                        byte green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
641:                        byte blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
642:
643:                        data[offset] = red;
644:                        data[offset + 1] = green;
645:                        data[offset + 2] = blue;
646:
647:                        offset += numChannels;
648:                    }
649:                } else if ((conversion == 1) && (subimageColorType == 3)) {
650:                    // System.out.println("Converting YCC to NIFRGB");
651:                    int offset = 0;
652:                    for (int i = 0; i < size; i++) {
653:                        float Y = data[offset] & 0xff;
654:                        float Cb = data[offset + 1] & 0xff;
655:                        float Cr = data[offset + 2] & 0xff;
656:
657:                        byte red = YCCToNIFRed(Y, Cb, Cr);
658:                        byte green = YCCToNIFGreen(Y, Cb, Cr);
659:                        byte blue = YCCToNIFBlue(Y, Cb, Cr);
660:
661:                        data[offset] = red;
662:                        data[offset + 1] = green;
663:                        data[offset + 2] = blue;
664:
665:                        offset += numChannels;
666:                    }
667:                }
668:
669:                // Perform special inversion step when output space is
670:                // NIF RGB (subimageColorType == 3) with premultiplied opacity
671:                // (numChannels == 4).
672:                if ((conversion == 1) && (subimageColorType == 3)
673:                        && (numChannels == 4)) {
674:                    // System.out.println("Flipping NIFRGB");
675:
676:                    int offset = 0;
677:                    for (int i = 0; i < size; i++) {
678:                        data[offset + 0] = (byte) (255 - data[offset + 0]);
679:                        data[offset + 1] = (byte) (255 - data[offset + 1]);
680:                        data[offset + 2] = (byte) (255 - data[offset + 2]);
681:
682:                        offset += 4;
683:                    }
684:                }
685:
686:                return ras;
687:            }
688:
689:            public synchronized Raster getTile(int tileX, int tileY) {
690:                int tileIndex = tileY * tilesAcross + tileX;
691:
692:                try {
693:                    int ctype = getCompressionType(tileIndex);
694:                    if (ctype == 0) {
695:                        return getUncompressedTile(tileX, tileY);
696:                    } else if (ctype == 1) {
697:                        return getSingleColorCompressedTile(tileX, tileY);
698:                    } else if (ctype == 2) {
699:                        return getJPEGCompressedTile(tileX, tileY);
700:                    }
701:                    return null;
702:                } catch (IOException e) {
703:                    ImagingListenerProxy
704:                            .errorOccurred(JaiI18N.getString("FPXImage0"), e,
705:                                    ImageCodec.class, false);
706:                    //            e.printStackTrace();
707:                    return null;
708:                }
709:            }
710:
711:            Hashtable properties = null;
712:
713:            private void addLPSTRProperty(String name, PropertySet ps, int id) {
714:                String s = ps.getLPSTR(id);
715:                if (s != null) {
716:                    properties.put(name.toLowerCase(), s);
717:                }
718:            }
719:
720:            private void addLPWSTRProperty(String name, PropertySet ps, int id) {
721:                String s = ps.getLPWSTR(id);
722:                if (s != null) {
723:                    properties.put(name.toLowerCase(), s);
724:                }
725:            }
726:
727:            private void addUI4Property(String name, PropertySet ps, int id) {
728:                if (ps.hasProperty(id)) {
729:                    long i = ps.getUI4(id);
730:                    properties.put(name.toLowerCase(), new Integer((int) i));
731:                }
732:            }
733:
734:            private void getSummaryInformation() {
735:                SeekableStream summaryInformation = null;
736:                PropertySet sips = null;
737:                try {
738:                    storage.changeDirectoryToRoot();
739:                    summaryInformation = storage
740:                            .getStream("SummaryInformation");
741:                    sips = new PropertySet(summaryInformation);
742:                } catch (IOException e) {
743:                    ImagingListenerProxy
744:                            .errorOccurred(JaiI18N.getString("FPXImage1"), e,
745:                                    ImageCodec.class, false);
746:                    //            e.printStackTrace();
747:                    return;
748:                }
749:
750:                addLPSTRProperty("title", sips, 0x000000002);
751:                addLPSTRProperty("subject", sips, 0x000000003);
752:                addLPSTRProperty("author", sips, 0x000000004);
753:                addLPSTRProperty("keywords", sips, 0x000000005);
754:                addLPSTRProperty("comments", sips, 0x000000006);
755:                addLPSTRProperty("template", sips, 0x000000007);
756:                addLPSTRProperty("last saved by", sips, 0x000000008);
757:                addLPSTRProperty("revision number", sips, 0x000000009);
758:            }
759:
760:            private void getImageInfo() {
761:                SeekableStream imageInfo = null;
762:                PropertySet iips = null;
763:                try {
764:                    storage.changeDirectoryToRoot();
765:                    imageInfo = storage.getStream("Image Info");
766:                    if (imageInfo == null) {
767:                        return;
768:                    }
769:                    iips = new PropertySet(imageInfo);
770:                } catch (IOException e) {
771:                    ImagingListenerProxy
772:                            .errorOccurred(JaiI18N.getString("FPXImage2"), e,
773:                                    ImageCodec.class, false);
774:                    //            e.printStackTrace();
775:                    return;
776:                }
777:
778:                addUI4Property("file source", iips, 0x21000000);
779:                addUI4Property("scene type", iips, 0x21000001);
780:                // creation path vector
781:                addLPWSTRProperty("software name/manufacturer/release", iips,
782:                        0x21000003);
783:                addLPWSTRProperty("user defined id", iips, 0x21000004);
784:
785:                addLPWSTRProperty("copyright message", iips, 0x22000000);
786:                addLPWSTRProperty("legal broker for the original image", iips,
787:                        0x22000001);
788:                addLPWSTRProperty("legal broker for the digital image", iips,
789:                        0x22000002);
790:                addLPWSTRProperty("authorship", iips, 0x22000003);
791:                addLPWSTRProperty("intellectual property notes", iips,
792:                        0x22000004);
793:            }
794:
795:            private synchronized void getProperties() {
796:                if (properties != null) {
797:                    return;
798:                }
799:                properties = new Hashtable();
800:
801:                getSummaryInformation();
802:                getImageInfo();
803:
804:                // Ad hoc properties
805:                properties
806:                        .put("max_resolution", new Integer(highestResolution));
807:            }
808:
809:            public String[] getPropertyNames() {
810:                getProperties();
811:
812:                int len = properties.size();
813:                String[] names = new String[len];
814:                Enumeration enumeration = properties.keys();
815:
816:                int count = 0;
817:                while (enumeration.hasMoreElements()) {
818:                    names[count++] = (String) enumeration.nextElement();
819:                }
820:
821:                return names;
822:            }
823:
824:            public Object getProperty(String name) {
825:                getProperties();
826:                return properties.get(name.toLowerCase());
827:            }
828:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.