test: new: CryptUtilsTest
[nikiroo-utils.git] / src / be / nikiroo / utils / Image.java
CommitLineData
80500544
NR
1package be.nikiroo.utils;
2
59864f77
NR
3import java.io.ByteArrayInputStream;
4import java.io.Closeable;
5import java.io.File;
6import java.io.FileInputStream;
80500544
NR
7import java.io.IOException;
8import java.io.InputStream;
9
10/**
11 * This class represents an image data.
12 *
13 * @author niki
14 */
59864f77 15public class Image implements Closeable {
82fcfcde 16 static private File tempRoot;
59864f77
NR
17 static private TempFiles tmpRepository;
18 static private long count = 0;
19 static private Object lock = new Object();
20
21 private File data;
80500544
NR
22
23 /**
24 * Do not use -- for serialisation purposes only.
25 */
26 @SuppressWarnings("unused")
27 private Image() {
28 }
29
30 /**
31 * Create a new {@link Image} with the given data.
32 *
33 * @param data
34 * the data
35 */
36 public Image(byte[] data) {
59864f77
NR
37 ByteArrayInputStream in = new ByteArrayInputStream(data);
38 try {
39 this.data = getTemporaryFile();
40 IOUtils.write(in, this.data);
41 } catch (IOException e) {
42 throw new RuntimeException(e);
43 } finally {
44 try {
45 in.close();
46 } catch (IOException e) {
47 throw new RuntimeException(e);
48 }
49 }
80500544
NR
50 }
51
52 /**
53 * Create a new {@link Image} from its Base64 representation.
54 *
55 * @param base64
56 * the {@link Image} in Base64 format
57 *
58 * @throws IOException
59 * in case of I/O error
60 */
61 public Image(String base64) throws IOException {
62 this(Base64.decode(base64));
63 }
64
65 /**
66 * Create a new {@link Image} from a stream.
67 *
68 * @param in
69 * the stream
70 *
71 * @throws IOException
72 * in case of I/O error
73 */
74 public Image(InputStream in) throws IOException {
59864f77
NR
75 data = getTemporaryFile();
76 IOUtils.write(in, data);
80500544
NR
77 }
78
79 /**
59864f77 80 * <b>Read</b> the actual image data, as a byte array.
80500544
NR
81 *
82 * @return the image data
83 */
84 public byte[] getData() {
59864f77
NR
85 try {
86 FileInputStream in = new FileInputStream(data);
87 try {
88 return IOUtils.toByteArray(in);
89 } finally {
90 in.close();
91 }
92 } catch (IOException e) {
93 throw new RuntimeException(e);
94 }
80500544
NR
95 }
96
97 /**
98 * Convert the given {@link Image} object into a Base64 representation of
99 * the same {@link Image} object.
100 *
101 * @return the Base64 representation
102 */
103 public String toBase64() {
0988831f 104 return Base64.encodeBytes(getData());
80500544 105 }
59864f77
NR
106
107 /**
108 * Closing the {@link Image} will delete the associated temporary file on
109 * disk.
110 * <p>
111 * Note that even if you don't, the program will still <b>try</b> to delete
112 * all the temporary files at JVM termination.
113 */
114 @Override
115 public void close() throws IOException {
116 data.delete();
117 synchronized (lock) {
118 count--;
119 if (count <= 0) {
120 count = 0;
121 tmpRepository.close();
122 tmpRepository = null;
123 }
124 }
125 }
126
127 @Override
128 protected void finalize() throws Throwable {
129 try {
130 close();
131 } finally {
132 super.finalize();
133 }
134 }
135
136 /**
137 * Return a newly created temporary file to work on.
138 *
139 * @return the file
140 *
141 * @throws IOException
142 * in case of I/O error
143 */
144 private File getTemporaryFile() throws IOException {
145 synchronized (lock) {
146 if (tmpRepository == null) {
82fcfcde 147 tmpRepository = new TempFiles(tempRoot, "images");
59864f77
NR
148 count = 0;
149 }
150
151 count++;
152
153 return tmpRepository.createTempFile("image");
154 }
155 }
82fcfcde
NR
156
157 /**
158 * Change the temporary root directory used by the program.
159 * <p>
160 * Caution: the directory will be <b>owned</b> by the system, all its files
161 * now belong to us (and will most probably be deleted).
162 * <p>
163 * Note: it may take some time until the new temporary root is used, we
164 * first need to make sure the previous one is not used anymore (i.e., we
165 * must reach a point where no unclosed {@link Image} remains in memory) to
166 * switch the temporary root.
167 *
168 * @param root
169 * the new temporary root, which will be <b>owned</b> by the
170 * system
171 */
172 public static void setTemporaryFilesRoot(File root) {
173 tempRoot = root;
174 }
80500544 175}