001: /*******************************************************************************
002: * Copyright (c) 2000, 2003 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.internal.image;
011:
012: import java.io.*;
013:
014: final class TIFFRandomFileAccess {
015:
016: LEDataInputStream inputStream;
017: int start, current, next;
018: byte[][] buffers;
019:
020: static final int CHUNK_SIZE = 8192;
021: static final int LIST_SIZE = 128;
022:
023: public TIFFRandomFileAccess(LEDataInputStream stream) {
024: inputStream = stream;
025: start = current = next = inputStream.getPosition();
026: buffers = new byte[LIST_SIZE][];
027: }
028:
029: void seek(int pos) throws IOException {
030: if (pos == current)
031: return;
032: if (pos < start)
033: throw new IOException();
034: current = pos;
035: if (current > next) {
036: int n = current - next;
037: /* store required bytes */
038: int index = next / CHUNK_SIZE;
039: int offset = next % CHUNK_SIZE;
040: while (n > 0) {
041: if (index >= buffers.length) {
042: byte[][] oldBuffers = buffers;
043: buffers = new byte[Math.max(index + 1,
044: oldBuffers.length + LIST_SIZE)][];
045: System.arraycopy(oldBuffers, 0, buffers, 0,
046: oldBuffers.length);
047: }
048: if (buffers[index] == null)
049: buffers[index] = new byte[CHUNK_SIZE];
050: int cnt = inputStream.read(buffers[index], offset, Math
051: .min(n, CHUNK_SIZE - offset));
052: n -= cnt;
053: next += cnt;
054: index++;
055: offset = 0;
056: }
057: }
058: }
059:
060: void read(byte b[]) throws IOException {
061: int size = b.length;
062: int nCached = Math.min(size, next - current);
063: int nMissing = size - next + current;
064: int destNext = 0;
065: if (nCached > 0) {
066: /* Get cached bytes */
067: int index = current / CHUNK_SIZE;
068: int offset = current % CHUNK_SIZE;
069: while (nCached > 0) {
070: int cnt = Math.min(nCached, CHUNK_SIZE - offset);
071: System.arraycopy(buffers[index], offset, b, destNext,
072: cnt);
073: nCached -= cnt;
074: destNext += cnt;
075: index++;
076: offset = 0;
077: }
078: }
079: if (nMissing > 0) {
080: /* Read required bytes */
081: int index = next / CHUNK_SIZE;
082: int offset = next % CHUNK_SIZE;
083: while (nMissing > 0) {
084: if (index >= buffers.length) {
085: byte[][] oldBuffers = buffers;
086: buffers = new byte[Math.max(index,
087: oldBuffers.length + LIST_SIZE)][];
088: System.arraycopy(oldBuffers, 0, buffers, 0,
089: oldBuffers.length);
090: }
091: if (buffers[index] == null)
092: buffers[index] = new byte[CHUNK_SIZE];
093: int cnt = inputStream.read(buffers[index], offset, Math
094: .min(nMissing, CHUNK_SIZE - offset));
095: System.arraycopy(buffers[index], offset, b, destNext,
096: cnt);
097: nMissing -= cnt;
098: next += cnt;
099: destNext += cnt;
100: index++;
101: offset = 0;
102: }
103: }
104: current += size;
105: }
106:
107: }
|