Statistics
| Revision:

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
}