Source Code Cross Referenced for SegmentedSeekableStream.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » jai » codec » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » com.sun.media.jai.codec 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: SegmentedSeekableStream.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.1 $
009:         * $Date: 2005/02/11 04:55:33 $
010:         * $State: Exp $
011:         */
012:        package com.sun.media.jai.codec;
013:
014:        import java.io.IOException;
015:
016:        /**
017:         * An implementation of the <code>StreamSegmentMapper</code> interface
018:         * that requires an explicit list of the starting locations and
019:         * lengths of the source segments.
020:         */
021:        class StreamSegmentMapperImpl implements  StreamSegmentMapper {
022:
023:            private long[] segmentPositions;
024:
025:            private int[] segmentLengths;
026:
027:            public StreamSegmentMapperImpl(long[] segmentPositions,
028:                    int[] segmentLengths) {
029:                this .segmentPositions = (long[]) segmentPositions.clone();
030:                this .segmentLengths = (int[]) segmentLengths.clone();
031:            }
032:
033:            public StreamSegment getStreamSegment(long position, int length) {
034:                int numSegments = segmentLengths.length;
035:                for (int i = 0; i < numSegments; i++) {
036:                    int len = segmentLengths[i];
037:                    if (position < len) {
038:                        return new StreamSegment(
039:                                segmentPositions[i] + position, Math.min(len
040:                                        - (int) position, length));
041:                    }
042:                    position -= len;
043:                }
044:
045:                return null;
046:            }
047:
048:            public void getStreamSegment(long position, int length,
049:                    StreamSegment seg) {
050:                int numSegments = segmentLengths.length;
051:                for (int i = 0; i < numSegments; i++) {
052:                    int len = segmentLengths[i];
053:                    if (position < len) {
054:                        seg.setStartPos(segmentPositions[i] + position);
055:                        seg.setSegmentLength(Math.min(len - (int) position,
056:                                length));
057:                        return;
058:                    }
059:                    position -= len;
060:                }
061:
062:                seg.setStartPos(-1);
063:                seg.setSegmentLength(-1);
064:                return;
065:            }
066:        }
067:
068:        /**
069:         * An implementation of the <code>StreamSegmentMapper</code> interface
070:         * for segments of equal length.
071:         */
072:        class SectorStreamSegmentMapper implements  StreamSegmentMapper {
073:
074:            long[] segmentPositions;
075:            int segmentLength;
076:            int totalLength;
077:            int lastSegmentLength;
078:
079:            public SectorStreamSegmentMapper(long[] segmentPositions,
080:                    int segmentLength, int totalLength) {
081:                this .segmentPositions = (long[]) segmentPositions.clone();
082:                this .segmentLength = segmentLength;
083:                this .totalLength = totalLength;
084:                this .lastSegmentLength = totalLength
085:                        - (segmentPositions.length - 1) * segmentLength;
086:            }
087:
088:            public StreamSegment getStreamSegment(long position, int length) {
089:                int index = (int) (position / segmentLength);
090:
091:                // Compute segment length
092:                int len = (index == segmentPositions.length - 1) ? lastSegmentLength
093:                        : segmentLength;
094:
095:                // Compute position within the segment
096:                position -= index * segmentLength;
097:
098:                // Compute maximum legal length
099:                len -= position;
100:                if (len > length) {
101:                    len = length;
102:                }
103:                return new StreamSegment(segmentPositions[index] + position,
104:                        len);
105:            }
106:
107:            public void getStreamSegment(long position, int length,
108:                    StreamSegment seg) {
109:                int index = (int) (position / segmentLength);
110:
111:                // Compute segment length
112:                int len = (index == segmentPositions.length - 1) ? lastSegmentLength
113:                        : segmentLength;
114:
115:                // Compute position within the segment
116:                position -= index * segmentLength;
117:
118:                // Compute maximum legal length
119:                len -= position;
120:                if (len > length) {
121:                    len = length;
122:                }
123:
124:                seg.setStartPos(segmentPositions[index] + position);
125:                seg.setSegmentLength(len);
126:            }
127:        }
128:
129:        /**
130:         * A <code>SegmentedSeekableStream</code> provides a view of a
131:         * subset of another <code>SeekableStream</code> consiting of a series
132:         * of segments with given starting positions in the source stream and
133:         * lengths.  The resulting stream behaves like an ordinary
134:         * <code>SeekableStream</code>.
135:         *
136:         * <p> For example, given a <code>SeekableStream</code> containing
137:         * data in a format consisting of a number of sub-streams stored in
138:         * non-contiguous sectors indexed by a directory, it is possible to
139:         * construct a set of <code>SegmentedSeekableStream</code>s, one for
140:         * each sub-stream, that each provide a view of the sectors comprising
141:         * a particular stream by providing the positions and lengths of the
142:         * stream's sectors as indicated by the directory.  The complex
143:         * multi-stream structure of the original stream may be ignored by
144:         * users of the <code>SegmentedSeekableStream</code>, who see a
145:         * separate <code>SeekableStream</code> for each sub-stream and do not
146:         * need to understand the directory structure at all.
147:         *
148:         * <p> For further efficiency, a directory structure such as in the
149:         * example described above need not be fully parsed in order to build
150:         * a <code>SegmentedSeekableStream</code>.  Instead, the
151:         * <code>StreamSegmentMapper</code> interface allows the association
152:         * between a desired region of the output and an input segment to be
153:         * provided dynamically.  This mapping might be computed by reading
154:         * from a directory in piecemeal fashion in order to avoid consuming
155:         * memory resources.
156:         *
157:         * <p> It is the responsibility of the user of this class to determine
158:         * whether backwards seeking should be enabled.  If the source stream
159:         * supports only forward seeking, backwards seeking must be disabled
160:         * and the <code>StreamSegmentMapper</code> must be monotone; that is,
161:         * forward motion in the destination must always result in forward
162:         * motion within the source.  If the source stream supports backwards
163:         * seeking, there are no restrictions on the
164:         * <code>StreamSegmentMapper</code> and backwards seeking may always
165:         * be enabled for the <code>SegmentedSeekableStream</code>.
166:         *
167:         * <p><b> This class is not a committed part of the JAI API.  It may
168:         * be removed or changed in future releases of JAI.</b>
169:         */
170:        public class SegmentedSeekableStream extends SeekableStream {
171:
172:            private SeekableStream stream;
173:            private StreamSegmentMapper mapper;
174:            private long pointer = 0;
175:            private boolean canSeekBackwards;
176:
177:            /**
178:             * Constructs a <code>SegmentedSeekableStream</code>
179:             * given a <code>SeekableStream</code> as input,
180:             * an instance of <code>StreamSegmentMapper</code>,
181:             * and a <code>boolean</code> indicating whether the
182:             * output <code>SegmentedSeekableStream</code> should
183:             * support seeking backwards.  If <code>canSeekBackwards</code>
184:             * is <code>true</code>, the source stream must itself
185:             * support seeking backwards.
186:             *
187:             * @param stream A source <code>SeekableStream</code>
188:             * @param mapper An instance of the <code>StreamSegmentMapper</code>
189:             *        interface.
190:             * @param canSeekBackwards <code>true</code> if the ability to
191:             *        seek backwards is desired.   
192:             */
193:            public SegmentedSeekableStream(SeekableStream stream,
194:                    StreamSegmentMapper mapper, boolean canSeekBackwards) {
195:                this .stream = stream;
196:                this .mapper = mapper;
197:                this .canSeekBackwards = canSeekBackwards;
198:
199:                if (canSeekBackwards && !stream.canSeekBackwards()) {
200:                    throw new IllegalArgumentException(JaiI18N
201:                            .getString("SegmentedSeekableStream0"));
202:                }
203:            }
204:
205:            /**
206:             * Constructs a <code>SegmentedSeekableStream</code> given a
207:             * <code>SeekableStream</code> as input, a list of the starting
208:             * positions and lengths of the segments of the source stream, and
209:             * a <code>boolean</code> indicating whether the output
210:             * <code>SegmentedSeekableStream</code> should support seeking
211:             * backwards.  If <code>canSeekBakckwards</code> is
212:             * <code>true</code>, the source stream must itself support
213:             * seeking backwards.
214:             *
215:             * @param stream A source <code>SeekableStream</code>
216:             * @param segmentPositions An array of <code>long</code>s 
217:             *        giving the starting positions of the segments in the
218:             *        source stream.
219:             * @param segmentLengths  An array of <code>int</code>s 
220:             *        giving the lengths of segments in the source stream.
221:             * @param canSeekBackwards <code>true</code> if the ability to
222:             *        seek backwards is desired.
223:             */
224:            public SegmentedSeekableStream(SeekableStream stream,
225:                    long[] segmentPositions, int[] segmentLengths,
226:                    boolean canSeekBackwards) {
227:                this (stream, new StreamSegmentMapperImpl(segmentPositions,
228:                        segmentLengths), canSeekBackwards);
229:            }
230:
231:            /**
232:             * Constructs a <code>SegmentedSeekableStream</code> given a
233:             * <code>SeekableStream</code> as input, a list of the starting
234:             * positions of the segments of the source stream, the common
235:             * length of each segment, the total length of the segments and
236:             * a <code>boolean</code> indicating whether the output
237:             * <code>SegmentedSeekableStream</code> should support seeking
238:             * backwards.  If <code>canSeekBakckwards</code> is
239:             * <code>true</code>, the source stream must itself support
240:             * seeking backwards.
241:             *
242:             * <p> This constructor is useful for selecting substreams
243:             *     of sector-oriented file formats in which each segment
244:             *     of the substream (except possibly the final segment)
245:             *     occupies a fixed-length sector.
246:             *
247:             * @param stream A source <code>SeekableStream</code>
248:             * @param segmentPositions An array of <code>long</code>s 
249:             *        giving the starting positions of the segments in the
250:             *        source stream.
251:             * @param segmentLength  The common length of each segment.
252:             * @param totalLength  The total length of the source segments.
253:             * @param canSeekBackwards <code>true</code> if the ability to
254:             *        seek backwards is desired.
255:             */
256:            public SegmentedSeekableStream(SeekableStream stream,
257:                    long[] segmentPositions, int segmentLength,
258:                    int totalLength, boolean canSeekBackwards) {
259:                this (stream, new SectorStreamSegmentMapper(segmentPositions,
260:                        segmentLength, totalLength), canSeekBackwards);
261:            }
262:
263:            /**
264:             * Returns the current offset in this stream.
265:             *
266:             * @return     the offset from the beginning of the stream, in bytes,
267:             *             at which the next read occurs.
268:             */
269:            public long getFilePointer() {
270:                return (long) pointer;
271:            }
272:
273:            /**
274:             * Returns <code>true</code> if seeking backwards is supported.
275:             * Support is determined by the value of the
276:             * <code>canSeekBackwards</code> parameter at construction time.
277:             */
278:            public boolean canSeekBackwards() {
279:                return canSeekBackwards;
280:            }
281:
282:            /**
283:             * Sets the offset, measured from the beginning of this 
284:             * stream, at which the next read occurs.
285:             *
286:             * <p> If <code>canSeekBackwards()</code> returns <code>false</code>,
287:             * then setting <code>pos</code> to an offset smaller than
288:             * the current value of <code>getFilePointer()</code> will have
289:             * no effect.
290:             *
291:             * @param      pos   the offset position, measured in bytes from the 
292:             *                   beginning of the stream, at which to set the stream 
293:             *                   pointer.
294:             * @exception  IOException  if <code>pos</code> is less than 
295:             *                          <code>0</code> or if an I/O error occurs.
296:             */
297:            public void seek(long pos) throws IOException {
298:                if (pos < 0) {
299:                    throw new IOException();
300:                }
301:                pointer = pos;
302:            }
303:
304:            private StreamSegment streamSegment = new StreamSegment();
305:
306:            /**
307:             * Reads the next byte of data from the input stream. The value byte is
308:             * returned as an <code>int</code> in the range <code>0</code> to
309:             * <code>255</code>. If no byte is available because the end of the stream
310:             * has been reached, the value <code>-1</code> is returned. This method
311:             * blocks until input data is available, the end of the stream is detected,
312:             * or an exception is thrown.
313:             *
314:             * @return     the next byte of data, or <code>-1</code> if the end of the
315:             *             stream is reached.
316:             * @exception  IOException  if an I/O error occurs.
317:             */
318:            public int read() throws IOException {
319:                mapper.getStreamSegment(pointer, 1, streamSegment);
320:                stream.seek(streamSegment.getStartPos());
321:
322:                int val = stream.read();
323:                ++pointer;
324:                return val;
325:            }
326:
327:            /**
328:             * Reads up to <code>len</code> bytes of data from the input stream into
329:             * an array of bytes.  An attempt is made to read as many as
330:             * <code>len</code> bytes, but a smaller number may be read, possibly
331:             * zero. The number of bytes actually read is returned as an integer.
332:             *
333:             * <p> This method blocks until input data is available, end of stream is
334:             * detected, or an exception is thrown.
335:             *
336:             * <p> If <code>b</code> is <code>null</code>, a
337:             * <code>NullPointerException</code> is thrown.
338:             *
339:             * <p> If <code>off</code> is negative, or <code>len</code> is negative, or
340:             * <code>off+len</code> is greater than the length of the array
341:             * <code>b</code>, then an <code>IndexOutOfBoundsException</code> is
342:             * thrown.
343:             *
344:             * <p> If <code>len</code> is zero, then no bytes are read and
345:             * <code>0</code> is returned; otherwise, there is an attempt to read at
346:             * least one byte. If no byte is available because the stream is at end of
347:             * stream, the value <code>-1</code> is returned; otherwise, at least one
348:             * byte is read and stored into <code>b</code>.
349:             *
350:             * <p> The first byte read is stored into element <code>b[off]</code>, the
351:             * next one into <code>b[off+1]</code>, and so on. The number of bytes read
352:             * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
353:             * bytes actually read; these bytes will be stored in elements
354:             * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
355:             * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
356:             * <code>b[off+len-1]</code> unaffected.
357:             *
358:             * <p> In every case, elements <code>b[0]</code> through
359:             * <code>b[off]</code> and elements <code>b[off+len]</code> through
360:             * <code>b[b.length-1]</code> are unaffected.
361:             *
362:             * <p> If the first byte cannot be read for any reason other than end of
363:             * stream, then an <code>IOException</code> is thrown. In particular, an
364:             * <code>IOException</code> is thrown if the input stream has been closed.
365:             *
366:             * @param      b     the buffer into which the data is read.
367:             * @param      off   the start offset in array <code>b</code>
368:             *                   at which the data is written.
369:             * @param      len   the maximum number of bytes to read.
370:             * @return     the total number of bytes read into the buffer, or
371:             *             <code>-1</code> if there is no more data because the end of
372:             *             the stream has been reached.
373:             * @exception  IOException  if an I/O error occurs.
374:             */
375:            public int read(byte[] b, int off, int len) throws IOException {
376:                if (b == null) {
377:                    throw new NullPointerException();
378:                }
379:                if ((off < 0) || (len < 0) || (off + len > b.length)) {
380:                    throw new IndexOutOfBoundsException();
381:                }
382:                if (len == 0) {
383:                    return 0;
384:                }
385:
386:                mapper.getStreamSegment(pointer, len, streamSegment);
387:                stream.seek(streamSegment.getStartPos());
388:
389:                int nbytes = stream.read(b, off, streamSegment
390:                        .getSegmentLength());
391:                pointer += nbytes;
392:                return nbytes;
393:            }
394:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.