merge with master
[fanfix.git] / src / be / nikiroo / utils / Image.java
1 package be.nikiroo.utils;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.Closeable;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 /**
11 * This class represents an image data.
12 *
13 * @author niki
14 */
15 public class Image implements Closeable {
16 static private TempFiles tmpRepository;
17 static private long count = 0;
18 static private Object lock = new Object();
19
20 private File data;
21
22 /**
23 * Do not use -- for serialisation purposes only.
24 */
25 @SuppressWarnings("unused")
26 private Image() {
27 }
28
29 /**
30 * Create a new {@link Image} with the given data.
31 *
32 * @param data
33 * the data
34 */
35 public Image(byte[] data) {
36 ByteArrayInputStream in = new ByteArrayInputStream(data);
37 try {
38 this.data = getTemporaryFile();
39 IOUtils.write(in, this.data);
40 } catch (IOException e) {
41 throw new RuntimeException(e);
42 } finally {
43 try {
44 in.close();
45 } catch (IOException e) {
46 throw new RuntimeException(e);
47 }
48 }
49 }
50
51 /**
52 * Create a new {@link Image} from its Base64 representation.
53 *
54 * @param base64
55 * the {@link Image} in Base64 format
56 *
57 * @throws IOException
58 * in case of I/O error
59 */
60 public Image(String base64) throws IOException {
61 this(Base64.decode(base64));
62 }
63
64 /**
65 * Create a new {@link Image} from a stream.
66 *
67 * @param in
68 * the stream
69 *
70 * @throws IOException
71 * in case of I/O error
72 */
73 public Image(InputStream in) throws IOException {
74 data = getTemporaryFile();
75 IOUtils.write(in, data);
76 }
77
78 /**
79 * <b>Read</b> the actual image data, as a byte array.
80 *
81 * @return the image data
82 */
83 public byte[] getData() {
84 try {
85 FileInputStream in = new FileInputStream(data);
86 try {
87 return IOUtils.toByteArray(in);
88 } finally {
89 in.close();
90 }
91 } catch (IOException e) {
92 throw new RuntimeException(e);
93 }
94 }
95
96 /**
97 * Convert the given {@link Image} object into a Base64 representation of
98 * the same {@link Image} object.
99 *
100 * @return the Base64 representation
101 */
102 public String toBase64() {
103 return Base64.encodeBytes(getData());
104 }
105
106 /**
107 * Closing the {@link Image} will delete the associated temporary file on
108 * disk.
109 * <p>
110 * Note that even if you don't, the program will still <b>try</b> to delete
111 * all the temporary files at JVM termination.
112 */
113 @Override
114 public void close() throws IOException {
115 data.delete();
116 synchronized (lock) {
117 count--;
118 if (count <= 0) {
119 count = 0;
120 tmpRepository.close();
121 tmpRepository = null;
122 }
123 }
124 }
125
126 @Override
127 protected void finalize() throws Throwable {
128 try {
129 close();
130 } finally {
131 super.finalize();
132 }
133 }
134
135 /**
136 * Return a newly created temporary file to work on.
137 *
138 * @return the file
139 *
140 * @throws IOException
141 * in case of I/O error
142 */
143 private File getTemporaryFile() throws IOException {
144 synchronized (lock) {
145 if (tmpRepository == null) {
146 tmpRepository = new TempFiles("images");
147 count = 0;
148 }
149
150 count++;
151
152 return tmpRepository.createTempFile("image");
153 }
154 }
155 }