gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / bufferedImage / VirtualBufferedImageHelper.java @ 1538
History | View | Annotate | Download (7.25 KB)
1 |
/**
|
---|---|
2 |
* gvSIG. Desktop Geographic Information System.
|
3 |
*
|
4 |
* Copyright (C) 2007-2013 gvSIG Association.
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* as published by the Free Software Foundation; either version 3
|
9 |
* of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This program is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with this program; if not, write to the Free Software
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 |
* MA 02110-1301, USA.
|
20 |
*
|
21 |
* For any additional information, do not hesitate to contact us
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
23 |
*/
|
24 |
package org.gvsig.tools.swing.impl.bufferedImage; |
25 |
|
26 |
import java.awt.Point; |
27 |
import java.awt.image.BufferedImage; |
28 |
import java.awt.image.ColorModel; |
29 |
import java.awt.image.DataBuffer; |
30 |
import java.awt.image.SampleModel; |
31 |
import java.io.File; |
32 |
import java.io.IOException; |
33 |
import java.io.RandomAccessFile; |
34 |
import java.nio.Buffer; |
35 |
import java.nio.ByteBuffer; |
36 |
import java.nio.IntBuffer; |
37 |
import java.nio.MappedByteBuffer; |
38 |
import java.nio.ShortBuffer; |
39 |
import java.nio.channels.FileChannel; |
40 |
import org.gvsig.tools.ToolsLocator; |
41 |
|
42 |
/*
|
43 |
* Based on portions of code from TwelveMonkeys ImageIO 3.3.2
|
44 |
* under BSD 3-Clause License.
|
45 |
* Copyright (c) 2008-2015, Harald Kuhr
|
46 |
* https://github.com/haraldk/TwelveMonkeys
|
47 |
*/
|
48 |
public class VirtualBufferedImageHelper { |
49 |
|
50 |
public static abstract class VirtualDataBuffer extends DataBuffer { |
51 |
|
52 |
protected final Buffer buffer; |
53 |
|
54 |
protected VirtualDataBuffer(final int type, final int size, final int numBanks) throws IOException { |
55 |
super(type, size, numBanks);
|
56 |
if( size < 0 ) { |
57 |
throw new IllegalArgumentException("size can't be less than zero"); |
58 |
} |
59 |
int componentSize = DataBuffer.getDataTypeSize(type) / 8; |
60 |
File tempFile = ToolsLocator.getFoldersManager().getUniqueTemporaryFile("BufferedImage.dat"); |
61 |
try {
|
62 |
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw"); |
63 |
long length = ((long) size) * componentSize * numBanks; |
64 |
raf.setLength(length); |
65 |
try (FileChannel channel = raf.getChannel()) { |
66 |
MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, length); |
67 |
switch( type ) {
|
68 |
case DataBuffer.TYPE_BYTE: |
69 |
buffer = byteBuffer; |
70 |
break;
|
71 |
case DataBuffer.TYPE_USHORT: |
72 |
buffer = byteBuffer.asShortBuffer(); |
73 |
break;
|
74 |
case DataBuffer.TYPE_INT: |
75 |
buffer = byteBuffer.asIntBuffer(); |
76 |
break;
|
77 |
default:
|
78 |
throw new IllegalArgumentException("Unsupported data type: " + type); |
79 |
} |
80 |
} |
81 |
} finally {
|
82 |
tempFile.deleteOnExit(); |
83 |
} |
84 |
} |
85 |
} |
86 |
|
87 |
public static class DataBufferByte extends VirtualDataBuffer { |
88 |
|
89 |
public DataBufferByte(int size, int numBanks) throws IOException { |
90 |
super(DataBuffer.TYPE_BYTE, size, numBanks); |
91 |
} |
92 |
|
93 |
@Override
|
94 |
public int getElem(int bank, int i) { |
95 |
return ((ByteBuffer) buffer).get(bank * size + i) & 0xff; |
96 |
} |
97 |
|
98 |
@Override
|
99 |
public void setElem(int bank, int i, int val) { |
100 |
((ByteBuffer) buffer).put(bank * size + i, (byte) val); |
101 |
} |
102 |
} |
103 |
|
104 |
private static class DataBufferUShort extends VirtualDataBuffer { |
105 |
|
106 |
public DataBufferUShort(int size, int numBanks) throws IOException { |
107 |
super(DataBuffer.TYPE_USHORT, size, numBanks); |
108 |
} |
109 |
|
110 |
@Override
|
111 |
public int getElem(int bank, int i) { |
112 |
return ((ShortBuffer) buffer).get(bank * size + i) & 0xffff; |
113 |
} |
114 |
|
115 |
@Override
|
116 |
public void setElem(int bank, int i, int val) { |
117 |
((ShortBuffer) buffer).put(bank * size + i, (short) val); |
118 |
} |
119 |
} |
120 |
|
121 |
private static class DataBufferInt extends VirtualDataBuffer { |
122 |
|
123 |
public DataBufferInt(int size, int numBanks) throws IOException { |
124 |
super(DataBuffer.TYPE_INT, size, numBanks); |
125 |
} |
126 |
|
127 |
@Override
|
128 |
public int getElem(int bank, int i) { |
129 |
return ((IntBuffer) buffer).get(bank * size + i); |
130 |
} |
131 |
|
132 |
@Override
|
133 |
public void setElem(int bank, int i, int val) { |
134 |
((IntBuffer) buffer).put(bank * size + i, val);
|
135 |
} |
136 |
} |
137 |
|
138 |
private static class WritableRaster extends java.awt.image.WritableRaster { |
139 |
|
140 |
public WritableRaster(final SampleModel model, final DataBuffer buffer) { |
141 |
super(model, buffer, new Point()); // Este constructor es protegido. |
142 |
} |
143 |
} |
144 |
|
145 |
public static class IORuntimeException extends RuntimeException { |
146 |
|
147 |
private static final long serialVersionUID = -4461981890554048338L; |
148 |
|
149 |
public IORuntimeException(IOException ex) { |
150 |
super(ex.getMessage(), ex);
|
151 |
} |
152 |
} |
153 |
|
154 |
public static DataBuffer createVirtualDataBuffer(final int type, final int size, final int numBanks) throws IOException { |
155 |
switch( type ) {
|
156 |
case DataBuffer.TYPE_BYTE: |
157 |
return new DataBufferByte(size, numBanks); |
158 |
case DataBuffer.TYPE_USHORT: |
159 |
return new DataBufferUShort(size, numBanks); |
160 |
case DataBuffer.TYPE_INT: |
161 |
return new DataBufferInt(size, numBanks); |
162 |
default:
|
163 |
throw new IllegalArgumentException("Unsupported data type: " + type); |
164 |
} |
165 |
} |
166 |
|
167 |
public static BufferedImage createVirtualBufferedImage(int width, int height, int type) { |
168 |
BufferedImage temp = new BufferedImage(1, 1, type); |
169 |
SampleModel sampleModel = temp.getSampleModel().createCompatibleSampleModel(width, height);
|
170 |
ColorModel colorModel = temp.getColorModel();
|
171 |
BufferedImage x = createVirtualBufferedImage(width, height, sampleModel, colorModel);
|
172 |
return x;
|
173 |
} |
174 |
|
175 |
public static BufferedImage createVirtualBufferedImage(int width, int height, SampleModel sampleModel, ColorModel colorModel) throws IORuntimeException { |
176 |
DataBuffer buffer;
|
177 |
try {
|
178 |
buffer = createVirtualDataBuffer(sampleModel.getTransferType(), width * height * sampleModel.getNumDataElements(), 1);
|
179 |
} catch (IOException ex) { |
180 |
throw new IORuntimeException(ex); |
181 |
} |
182 |
WritableRaster raster = new WritableRaster(sampleModel, buffer); |
183 |
BufferedImage x = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null); |
184 |
// try {
|
185 |
// Field field = x.getClass().getDeclaredField("imageType");
|
186 |
// field.setAccessible(true);
|
187 |
// field.setInt(x, type);
|
188 |
// field.setAccessible(false);
|
189 |
// } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
190 |
// throw new RuntimeException("Can't set the image type to the BufferedImage.", e);
|
191 |
// }
|
192 |
return x;
|
193 |
} |
194 |
|
195 |
} |