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 |
|
---|
23 | /**
|
---|
24 | *
|
---|
25 | * @param content byte array containing image
|
---|
26 | */
|
---|
27 | public BufferedImageCacheEntry(byte[] content) {
|
---|
28 | super(content);
|
---|
29 | }
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Returns BufferedImage from for the content. Subsequent calls will return the same instance,
|
---|
33 | * to reduce overhead of ImageIO
|
---|
34 | *
|
---|
35 | * @return BufferedImage of cache entry content
|
---|
36 | * @throws IOException
|
---|
37 | */
|
---|
38 | public BufferedImage getImage() throws IOException {
|
---|
39 | if (img != null)
|
---|
40 | return img;
|
---|
41 | synchronized(this) {
|
---|
42 | if (img != null)
|
---|
43 | return img;
|
---|
44 | byte[] content = getContent();
|
---|
45 | if (content != null && content.length > 0) {
|
---|
46 | img = ImageIO.read(new ByteArrayInputStream(content));
|
---|
47 |
|
---|
48 | if (writtenToDisk)
|
---|
49 | content = null;
|
---|
50 | }
|
---|
51 |
|
---|
52 | }
|
---|
53 | return img;
|
---|
54 | }
|
---|
55 |
|
---|
56 |
|
---|
57 | private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
---|
58 | /*
|
---|
59 | * This method below will be needed, if Apache Commons JCS (or any other caching system), will update
|
---|
60 | * disk representation of object from memory, once it is put into the cache (for example - at closing the cache)
|
---|
61 | *
|
---|
62 | * For now it is not the case, as we use DiskUsagePattern.UPDATE, which on JCS shutdown doesn't write again memory
|
---|
63 | * contents to file, so the fact, that we've cleared never gets saved to the disk
|
---|
64 | *
|
---|
65 | * This method is commented out, as it will convert all cache entries to PNG files regardless of what was returned.
|
---|
66 | * It might cause recompression/change of format which may result in decreased quality of imagery
|
---|
67 | */
|
---|
68 | /* synchronized (this) {
|
---|
69 | if (content == null && img != null) {
|
---|
70 | ByteArrayOutputStream restoredData = new ByteArrayOutputStream();
|
---|
71 | ImageIO.write(img, "png", restoredData);
|
---|
72 | content = restoredData.toByteArray();
|
---|
73 | }
|
---|
74 | out.writeObject(this);
|
---|
75 | }
|
---|
76 | */
|
---|
77 | synchronized (this) {
|
---|
78 | if (content == null && img != null) {
|
---|
79 | throw new AssertionError("Trying to serialize (save to disk?) an BufferedImageCacheEntry that was converted to BufferedImage and no raw data is present anymore");
|
---|
80 | }
|
---|
81 | out.writeObject(this);
|
---|
82 | // ugly hack to wait till element will get to disk to clean the memory
|
---|
83 | writtenToDisk = true;
|
---|
84 |
|
---|
85 | if (img != null) {
|
---|
86 | content = null;
|
---|
87 | }
|
---|
88 |
|
---|
89 | }
|
---|
90 | }
|
---|
91 | }
|
---|