1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.internal.image;
15
16 import java.io.*;
17
18 final class TIFFRandomFileAccess {
19
20 LEDataInputStream inputStream;
21 int start, current, next;
22 byte[][] buffers;
23
24 static final int CHUNK_SIZE = 8192;
25 static final int LIST_SIZE = 128;
26
TIFFRandomFileAccess(LEDataInputStream stream)27 public TIFFRandomFileAccess(LEDataInputStream stream) {
28 inputStream = stream;
29 start = current = next = inputStream.getPosition();
30 buffers = new byte[LIST_SIZE][];
31 }
32
seek(int pos)33 void seek(int pos) throws IOException {
34 if (pos == current) return;
35 if (pos < start) throw new IOException();
36 current = pos;
37 if (current > next) {
38 int n = current - next;
39 /* store required bytes */
40 int index = next / CHUNK_SIZE;
41 int offset = next % CHUNK_SIZE;
42 while (n > 0) {
43 if (index >= buffers.length) {
44 byte[][] oldBuffers = buffers;
45 buffers = new byte[Math.max(index + 1, oldBuffers.length + LIST_SIZE)][];
46 System.arraycopy(oldBuffers, 0, buffers, 0, oldBuffers.length);
47 }
48 if (buffers[index] == null) buffers[index] = new byte[CHUNK_SIZE];
49 int cnt = inputStream.read(buffers[index], offset, Math.min(n, CHUNK_SIZE - offset));
50 n -= cnt;
51 next += cnt;
52 index++;
53 offset = 0;
54 }
55 }
56 }
57
read(byte b[])58 void read(byte b[]) throws IOException {
59 int size = b.length;
60 int nCached = Math.min(size, next - current);
61 int nMissing = size - next + current;
62 int destNext = 0;
63 if (nCached > 0) {
64 /* Get cached bytes */
65 int index = current / CHUNK_SIZE;
66 int offset = current % CHUNK_SIZE;
67 while (nCached > 0) {
68 int cnt = Math.min(nCached, CHUNK_SIZE - offset);
69 System.arraycopy(buffers[index], offset, b, destNext, cnt);
70 nCached -= cnt;
71 destNext += cnt;
72 index++;
73 offset = 0;
74 }
75 }
76 if (nMissing > 0) {
77 /* Read required bytes */
78 int index = next / CHUNK_SIZE;
79 int offset = next % CHUNK_SIZE;
80 while (nMissing > 0) {
81 if (index >= buffers.length) {
82 byte[][] oldBuffers = buffers;
83 buffers = new byte[Math.max(index, oldBuffers.length + LIST_SIZE)][];
84 System.arraycopy(oldBuffers, 0, buffers, 0, oldBuffers.length);
85 }
86 if (buffers[index] == null) buffers[index] = new byte[CHUNK_SIZE];
87 int cnt = inputStream.read(buffers[index], offset, Math.min(nMissing, CHUNK_SIZE - offset));
88 System.arraycopy(buffers[index], offset, b, destNext, cnt);
89 nMissing -= cnt;
90 next += cnt;
91 destNext += cnt;
92 index++;
93 offset = 0;
94 }
95 }
96 current += size;
97 }
98
99 }
100