-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSubImageOutputStream.java
More file actions
136 lines (117 loc) · 3.5 KB
/
SubImageOutputStream.java
File metadata and controls
136 lines (117 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* @(#)SubImageOutputStream.java 1.0 2011-07-20
*
* Copyright (c) 2011 Werner Randelshofer, Immensee, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
import java.io.IOException;
import java.nio.ByteOrder;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.ImageOutputStreamImpl;
/**
* {@code SubImageOutputStream}.
*
* @author Werner Randelshofer
* @version 1.0 2011-07-20 Created.
*/
public class SubImageOutputStream extends ImageOutputStreamImpl {
private ImageOutputStream out;
private long offset;
private long length;
/** Whether flush and close request shall be forwarded to underlying stream.*/
private boolean forwardFlushAndClose;
public SubImageOutputStream(ImageOutputStream out, ByteOrder bo,boolean forwardFlushAndClose) throws IOException {
this(out, out.getStreamPosition(),bo,forwardFlushAndClose);
}
public SubImageOutputStream(ImageOutputStream out, long offset, ByteOrder bo,boolean forwardFlushAndClose) throws IOException {
this.out = out;
this.offset = offset;
this.forwardFlushAndClose=forwardFlushAndClose;
setByteOrder(bo);
out.seek(offset);
}
private long available() throws IOException {
checkClosed();
long pos = out.getStreamPosition();
if (pos < offset) {
out.seek(offset);
pos = offset;
}
return offset + out.length() - pos;
}
@Override
public int read() throws IOException {
if (available() <= 0) {
return -1;
} else {
return out.read();
}
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
long av = available();
if (av <= 0) {
return -1;
} else {
int result = out.read(b, off, (int) Math.min(len, av));
return result;
}
}
@Override
public long getStreamPosition() throws IOException {
return out.getStreamPosition() - offset;
}
@Override
public void seek(long pos) throws IOException {
out.seek(pos + offset);
length=Math.max(pos-offset+1,length);
}
@Override
public void flush() throws IOException {
if (forwardFlushAndClose) {
out.flush();
}
}
@Override
public long getFlushedPosition() {
return out.getFlushedPosition() - offset;
}
/**
* Default implementation returns false. Subclasses should
* override this if they cache data.
*/
@Override
public boolean isCached() {
return out.isCached();
}
/**
* Default implementation returns false. Subclasses should
* override this if they cache data in main memory.
*/
@Override
public boolean isCachedMemory() {
return out.isCachedMemory();
}
@Override
public boolean isCachedFile() {
return out.isCachedFile();
}
@Override
public long length() {
return length;
}
@Override
public void write(int b) throws IOException {
out.write(b);
length = Math.max(out.getStreamPosition()-offset,length);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
out.write(b,off,len);
length = Math.max(out.getStreamPosition()-offset,length);
}
}