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