1 package de.desy.acop.video.displayer;
2
3 import java.awt.Image;
4 import java.awt.image.BufferedImage;
5 import java.io.BufferedWriter;
6 import java.io.DataInputStream;
7 import java.io.EOFException;
8 import java.io.File;
9 import java.io.FileInputStream;
10 import java.io.FileWriter;
11 import java.io.IOException;
12 import java.io.Writer;
13 import java.net.URL;
14 import java.text.DateFormat;
15 import java.text.SimpleDateFormat;
16 import java.util.Date;
17
18 import javax.imageio.ImageIO;
19
20 import de.desy.acop.video.displayer.timage.TImageUtils;
21 import de.desy.tine.types.IMAGE;
22
23 public class ImageParser {
24
25 private static ImageParser SINGLETON;
26 static {
27 SINGLETON = new ImageParser();
28 }
29
30 public static ImageParser instance() {
31 return SINGLETON;
32 }
33
34 public static void refresh() {
35 SINGLETON = new ImageParser();
36 }
37
38 private ImageParser() {
39 }
40
41
42
43
44
45
46
47 public static final boolean loadImageFile(String aFileName, IMAGE aOutImage) {
48 return loadImageFile(aFileName, aOutImage, false);
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public static final boolean loadImageFile(String aFileName, IMAGE aOutImage, boolean aChangeToGrey) {
69 if (aOutImage == null)
70 return false;
71
72
73 BufferedImage img = null;
74 File imgFile = null;
75 try {
76 imgFile = new File(aFileName);
77 img = ImageIO.read(imgFile);
78 } catch (IOException ex) {
79 return false;
80 }
81
82 return postProcess(imgFile, img, aOutImage, aChangeToGrey);
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public static final boolean loadImageFile(URL url, IMAGE outImage, boolean toGrey) {
101 try {
102 return postProcess(url.toString(), ImageIO.read(url), outImage, toGrey);
103
104 } catch (IOException ignored) {
105 }
106 return false;
107 }
108
109
110
111
112
113
114
115
116
117
118 @Deprecated
119 private static final boolean postProcess(File imgFile, BufferedImage img, IMAGE aOutImage, boolean aChangeToGrey) {
120
121
122 int imgWidth = img.getWidth();
123 int imgHeight = img.getHeight();
124
125 int[] pixelArr = new int[imgWidth * imgHeight];
126
127 if (img.getRGB(0, 0, imgWidth, imgHeight, pixelArr, 0, imgWidth) == null)
128 return false;
129
130
131
132 IMAGE.FrameHeader frameHeader = aOutImage.getFrameHeader();
133 IMAGE.SourceHeader sourceHeader = aOutImage.getSourceHeader();
134
135 if (aChangeToGrey == true) {
136 frameHeader.bytesPerPixel = 1;
137 frameHeader.effectiveBitsPerPixel = 8;
138 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
139 frameHeader.sourceFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
140 } else {
141
142 frameHeader.bytesPerPixel = 3;
143 frameHeader.effectiveBitsPerPixel = 24;
144 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_RGB.getId();
145 frameHeader.sourceFormat = ImageFormat.IMAGE_FORMAT_RGB.getId();
146 }
147
148 frameHeader.appendedFrameSize = imgWidth * imgHeight * frameHeader.bytesPerPixel;
149
150
151
152
153
154
155
156 frameHeader.imageFlags = ImageFlag.IMAGE_LOSSLESS.getId() | ImageFlag.LITTLE_ENDIAN_BYTE_ORDER.getId();
157
158 frameHeader.sourceHeight = imgHeight;
159 frameHeader.sourceWidth = imgWidth;
160 frameHeader.xScale = 1;
161 frameHeader.yScale = 1;
162
163
164 sourceHeader.cameraPortName = "file://" + imgFile.getName();
165
166 long msTimeEpoch = imgFile.lastModified();
167 sourceHeader.timestampMicroseconds = (int) (((msTimeEpoch % ((long) 1000)) * ((long) 1000)));
168 sourceHeader.timestampSeconds = (int) (((msTimeEpoch) / ((long) 1000)));
169
170 sourceHeader.totalLength = IMAGE.HEADER_SIZE + frameHeader.appendedFrameSize;
171
172 byte[] buf = new byte[frameHeader.appendedFrameSize];
173
174
175
176
177 if (aChangeToGrey == true) {
178 for (int i = 0; i < frameHeader.sourceWidth * frameHeader.sourceHeight; i++) {
179 double r = (double) ((pixelArr[i] >> 16) & 0xff);
180 double g = (double) ((pixelArr[i] >> 8) & 0xff);
181 double b = (double) (pixelArr[i] & 0xff);
182 buf[i] = (byte) (0.114 * b + 0.587 * g + 0.299 * r);
183 }
184 } else {
185 int pos = 0;
186 for (int i = 0; i < frameHeader.sourceWidth * frameHeader.sourceHeight; i++) {
187 buf[pos++] = (byte) ((pixelArr[i] >> 16) & 0xff);
188 buf[pos++] = (byte) ((pixelArr[i] >> 8) & 0xff);
189 buf[pos++] = (byte) (pixelArr[i] & 0xff);
190 }
191 }
192
193 aOutImage.setImageFrameBuffer(buf);
194
195 return true;
196 }
197
198
199
200
201
202
203
204
205
206
207 @SuppressWarnings("deprecation")
208 private static final boolean postProcess(String defltCameraPortName, BufferedImage img, IMAGE aOutImage,
209 boolean aChangeToGrey) {
210
211
212 int imgWidth = img.getWidth();
213 int imgHeight = img.getHeight();
214
215 int[] pixelArr = new int[imgWidth * imgHeight];
216
217 if (img.getRGB(0, 0, imgWidth, imgHeight, pixelArr, 0, imgWidth) == null)
218 return false;
219
220
221
222 IMAGE.FrameHeader frameHeader = aOutImage.getFrameHeader();
223 IMAGE.SourceHeader sourceHeader = aOutImage.getSourceHeader();
224
225 if (aChangeToGrey == true) {
226 frameHeader.bytesPerPixel = 1;
227 frameHeader.effectiveBitsPerPixel = 8;
228 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
229 frameHeader.sourceFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
230 } else {
231
232 frameHeader.bytesPerPixel = 3;
233 frameHeader.effectiveBitsPerPixel = 24;
234 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_RGB.getId();
235 frameHeader.sourceFormat = ImageFormat.IMAGE_FORMAT_RGB.getId();
236 }
237
238 frameHeader.appendedFrameSize = imgWidth * imgHeight * frameHeader.bytesPerPixel;
239
240
241
242
243
244
245
246 frameHeader.imageFlags = ImageFlag.IMAGE_LOSSLESS.getId() | ImageFlag.LITTLE_ENDIAN_BYTE_ORDER.getId();
247
248 frameHeader.sourceHeight = imgHeight;
249 frameHeader.sourceWidth = imgWidth;
250 frameHeader.xScale = 1;
251 frameHeader.yScale = 1;
252
253
254 sourceHeader.cameraPortName = defltCameraPortName;
255
256 long msTimeEpoch = System.currentTimeMillis();
257 sourceHeader.timestampMicroseconds = (int) (((msTimeEpoch % ((long) 1000)) * ((long) 1000)));
258 sourceHeader.timestampSeconds = (int) (((msTimeEpoch) / ((long) 1000)));
259
260 sourceHeader.totalLength = IMAGE.HEADER_SIZE + frameHeader.appendedFrameSize;
261
262 byte[] buf = new byte[frameHeader.appendedFrameSize];
263
264
265
266
267 if (aChangeToGrey == true) {
268 for (int i = 0; i < frameHeader.sourceWidth * frameHeader.sourceHeight; i++) {
269 double r = (double) ((pixelArr[i] >> 16) & 0xff);
270 double g = (double) ((pixelArr[i] >> 8) & 0xff);
271 double b = (double) (pixelArr[i] & 0xff);
272 buf[i] = (byte) (0.114 * b + 0.587 * g + 0.299 * r);
273 }
274 } else {
275 int pos = 0;
276 for (int i = 0; i < frameHeader.sourceWidth * frameHeader.sourceHeight; i++) {
277 buf[pos++] = (byte) ((pixelArr[i] >> 16) & 0xff);
278 buf[pos++] = (byte) ((pixelArr[i] >> 8) & 0xff);
279 buf[pos++] = (byte) (pixelArr[i] & 0xff);
280 }
281 }
282
283 aOutImage.setImageFrameBuffer(buf);
284 return true;
285 }
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 @SuppressWarnings("deprecation")
301 public static final boolean loadIMM(String aFileName, IMAGE aOutImage) {
302 if (aOutImage == null)
303 return false;
304
305 int width;
306 int height;
307 int bytesperpixel;
308 int bitsperpixel;
309 double scale;
310 FileInputStream fis = null;
311 DataInputStream dis = null;
312 byte[] imagebits = null;
313
314
315
316
317
318
319
320
321
322
323
324
325 width = -1;
326 height = -1;
327 bytesperpixel = -1;
328 bitsperpixel = -1;
329 scale = -1.0;
330
331 try {
332 fis = new FileInputStream(aFileName);
333 dis = new DataInputStream(fis);
334
335 long fsize = fis.getChannel().size();
336
337 width = dis.readUnsignedShort();
338 width = ((width & 0xff) << 8) + (width >> 8);
339 bytesperpixel = dis.readUnsignedShort();
340 bytesperpixel = ((bytesperpixel & 0xff) << 8) + (bytesperpixel >> 8);
341 height = dis.readUnsignedShort();
342 height = ((height & 0xff) << 8) + (height >> 8);
343 bitsperpixel = dis.readUnsignedShort();
344 bitsperpixel = ((bitsperpixel & 0xff) << 8) + (bitsperpixel >> 8);
345
346 bytesperpixel /= 8;
347 if (bytesperpixel == 0)
348 bytesperpixel = 1;
349
350 if ((bitsperpixel == 0) || (bitsperpixel > (8 * bytesperpixel)))
351 bitsperpixel = bytesperpixel * 8;
352
353
354
355
356 if (fsize < (width * height * bytesperpixel + 16))
357 throw new EOFException();
358
359 imagebits = new byte[width * height * bytesperpixel];
360
361 dis.read(imagebits, 0, imagebits.length);
362
363 byte[] buf = new byte[8];
364
365 dis.read(buf, 0, buf.length);
366
367 int off = 0;
368 long scale_long = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
369 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24)
370 | ((((long) buf[off + 4]) & 0xFF) << 32) | ((((long) buf[off + 5]) & 0xFF) << 40)
371 | ((((long) buf[off + 6]) & 0xFF) << 48) | ((((long) buf[off + 7]) & 0xFF) << 56);
372
373 scale = Double.longBitsToDouble(scale_long);
374 } catch (EOFException eof) {
375
376 return false;
377 } catch (IOException ioe) {
378
379 return false;
380 } finally {
381 try {
382 if (dis != null)
383 dis.close();
384 } catch (IOException ex) {
385 }
386 try {
387 if (fis != null)
388 fis.close();
389 } catch (IOException ex) {
390 }
391 dis = null;
392 fis = null;
393 }
394
395 IMAGE.FrameHeader frameHeader = aOutImage.getFrameHeader();
396 IMAGE.SourceHeader sourceHeader = aOutImage.getSourceHeader();
397
398 frameHeader.bytesPerPixel = bytesperpixel;
399 frameHeader.effectiveBitsPerPixel = bitsperpixel;
400 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
401 frameHeader.sourceFormat = frameHeader.imageFormat;
402
403 frameHeader.appendedFrameSize = width * height * frameHeader.bytesPerPixel;
404
405
406 frameHeader.imageFlags |= ImageFlag.IMAGE_LOSSLESS.getId();
407
408 frameHeader.sourceHeight = height;
409 frameHeader.sourceWidth = width;
410 frameHeader.xScale = (float) scale;
411 frameHeader.yScale = (float) scale;
412
413 File imgFile = new File(aFileName);
414
415
416 sourceHeader.cameraPortName = "file://" + imgFile.getName();
417
418 long msTimeEpoch = imgFile.lastModified();
419 sourceHeader.timestampMicroseconds = (int) (((msTimeEpoch % ((long) 1000)) * ((long) 1000)));
420 sourceHeader.timestampSeconds = (int) (((msTimeEpoch) / ((long) 1000)));
421
422 sourceHeader.totalLength = IMAGE.HEADER_SIZE + frameHeader.appendedFrameSize;
423
424 aOutImage.setImageFrameBuffer(imagebits);
425
426 return true;
427 }
428
429
430
431
432
433 public static void printLoadableFormats() {
434 String[] names = ImageIO.getReaderFormatNames();
435 for (String name : names)
436 System.out.println(name);
437 }
438
439
440
441
442
443
444
445
446 public static boolean write(String aFileName, Image aImg, IMAGE timage) {
447 return write(new File(aFileName), aImg, timage);
448 }
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 public static boolean write(File aFile, Image aImg, IMAGE timage) {
466 try {
467 ImageIO.write(TImageUtils.toBufferedImage(aImg), "png", aFile);
468
469
470 String wholename = aFile.getAbsolutePath();
471 wholename += ".txt";
472
473 Writer output = null;
474 try {
475
476
477 File txtF = new File(wholename);
478 txtF.createNewFile();
479
480 String n = System.getProperty("line.separator");
481 DateFormat dfmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
482
483 output = new BufferedWriter(new FileWriter(txtF));
484
485 IMAGE.SourceHeader srcH = timage.getSourceHeader();
486 IMAGE.FrameHeader frmH = timage.getFrameHeader();
487
488 output.write("SourceHeader." + n);
489 output.write(" .version " + srcH.versionTag + n);
490 output.write(" .timestamp "
491 + dfmt.format(new Date((srcH.timestampSeconds * 1000L) + (srcH.timestampMicroseconds / 1000L)))
492 + n);
493 output.write(" .cameraport \"" + srcH.cameraPortName + "\"" + n);
494 output.write(" .total_length " + srcH.totalLength + n);
495
496 output.write(" FrameHeader" + n);
497 output.write(" .sourceWidth " + frmH.sourceWidth + n);
498 output.write(" .sourceHeight " + frmH.sourceHeight + n);
499 output.write(" .aoiWidth " + frmH.aoiWidth + n);
500 output.write(" .aoiHeight " + frmH.aoiHeight + n);
501 output.write(" .xStart " + frmH.xStart + n);
502 output.write(" .yStart " + frmH.yStart + n);
503 output.write(" .bytesPerPixel " + frmH.bytesPerPixel + n);
504 output.write(" .effectiveBitsPerPixel " + frmH.effectiveBitsPerPixel + n);
505 output.write(" .horizontalBinning " + frmH.horizontalBinning + n);
506 output.write(" .verticalBinning " + frmH.verticalBinning + n);
507 output.write(" .sourceFormat " + ImageFormat.valueOf(frmH.sourceFormat) + n);
508 output.write(" .currentFormat " + ImageFormat.valueOf(frmH.imageFormat) + n);
509 output.write(" .frameNumber " + frmH.frameNumber + n);
510 output.write(" .eventNumer " + frmH.eventNumber + n);
511 output.write(" .xScale " + frmH.xScale + n);
512 output.write(" .yScale " + frmH.yScale + n);
513 output.write(" .imageRotation " + frmH.imageRotation + n);
514
515
516
517
518
519
520 output.write(" .imageFlags " + ImageFlag.toString(frmH.imageFlags) + n);
521
522 output.write(" .appendedFrameSize " + frmH.appendedFrameSize + n);
523 output.write("Header END" + n);
524 } catch (IOException ex1) {
525 return false;
526
527 } finally {
528
529 if (output != null)
530 output.close();
531 }
532
533 } catch (IOException ex) {
534 return false;
535 }
536
537 return true;
538 }
539 }