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


001:        /*
002:         * $RCSfile: SegmentedImageInputStream.java,v $
003:         *
004:         * 
005:         * Copyright (c) 2005 Sun Microsystems, Inc. All  Rights Reserved.
006:         * 
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met: 
010:         * 
011:         * - Redistribution of source code must retain the above copyright 
012:         *   notice, this  list of conditions and the following disclaimer.
013:         * 
014:         * - Redistribution in binary form must reproduce the above copyright
015:         *   notice, this list of conditions and the following disclaimer in 
016:         *   the documentation and/or other materials provided with the
017:         *   distribution.
018:         * 
019:         * Neither the name of Sun Microsystems, Inc. or the names of 
020:         * contributors may be used to endorse or promote products derived 
021:         * from this software without specific prior written permission.
022:         * 
023:         * This software is provided "AS IS," without a warranty of any 
024:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 
025:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 
026:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027:         * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 
028:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
029:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 
031:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035:         * POSSIBILITY OF SUCH DAMAGES. 
036:         * 
037:         * You acknowledge that this software is not designed or intended for 
038:         * use in the design, construction, operation or maintenance of any 
039:         * nuclear facility. 
040:         *
041:         * $Revision: 1.2 $
042:         * $Date: 2007/08/28 01:12:56 $
043:         * $State: Exp $
044:         */
045:        package com.sun.media.imageio.stream;
046:
047:        import java.io.IOException;
048:        import javax.imageio.stream.ImageInputStream;
049:        import javax.imageio.stream.ImageInputStreamImpl;
050:
051:        /**
052:         * An implementation of the <code>StreamSegmentMapper</code> interface
053:         * that requires an explicit list of the starting locations and
054:         * lengths of the source segments.
055:         */
056:        class StreamSegmentMapperImpl implements  StreamSegmentMapper {
057:
058:            private long[] segmentPositions;
059:
060:            private int[] segmentLengths;
061:
062:            public StreamSegmentMapperImpl(long[] segmentPositions,
063:                    int[] segmentLengths) {
064:                this .segmentPositions = (long[]) segmentPositions.clone();
065:                this .segmentLengths = (int[]) segmentLengths.clone();
066:            }
067:
068:            public StreamSegment getStreamSegment(long position, int length) {
069:                int numSegments = segmentLengths.length;
070:                for (int i = 0; i < numSegments; i++) {
071:                    int len = segmentLengths[i];
072:                    if (position < len) {
073:                        return new StreamSegment(
074:                                segmentPositions[i] + position, Math.min(len
075:                                        - (int) position, length));
076:                    }
077:                    position -= len;
078:                }
079:
080:                return null;
081:            }
082:
083:            public void getStreamSegment(long position, int length,
084:                    StreamSegment seg) {
085:                int numSegments = segmentLengths.length;
086:                for (int i = 0; i < numSegments; i++) {
087:                    int len = segmentLengths[i];
088:                    if (position < len) {
089:                        seg.setStartPos(segmentPositions[i] + position);
090:                        seg.setSegmentLength(Math.min(len - (int) position,
091:                                length));
092:                        return;
093:                    }
094:                    position -= len;
095:                }
096:
097:                seg.setStartPos(-1);
098:                seg.setSegmentLength(-1);
099:                return;
100:            }
101:
102:            long length() {
103:                int numSegments = segmentLengths.length;
104:                long len = 0L;
105:
106:                for (int i = 0; i < numSegments; i++) {
107:                    len += segmentLengths[i];
108:                }
109:
110:                return len;
111:            }
112:        }
113:
114:        /**
115:         * An implementation of the <code>StreamSegmentMapper</code> interface
116:         * for segments of equal length.
117:         */
118:        class SectorStreamSegmentMapper implements  StreamSegmentMapper {
119:
120:            long[] segmentPositions;
121:            int segmentLength;
122:            int totalLength;
123:            int lastSegmentLength;
124:
125:            public SectorStreamSegmentMapper(long[] segmentPositions,
126:                    int segmentLength, int totalLength) {
127:                this .segmentPositions = (long[]) segmentPositions.clone();
128:                this .segmentLength = segmentLength;
129:                this .totalLength = totalLength;
130:                this .lastSegmentLength = totalLength
131:                        - (segmentPositions.length - 1) * segmentLength;
132:            }
133:
134:            public StreamSegment getStreamSegment(long position, int length) {
135:                int index = (int) (position / segmentLength);
136:
137:                // Compute segment length
138:                int len = (index == segmentPositions.length - 1) ? lastSegmentLength
139:                        : segmentLength;
140:
141:                // Compute position within the segment
142:                position -= index * segmentLength;
143:
144:                // Compute maximum legal length
145:                len -= position;
146:                if (len > length) {
147:                    len = length;
148:                }
149:                return new StreamSegment(segmentPositions[index] + position,
150:                        len);
151:            }
152:
153:            public void getStreamSegment(long position, int length,
154:                    StreamSegment seg) {
155:                int index = (int) (position / segmentLength);
156:
157:                // Compute segment length
158:                int len = (index == segmentPositions.length - 1) ? lastSegmentLength
159:                        : segmentLength;
160:
161:                // Compute position within the segment
162:                position -= index * segmentLength;
163:
164:                // Compute maximum legal length
165:                len -= position;
166:                if (len > length) {
167:                    len = length;
168:                }
169:
170:                seg.setStartPos(segmentPositions[index] + position);
171:                seg.setSegmentLength(len);
172:            }
173:
174:            long length() {
175:                return (long) totalLength;
176:            }
177:        }
178:
179:        /**
180:         * A <code>SegmentedImageInputStream</code> provides a view of a
181:         * subset of another <code>ImageInputStream</code> consiting of a series
182:         * of segments with given starting positions in the source stream and
183:         * lengths.  The resulting stream behaves like an ordinary
184:         * <code>ImageInputStream</code>.
185:         *
186:         * <p> For example, given a <code>ImageInputStream</code> containing
187:         * data in a format consisting of a number of sub-streams stored in
188:         * non-contiguous sectors indexed by a directory, it is possible to
189:         * construct a set of <code>SegmentedImageInputStream</code>s, one for
190:         * each sub-stream, that each provide a view of the sectors comprising
191:         * a particular stream by providing the positions and lengths of the
192:         * stream's sectors as indicated by the directory.  The complex
193:         * multi-stream structure of the original stream may be ignored by
194:         * users of the <code>SegmentedImageInputStream</code>, who see a
195:         * separate <code>ImageInputStream</code> for each sub-stream and do not
196:         * need to understand the directory structure at all.
197:         *
198:         * <p> For further efficiency, a directory structure such as in the
199:         * example described above need not be fully parsed in order to build
200:         * a <code>SegmentedImageInputStream</code>.  Instead, the
201:         * <code>StreamSegmentMapper</code> interface allows the association
202:         * between a desired region of the output and an input segment to be
203:         * provided dynamically.  This mapping might be computed by reading
204:         * from a directory in piecemeal fashion in order to avoid consuming
205:         * memory resources.
206:         */
207:        public class SegmentedImageInputStream extends ImageInputStreamImpl {
208:
209:            private ImageInputStream stream;
210:            private StreamSegmentMapper mapper;
211:
212:            /**
213:             * Constructs a <code>SegmentedImageInputStream</code>
214:             * given a <code>ImageInputStream</code> as input
215:             * and an instance of <code>StreamSegmentMapper</code>.
216:             *
217:             * @param stream A source <code>ImageInputStream</code>
218:             * @param mapper An instance of the <code>StreamSegmentMapper</code>
219:             *        interface.
220:             */
221:            public SegmentedImageInputStream(ImageInputStream stream,
222:                    StreamSegmentMapper mapper) {
223:                super ();
224:
225:                this .stream = stream;
226:                this .mapper = mapper;
227:            }
228:
229:            /**
230:             * Constructs a <code>SegmentedImageInputStream</code> given a
231:             * <code>ImageInputStream</code> as input and a list of the starting
232:             * positions and lengths of the segments of the source stream.
233:             *
234:             * @param stream A source <code>ImageInputStream</code>
235:             * @param segmentPositions An array of <code>long</code>s 
236:             *        giving the starting positions of the segments in the
237:             *        source stream.
238:             * @param segmentLengths  An array of <code>int</code>s 
239:             *        giving the lengths of segments in the source stream.
240:             */
241:            public SegmentedImageInputStream(ImageInputStream stream,
242:                    long[] segmentPositions, int[] segmentLengths) {
243:                this (stream, new StreamSegmentMapperImpl(segmentPositions,
244:                        segmentLengths));
245:            }
246:
247:            /**
248:             * Constructs a <code>SegmentedImageInputStream</code> given a
249:             * <code>ImageInputStream</code> as input, a list of the starting
250:             * positions of the segments of the source stream, the common
251:             * length of each segment, and the total length of the segments.
252:             *
253:             * <p> This constructor is useful for selecting substreams
254:             *     of sector-oriented file formats in which each segment
255:             *     of the substream (except possibly the final segment)
256:             *     occupies a fixed-length sector.
257:             *
258:             * @param stream A source <code>ImageInputStream</code>
259:             * @param segmentPositions An array of <code>long</code>s 
260:             *        giving the starting positions of the segments in the
261:             *        source stream.
262:             * @param segmentLength  The common length of each segment.
263:             * @param totalLength  The total length of the source segments.
264:             */
265:            public SegmentedImageInputStream(ImageInputStream stream,
266:                    long[] segmentPositions, int segmentLength, int totalLength) {
267:                this (stream, new SectorStreamSegmentMapper(segmentPositions,
268:                        segmentLength, totalLength));
269:            }
270:
271:            private StreamSegment streamSegment = new StreamSegment();
272:
273:            /**
274:             * Reads the next byte of data from the input stream. The value byte is
275:             * returned as an <code>int</code> in the range <code>0</code> to
276:             * <code>255</code>. If no byte is available because the end of the stream
277:             * has been reached, the value <code>-1</code> is returned. This method
278:             * blocks until input data is available, the end of the stream is detected,
279:             * or an exception is thrown.
280:             *
281:             * @return     the next byte of data, or <code>-1</code> if the end of the
282:             *             stream is reached.
283:             * @exception  IOException  if an I/O error occurs.
284:             */
285:            public int read() throws IOException {
286:                mapper.getStreamSegment(streamPos, 1, streamSegment);
287:                int streamSegmentLength = streamSegment.getSegmentLength();
288:                if (streamSegmentLength < 0) {
289:                    return -1;
290:                }
291:                stream.seek(streamSegment.getStartPos());
292:
293:                // XXX What happens if streamSegmentLength == 0? Should this
294:                // method also return -1 as above for streamSegmentLength < 0?
295:                int val = stream.read();
296:                ++streamPos;
297:                return val;
298:            }
299:
300:            /**
301:             * Reads up to <code>len</code> bytes of data from the input stream into
302:             * an array of bytes.  An attempt is made to read as many as
303:             * <code>len</code> bytes, but a smaller number may be read, possibly
304:             * zero. The number of bytes actually read is returned as an integer.
305:             *
306:             * <p> This method blocks until input data is available, end of stream is
307:             * detected, or an exception is thrown.
308:             *
309:             * <p> If <code>b</code> is <code>null</code>, a
310:             * <code>NullPointerException</code> is thrown.
311:             *
312:             * <p> If <code>off</code> is negative, or <code>len</code> is negative, or
313:             * <code>off+len</code> is greater than the length of the array
314:             * <code>b</code>, then an <code>IndexOutOfBoundsException</code> is
315:             * thrown.
316:             *
317:             * <p> If <code>len</code> is zero, then no bytes are read and
318:             * <code>0</code> is returned; otherwise, there is an attempt to read at
319:             * least one byte. If no byte is available because the stream is at end of
320:             * stream, the value <code>-1</code> is returned; otherwise, at least one
321:             * byte is read and stored into <code>b</code>.
322:             *
323:             * <p> The first byte read is stored into element <code>b[off]</code>, the
324:             * next one into <code>b[off+1]</code>, and so on. The number of bytes read
325:             * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
326:             * bytes actually read; these bytes will be stored in elements
327:             * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
328:             * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
329:             * <code>b[off+len-1]</code> unaffected.
330:             *
331:             * <p> In every case, elements <code>b[0]</code> through
332:             * <code>b[off]</code> and elements <code>b[off+len]</code> through
333:             * <code>b[b.length-1]</code> are unaffected.
334:             *
335:             * <p> If the first byte cannot be read for any reason other than end of
336:             * stream, then an <code>IOException</code> is thrown. In particular, an
337:             * <code>IOException</code> is thrown if the input stream has been closed.
338:             *
339:             * @param      b     the buffer into which the data is read.
340:             * @param      off   the start offset in array <code>b</code>
341:             *                   at which the data is written.
342:             * @param      len   the maximum number of bytes to read.
343:             * @return     the total number of bytes read into the buffer, or
344:             *             <code>-1</code> if there is no more data because the end of
345:             *             the stream has been reached.
346:             * @exception  IOException  if an I/O error occurs.
347:             */
348:            public int read(byte[] b, int off, int len) throws IOException {
349:                if (b == null) {
350:                    throw new NullPointerException();
351:                }
352:                if ((off < 0) || (len < 0) || (off + len > b.length)) {
353:                    throw new IndexOutOfBoundsException();
354:                }
355:                if (len == 0) {
356:                    return 0;
357:                }
358:
359:                mapper.getStreamSegment(streamPos, len, streamSegment);
360:                int streamSegmentLength = streamSegment.getSegmentLength();
361:                if (streamSegmentLength < 0) {
362:                    return -1;
363:                }
364:                stream.seek(streamSegment.getStartPos());
365:
366:                int nbytes = stream.read(b, off, streamSegmentLength);
367:                streamPos += nbytes;
368:                return nbytes;
369:            }
370:
371:            public long length() {
372:                long len;
373:                if (mapper instanceof  StreamSegmentMapperImpl) {
374:                    len = ((StreamSegmentMapperImpl) mapper).length();
375:                } else if (mapper instanceof  SectorStreamSegmentMapper) {
376:                    len = ((SectorStreamSegmentMapper) mapper).length();
377:                } else if (mapper != null) {
378:                    long pos = len = 0L;
379:                    StreamSegment seg = mapper.getStreamSegment(pos,
380:                            Integer.MAX_VALUE);
381:                    while ((len = seg.getSegmentLength()) > 0) {
382:                        pos += len;
383:                        seg.setSegmentLength(0);
384:                        mapper.getStreamSegment(pos, Integer.MAX_VALUE, seg);
385:                    }
386:                    len = pos;
387:                } else {
388:                    len = super.length();
389:                }
390:
391:                return len;
392:            }
393:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.