1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.data.cache;
|
---|
3 |
|
---|
4 | import java.awt.image.BufferedImage;
|
---|
5 | import java.io.ByteArrayInputStream;
|
---|
6 | import java.io.IOException;
|
---|
7 |
|
---|
8 | import javax.imageio.ImageIO;
|
---|
9 |
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * Cache Entry that has methods to get the BufferedImage, that will be cached along in memory
|
---|
13 | * but will be not serialized when saved to the disk (to avoid duplication of data)
|
---|
14 | * @author Wiktor Niesiobędzki
|
---|
15 | *
|
---|
16 | */
|
---|
17 | public class BufferedImageCacheEntry extends CacheEntry {
|
---|
18 | private static final long serialVersionUID = 1L; //version
|
---|
19 | // transient to avoid serialization, volatile to avoid synchronization of whole getImage() method
|
---|
20 | private transient volatile BufferedImage img = null;
|
---|
21 | private transient volatile boolean writtenToDisk = false;
|
---|
22 | // we need to have separate control variable, to know, if we already tried to load the image, as img might be null
|
---|
23 | // after we loaded image, as for example, when image file is malformed (eg. HTML file)
|
---|
24 | private transient volatile boolean imageLoaded = false;
|
---|
25 |
|
---|
26 | /**
|
---|
27 | *
|
---|
28 | * @param content byte array containing image
|
---|
29 | */
|
---|
30 | public BufferedImageCacheEntry(byte[] content) {
|
---|
31 | super(content);
|
---|
32 | }
|
---|
33 |
|
---|
34 | /**
|
---|
35 | * Returns BufferedImage from for the content. Subsequent calls will return the same instance,
|
---|
36 | * to reduce overhead of ImageIO
|
---|
37 | *
|
---|
38 | * @return BufferedImage of cache entry content
|
---|
39 | * @throws IOException if an error occurs during reading.
|
---|
40 | */
|
---|
41 | public BufferedImage getImage() throws IOException {
|
---|
42 | if (imageLoaded)
|
---|
43 | return img;
|
---|
44 | synchronized(this) {
|
---|
45 | if (imageLoaded)
|
---|
46 | return img;
|
---|
47 | byte[] content = getContent();
|
---|
48 | if (content != null && content.length > 0) {
|
---|
49 | img = ImageIO.read(new ByteArrayInputStream(content));
|
---|
50 | imageLoaded = true;
|
---|
51 |
|
---|
52 | if (writtenToDisk)
|
---|
53 | content = null;
|
---|
54 | }
|
---|
55 |
|
---|
56 | }
|
---|
57 | return img;
|
---|
58 | }
|
---|
59 |
|
---|
60 |
|
---|
61 | private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
---|
62 | /*
|
---|
63 | * This method below will be needed, if Apache Commons JCS (or any other caching system), will update
|
---|
64 | * disk representation of object from memory, once it is put into the cache (for example - at closing the cache)
|
---|
65 | *
|
---|
66 | * For now it is not the case, as we use DiskUsagePattern.UPDATE, which on JCS shutdown doesn't write again memory
|
---|
67 | * contents to file, so the fact, that we've cleared never gets saved to the disk
|
---|
68 | *
|
---|
69 | * This method is commented out, as it will convert all cache entries to PNG files regardless of what was returned.
|
---|
70 | * It might cause recompression/change of format which may result in decreased quality of imagery
|
---|
71 | */
|
---|
72 | /* synchronized (this) {
|
---|
73 | if (content == null && img != null) {
|
---|
74 | ByteArrayOutputStream restoredData = new ByteArrayOutputStream();
|
---|
75 | ImageIO.write(img, "png", restoredData);
|
---|
76 | content = restoredData.toByteArray();
|
---|
77 | }
|
---|
78 | out.writeObject(this);
|
---|
79 | }
|
---|
80 | */
|
---|
81 | synchronized (this) {
|
---|
82 | if (content == null && img != null) {
|
---|
83 | throw new AssertionError("Trying to serialize (save to disk?) an BufferedImageCacheEntry that was converted to BufferedImage and no raw data is present anymore");
|
---|
84 | }
|
---|
85 | out.writeObject(this);
|
---|
86 | // ugly hack to wait till element will get to disk to clean the memory
|
---|
87 | writtenToDisk = true;
|
---|
88 |
|
---|
89 | if (img != null) {
|
---|
90 | content = null;
|
---|
91 | }
|
---|
92 |
|
---|
93 | }
|
---|
94 | }
|
---|
95 | }
|
---|