1 package de.desy.acop.video.displayer;
2
3 import java.util.Date;
4
5 import de.desy.tine.types.IMAGE;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public final class VideoHeaderV2 {
23
24
25 public static final int HDRSIZE = 88;
26
27
28 public static final long HUFFYUV_FOURCC = 0x55594648;
29
30
31 private static final long KENNUNG = 0x11223344L;
32
33
34 private static final long MAX_INT = 0x7FFFFFFFL;
35
36
37 private int len_data;
38
39
40
41
42
43 private int len_fmthdr;
44
45
46 private long framenumber = -1L;
47
48
49 private Date timestamp = new Date(0L);
50
51
52 private int width = -1;
53
54
55 private int height = -1;
56
57
58
59
60
61 private boolean compressed;
62
63
64
65
66 private double scale = 1D;
67
68
69 private int bypp = 1;
70
71
72 private int effective_bpp = 8;
73
74 public VideoHeaderV2() {
75 super();
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public boolean packageV2BlobIntoIMAGE(String cameraPortName, byte[] imageV2blob, IMAGE destTineImage) {
102 if (!parseImageV2blob(imageV2blob))
103 return false;
104
105 IMAGE.FrameHeader frameHeader = destTineImage.getFrameHeader();
106 IMAGE.SourceHeader sourceHeader = destTineImage.getSourceHeader();
107
108 frameHeader.sourceFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
109 frameHeader.sourceWidth = width;
110 frameHeader.sourceHeight = height;
111 frameHeader.bytesPerPixel = bypp;
112 frameHeader.effectiveBitsPerPixel = effective_bpp;
113 frameHeader.aoiHeight = frameHeader.aoiWidth = -1;
114 frameHeader.eventNumber = -1L;
115 frameHeader.frameNumber = framenumber;
116
117 frameHeader.imageFlags = ImageFlag.IMAGE_LOSSLESS.getId() | ImageFlag.LITTLE_ENDIAN_BYTE_ORDER.getId();
118
119 if (compressed) {
120 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_HUFFYUV.getId();
121 frameHeader.appendedFrameSize = len_data;
122 } else {
123 frameHeader.imageFormat = ImageFormat.IMAGE_FORMAT_GRAY.getId();
124 frameHeader.appendedFrameSize = width * height * bypp;
125 }
126
127 sourceHeader.totalLength = IMAGE.HEADER_SIZE + frameHeader.appendedFrameSize;
128
129 frameHeader.ispare1 = frameHeader.ispare2 = frameHeader.ispare3 = -1;
130 frameHeader.fspare1 = frameHeader.fspare2 = frameHeader.fspare3 = -1F;
131 frameHeader.horizontalBinning = frameHeader.verticalBinning = 0;
132
133 frameHeader.imageRotation = 0F;
134 frameHeader.xScale = frameHeader.yScale = (float) scale;
135 frameHeader.xStart = frameHeader.yStart = 0;
136
137 sourceHeader.baseTag = IMAGE.DEFAULT_BASE_TAG;
138 sourceHeader.cameraPortName = cameraPortName;
139 sourceHeader.cameraPortId = IMAGE.DEFAULT_CAMERA_PORT_ID;
140
141 long msecs = timestamp.getTime();
142
143 sourceHeader.timestampMicroseconds = (int) ((msecs % 1000L) * 1000L);
144 sourceHeader.timestampSeconds = (int) (msecs / 1000L);
145 sourceHeader.versionTag = IMAGE.IMAGE_VERSION;
146
147 System.arraycopy(imageV2blob, HDRSIZE + len_fmthdr, destTineImage.getImageFrameBuffer(), 0, len_data);
148
149 return true;
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 public boolean parseImageV2blob(byte[] buf) {
168
169 long l_kennung;
170 long l_width;
171 long l_height;
172 long l_bypp;
173 long l_effective_bpp;
174 long l_len_total;
175 long l_len_data;
176 long l_len_fmthdr;
177 long l_framenumber;
178 long l_cameraport;
179 long l_timestamp;
180 long l_compressed;
181 double l_scale;
182 double l_framerate;
183
184 if (buf.length < HDRSIZE)
185 return false;
186
187 int off = 0;
188 l_kennung = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
189 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
190
191 off = 8;
192 l_len_total = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
193 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
194
195 off = 12;
196 l_len_data = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
197 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
198
199 off = 16;
200 l_len_fmthdr = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
201 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
202
203 off = 20;
204 l_framenumber = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
205 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
206
207 off = 24;
208 long l_timestamp_sec = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
209 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
210 off = 28;
211 long l_timestamp_msec = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8);
212
213 l_timestamp = (l_timestamp_sec * 1000L) + l_timestamp_msec;
214
215 off = 36;
216 l_cameraport = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
217 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
218
219 off = 40;
220 l_width = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
221 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
222
223 off = 44;
224 l_height = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
225 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
226
227 off = 48;
228 l_compressed = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
229 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
230
231 off = 56;
232
233 long l_framerate_long = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
234 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24)
235 | ((((long) buf[off + 4]) & 0xFF) << 32) | ((((long) buf[off + 5]) & 0xFF) << 40)
236 | ((((long) buf[off + 6]) & 0xFF) << 48) | ((((long) buf[off + 7]) & 0xFF) << 56);
237
238 l_framerate = Double.longBitsToDouble(l_framerate_long);
239
240 off = 64;
241 long l_scale_long = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
242 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24)
243 | ((((long) buf[off + 4]) & 0xFF) << 32) | ((((long) buf[off + 5]) & 0xFF) << 40)
244 | ((((long) buf[off + 6]) & 0xFF) << 48) | ((((long) buf[off + 7]) & 0xFF) << 56);
245
246 l_scale = Double.longBitsToDouble(l_scale_long);
247
248 off = 72;
249 l_bypp = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
250 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
251 l_bypp /= 8;
252
253 off = 76;
254 l_effective_bpp = (((long) buf[off + 0]) & 0xFF) | ((((long) buf[off + 1]) & 0xFF) << 8)
255 | ((((long) buf[off + 2]) & 0xFF) << 16) | ((((long) buf[off + 3]) & 0xFF) << 24);
256
257
258 if (l_effective_bpp >= l_bypp * 8)
259 l_effective_bpp = l_bypp * 8;
260
261
262 if ((l_kennung == KENNUNG) && ((l_width > 0) && (l_width <= MAX_INT))
263 && ((l_height > 0) && (l_height <= MAX_INT)) && ((l_bypp == 1) || (l_bypp == 2) || (l_bypp == 4))
264 && (l_effective_bpp <= l_bypp * 8) && (l_len_total <= buf.length) && (l_len_data <= buf.length)
265 && (l_len_fmthdr <= buf.length) && (l_len_total == l_len_data + l_len_fmthdr + HDRSIZE)
266 && (l_framenumber > 0) && ((l_cameraport >= 0) && (l_cameraport <= MAX_INT)) && (l_timestamp > 0)
267 && ((l_compressed == 0) || (l_compressed == 1)) && (l_scale > 0.0) && (l_framerate > 0.0)) {
268
269 width = (int) l_width;
270 height = (int) l_height;
271 bypp = (int) l_bypp;
272 effective_bpp = (int) l_effective_bpp;
273 len_data = (int) l_len_data;
274 len_fmthdr = (int) l_len_fmthdr;
275 framenumber = l_framenumber;
276 timestamp = new Date(l_timestamp);
277 scale = l_scale;
278 compressed = (l_compressed == 1);
279 return true;
280 }
281 return false;
282 }
283 }