1 package nom.tam.fits.test;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.RandomAccessFile;
7 import java.nio.file.Files;
8 import java.nio.file.StandardCopyOption;
9 import java.util.Arrays;
10
11 import org.junit.jupiter.api.Assertions;
12 import org.junit.jupiter.api.Disabled;
13 import org.junit.jupiter.api.Test;
14
15 import nom.tam.fits.BasicHDU;
16 import nom.tam.fits.Fits;
17 import nom.tam.fits.FitsException;
18 import nom.tam.fits.FitsFactory;
19 import nom.tam.fits.FitsIntegrityException;
20 import nom.tam.fits.Header;
21 import nom.tam.fits.ImageData;
22 import nom.tam.fits.ImageHDU;
23 import nom.tam.fits.header.Bitpix;
24 import nom.tam.fits.header.Standard;
25 import nom.tam.fits.utilities.FitsCheckSum;
26 import nom.tam.util.ArrayDataOutput;
27 import nom.tam.util.FitsFile;
28 import nom.tam.util.FitsIO;
29 import nom.tam.util.FitsInputStream;
30 import nom.tam.util.FitsOutputStream;
31 import nom.tam.util.RandomAccess;
32 import nom.tam.util.test.ThrowAnyException;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 import static nom.tam.fits.header.Checksum.CHECKSUM;
66 import static nom.tam.fits.header.Checksum.DATASUM;
67
68 @SuppressWarnings({"javadoc", "deprecation"})
69 public class ChecksumTest {
70
71 @Test
72 public void testChecksumDataFail() throws Exception {
73 Assertions.assertThrows(IllegalArgumentException.class, () -> FitsCheckSum.checksum(new byte[999]));
74 }
75
76 @Test
77 public void testChecksumDataFailException() throws Exception {
78 int[][] data = new int[][] {{1, 2}, {3, 4}, {5, 6}};
79 ImageData d = ImageHDU.encapsulate(data);
80 Header h = ImageHDU.manufactureHeader(d);
81 BasicHDU<?> bhdu = new ImageHDU(h, d) {
82
83 @Override
84 public ImageData getData() {
85 ThrowAnyException.throwIOException("fake");
86 return null;
87 }
88 };
89
90 Assertions.assertThrows(FitsException.class, () -> Fits.setChecksum(bhdu));
91 }
92
93 @Test
94 public void testChecksum() throws Exception {
95
96 FitsFactory.setLongStringsEnabled(false);
97
98 try (Fits f = new Fits()) {
99 int[][] data = new int[][] {{1, 2}, {3, 4}, {5, 6}};
100 BasicHDU<?> bhdu1 = FitsFactory.hduFactory(data);
101
102 BasicHDU<?> bhdu = bhdu1;
103 f.addHDU(bhdu);
104
105 Fits.setChecksum(bhdu);
106 ByteArrayOutputStream bs = new ByteArrayOutputStream();
107
108 try (FitsOutputStream bdos = new FitsOutputStream(bs)) {
109 f.write(bdos);
110 }
111
112 byte[] stream = bs.toByteArray();
113 long chk = Fits.checksum(stream);
114 int val = (int) chk;
115
116 Assertions.assertEquals(-1, val);
117 }
118 }
119
120 @Test
121 public void testCheckSumBasic() throws Exception {
122 try (FileInputStream in = new FileInputStream("src/test/resources/nom/tam/fits/test/test.fits")) {
123
124 try (Fits fits = new Fits()) {
125 try (FitsInputStream fin = new FitsInputStream(in)) {
126 fits.setStream(fin);
127 fits.read();
128 }
129 fits.setChecksum();
130 }
131 }
132 }
133
134 @Test
135 public void testCheckSum2() throws Exception {
136
137 FitsFactory.setLongStringsEnabled(false);
138
139 try (FileInputStream in = new FileInputStream("src/test/resources/nom/tam/fits/test/test.fits");
140 Fits fits = new Fits()) {
141 try (FitsInputStream fin = new FitsInputStream(in)) {
142 fits.setStream(fin);
143 fits.read();
144 }
145 fits.setChecksum();
146 Assertions.assertEquals(FitsIO.INTEGER_MASK, fits.getHDU(0).calcChecksum());
147 }
148 }
149
150
151 @Disabled
152 @Test
153 public void testIntegerOverflowChecksum() throws Exception {
154 byte[][] data = new byte[2][1440];
155 Arrays.fill(data[0], (byte) 17);
156 Arrays.fill(data[1], (byte) 17);
157 ImageData imageData = ImageHDU.encapsulate(data);
158 ImageHDU imageHdu = new ImageHDU(ImageHDU.manufactureHeader(imageData), imageData);
159
160 imageHdu.card(Standard.SIMPLE).comment("XXX").value(true);
161 imageHdu.setChecksum();
162 Assertions.assertEquals("CVfXFTeVCTeVCTeV", imageHdu.getHeader().card(CHECKSUM).card().getValue());
163 }
164
165 @Test
166 public void testCheckSumDeferred() throws Exception {
167 try (Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits")) {
168 ImageHDU im = (ImageHDU) fits.readHDU();
169
170 Assertions.assertTrue(im.getData().isDeferred());
171 fits.setChecksum();
172 Assertions.assertTrue(im.getData().isDeferred());
173 Assertions.assertEquals(FitsIO.INTEGER_MASK, im.calcChecksum());
174
175
176 im.getData().getData();
177 Assertions.assertFalse(im.getData().isDeferred());
178 fits.setChecksum();
179 Assertions.assertEquals(FitsIO.INTEGER_MASK, im.calcChecksum());
180 }
181 }
182
183 @Test
184 public void testCheckSumVerifyOfficial() throws Exception {
185 try (Fits fits = new Fits("src/test/resources/nom/tam/fits/test/checksum.fits")) {
186 fits.verifyIntegrity();
187
188
189 int n = fits.getNumberOfHDUs();
190
191 for (int i = 0; i < n; i++) {
192 Assertions.assertTrue(fits.getHDU(i).verifyDataIntegrity());
193 Assertions.assertTrue(fits.getHDU(i).verifyIntegrity());
194 }
195 }
196 }
197
198 @Test
199 public void testCheckSumVerifyModifiedHeaderFail() throws Exception {
200 File copy = new File("target/checksum-modhead.fits");
201
202 Files.copy(new File("src/test/resources/nom/tam/fits/test/checksum.fits").toPath(), copy.toPath(),
203 StandardCopyOption.REPLACE_EXISTING);
204
205 try (RandomAccessFile rf = new RandomAccessFile(copy, "rw")) {
206 rf.seek(FitsFactory.FITS_BLOCK_SIZE - 1);
207 rf.write('~');
208 }
209
210 try (Fits fits = new Fits(copy)) {
211 Assertions.assertThrows(FitsIntegrityException.class, () -> fits.verifyIntegrity());
212 }
213 }
214
215 @Test
216 public void testCheckSumVerifyModifiedDatasumFail() throws Exception {
217 File copy = new File("target/checksum-moddata.fits");
218
219 Files.copy(new File("src/test/resources/nom/tam/fits/test/checksum.fits").toPath(), copy.toPath(),
220 StandardCopyOption.REPLACE_EXISTING);
221
222 try (RandomAccessFile rf = new RandomAccessFile(copy, "rw")) {
223 rf.seek(rf.length() - 1);
224 rf.write('~');
225 }
226
227 try (Fits fits = new Fits(copy)) {
228 Assertions.assertThrows(FitsIntegrityException.class, () -> fits.verifyIntegrity());
229 }
230 }
231
232 @Test
233 public void testCheckSumVerifyNoSum() throws Exception {
234 try (Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits")) {
235 fits.verifyIntegrity();
236 Assertions.assertFalse(fits.getHDU(0).verifyIntegrity());
237 Assertions.assertFalse(fits.getHDU(0).verifyDataIntegrity());
238 }
239
240 }
241
242 @Test
243 public void testCheckSumVerifyStream() throws Exception {
244 try (Fits fits = new Fits(new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
245 fits.verifyIntegrity();
246 }
247
248 }
249
250 @Test
251 public void testDatasumVerifyStream() throws Exception {
252 try (Fits fits = new Fits(new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
253 Assertions.assertTrue(fits.getHDU(0).verifyDataIntegrity());
254 }
255 }
256
257 @Test
258 public void testCheckSumReadHDUStream() throws Exception {
259 try (FitsInputStream in = new FitsInputStream(
260 new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
261 ImageHDU hdu = new ImageHDU(null, null);
262 hdu.read(in);
263 hdu.verifyDataIntegrity();
264 hdu.verifyIntegrity();
265 }
266
267 }
268
269 @Test
270 public void testCheckSumReadHDUFile() throws Exception {
271 try (FitsFile in = new FitsFile("src/test/resources/nom/tam/fits/test/checksum.fits", "r")) {
272 ImageHDU hdu = new ImageHDU(null, null);
273 hdu.read(in);
274 hdu.verifyDataIntegrity();
275 hdu.verifyIntegrity();
276 }
277
278 }
279
280 @Test
281 public void testCStreamheckSumReads() throws Exception {
282 try (FitsInputStream in = new FitsInputStream(
283 new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
284 Assertions.assertEquals(0, in.nextChecksum());
285 for (int i = 0; i < FitsFactory.FITS_BLOCK_SIZE; i++) {
286 in.read();
287 }
288 Assertions.assertNotEquals(0, in.nextChecksum());
289 }
290
291 }
292
293 @Test
294 public void testCheckSumVerifyFail() throws Exception {
295 try (Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits")) {
296 fits.read();
297 fits.setChecksum();
298
299 ImageHDU im = (ImageHDU) fits.getHDU(0);
300
301 short[][] data = (short[][]) im.getData().getData();
302 data[0][0]++;
303
304
305 Assertions.assertNotEquals(FitsCheckSum.checksum(im.getData()), im.getStoredDatasum());
306 Assertions.assertNotEquals(FitsCheckSum.checksum(im), im.getStoredChecksum());
307 Assertions.assertNotEquals(fits.calcChecksum(0), im.getStoredChecksum());
308
309
310 Assertions.assertNotEquals(im.getData().calcChecksum(), im.getStoredDatasum());
311 Assertions.assertNotEquals(im.calcChecksum(), im.getStoredChecksum());
312 }
313 }
314
315 @Test
316 public void testCheckSumIncrement() throws Exception {
317 try (Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits")) {
318 fits.read();
319 fits.setChecksum();
320
321 ImageHDU im = (ImageHDU) fits.getHDU(0);
322 Header h = im.getHeader();
323
324 short[][] data = (short[][]) im.getData().getData();
325
326 data[0][0]++;
327
328 FitsCheckSum.setDatasum(h, FitsCheckSum.checksum(im.getData()));
329
330
331 Assertions.assertEquals(FitsCheckSum.checksum(im.getData()), im.getStoredDatasum());
332 Assertions.assertEquals(FitsIO.INTEGER_MASK, im.calcChecksum());
333
334
335 im.setChecksum();
336 Assertions.assertEquals(im.getData().calcChecksum(), im.getStoredDatasum());
337 Assertions.assertEquals(FitsIO.INTEGER_MASK, im.calcChecksum());
338 }
339 }
340
341 @Test
342 public void testCheckSumDecode() throws Exception {
343 long sum = 20220829;
344 Assertions.assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum)));
345 Assertions.assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum, false), false));
346 Assertions.assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum, true), true));
347 Assertions.assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.checksumEnc(sum, false), false));
348 Assertions.assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.checksumEnc(sum, true), true));
349 }
350
351 @Test
352 public void testCheckSumDecodeInvalidLength() throws Exception {
353 Assertions.assertThrows(IllegalArgumentException.class, () -> FitsCheckSum.decode(""));
354 }
355
356 @Test
357 public void testCheckSumDecodeInvalidChars() throws Exception {
358 byte[] b = new byte[16];
359 Arrays.fill(b, (byte) 0x2f);
360 Assertions.assertThrows(IllegalArgumentException.class, () -> FitsCheckSum.decode(new String(b)));
361 }
362
363 @Test
364 public void testCheckSumNoDatasum() throws Exception {
365 Assertions.assertThrows(FitsException.class, () -> FitsCheckSum.getStoredDatasum(new Header()));
366 }
367
368 @Test
369 public void testCheckSumNoChecksum() throws Exception {
370 Assertions.assertThrows(FitsException.class, () -> FitsCheckSum.getStoredChecksum(new Header()));
371 }
372
373 @Test
374 public void testCheckSumwWrap() throws Exception {
375 Assertions.assertEquals(0, FitsCheckSum.sumOf(Integer.MAX_VALUE, Integer.MAX_VALUE) & ~FitsIO.INTEGER_MASK);
376 }
377
378 @Test
379 public void testCheckSumAutoAdd() throws Exception {
380 Header h = new Header();
381 h.setSimple(true);
382 h.setBitpix(Bitpix.INTEGER);
383 h.setNaxes(0);
384 FitsCheckSum.checksum(h);
385 Assertions.assertFalse(h.containsKey(CHECKSUM));
386 }
387
388 @Test
389 public void testCheckSumKeep() throws Exception {
390 Header h = new Header();
391 h.setSimple(true);
392 h.setBitpix(Bitpix.INTEGER);
393 h.setNaxes(0);
394 h.addValue(DATASUM, "0");
395 h.addValue(CHECKSUM, "blah");
396 FitsCheckSum.checksum(h);
397 Assertions.assertEquals("blah", h.getStringValue(CHECKSUM));
398 }
399
400 @Test
401 public void testCheckSumMissingDatasum() throws Exception {
402 Header h = new Header();
403 h.setSimple(true);
404 h.setBitpix(Bitpix.INTEGER);
405 h.setNaxes(0);
406 h.addValue(CHECKSUM, "blah");
407 h.validate(true);
408 Assertions.assertFalse(h.containsKey(CHECKSUM));
409 }
410
411 @Test
412 public void testCheckSumSubtract() throws Exception {
413 long a = 20220829;
414 long b = 19740131;
415
416 long sum = FitsCheckSum.sumOf(a, b);
417
418 Assertions.assertEquals(b, FitsCheckSum.differenceOf(sum, a));
419 Assertions.assertEquals(a, FitsCheckSum.differenceOf(sum, b));
420 }
421
422 @Test
423 public void testSetChecksumFitsException() throws Exception {
424 ImageData data = new ImageData() {
425 @Override
426 public void write(ArrayDataOutput bdos) throws FitsException {
427 throw new FitsException("not implemented");
428 }
429 };
430
431 Header h = new Header();
432 h.setSimple(true);
433 h.setBitpix(Bitpix.INTEGER);
434 h.setNaxes(0);
435
436 ImageHDU im = new ImageHDU(h, data);
437
438 Assertions.assertThrows(FitsException.class, () -> FitsCheckSum.setChecksum(im));
439 }
440
441 @Test
442 public void testChecksumFitsLoaded() throws Exception {
443 try (Fits fits = new Fits(new File("src/test/resources/nom/tam/fits/test/test.fits"))) {
444 fits.read();
445 fits.setChecksum();
446 BasicHDU<?> hdu = fits.getHDU(0);
447 Header h = hdu.getHeader();
448 Assertions.assertTrue(h.containsKey(CHECKSUM));
449 Assertions.assertTrue(h.containsKey(DATASUM));
450 Assertions.assertNotEquals(0, hdu.getStoredChecksum());
451 Assertions.assertNotEquals(0, hdu.getStoredDatasum());
452 }
453 }
454
455 @Test
456 public void testChecksumFitsUnloaded() throws Exception {
457 try (Fits fits = new Fits(new File("src/test/resources/nom/tam/fits/test/test.fits"))) {
458 fits.setChecksum();
459 BasicHDU<?> hdu = fits.getHDU(0);
460 Header h = hdu.getHeader();
461 Assertions.assertTrue(h.containsKey(CHECKSUM));
462 Assertions.assertTrue(h.containsKey(DATASUM));
463 Assertions.assertNotEquals(0, hdu.getStoredChecksum());
464 Assertions.assertNotEquals(0, hdu.getStoredDatasum());
465 }
466 }
467
468 @Test
469 public void testChecksumFitsCreated() throws Exception {
470 int[][] data = new int[5][5];
471 data[0][0] = 1;
472
473 try (Fits fits = new Fits()) {
474 fits.addHDU(FitsFactory.hduFactory(data));
475 fits.setChecksum();
476 BasicHDU<?> hdu = fits.getHDU(0);
477 Header h = hdu.getHeader();
478 Assertions.assertTrue(h.containsKey(CHECKSUM));
479 Assertions.assertTrue(h.containsKey(DATASUM));
480 Assertions.assertNotEquals(0, hdu.getStoredChecksum());
481 Assertions.assertNotEquals(0, hdu.getStoredDatasum());
482 }
483 }
484
485 @Test
486 public void testChecksumNullFile() throws Exception {
487 Assertions.assertEquals(0, FitsCheckSum.checksum((RandomAccess) null, 0, 1000));
488 }
489
490 @Test
491 public void testDeferredChecksumRange() throws Exception {
492 int[][] im = new int[10][10];
493
494 for (int i = 0; i < 10; i++) {
495 for (int j = 0; j < 10; j++) {
496 im[i][j] = i + j;
497 }
498 }
499
500 ImageHDU hdu = (ImageHDU) FitsFactory.hduFactory(im);
501 long sum = hdu.getData().calcChecksum();
502
503 try (Fits fits = new Fits()) {
504 fits.addHDU(hdu);
505 fits.addHDU(hdu);
506 fits.write("target/checksumRangeTest.fits");
507 }
508
509 try (Fits fits = new Fits("target/checksumRangeTest.fits")) {
510 Assertions.assertEquals(sum, fits.calcDatasum(0));
511 fits.close();
512 }
513 }
514
515 @Test
516 public void testChecksumEncode() throws Exception {
517 Assertions.assertEquals("hcHjjc9ghcEghc9g", FitsCheckSum.encode(868229149L));
518 }
519
520 @Test
521 public void testChecksumDecode() throws Exception {
522 Assertions.assertEquals(868229149L, FitsCheckSum.decode("hcHjjc9ghcEghc9g"));
523 }
524 }