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