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("Bd5LEb5LBb5LBb5L", fits.getHDU(0).getHeader().getStringValue("CHECKSUM"));
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
170
171 im.getData().getData();
172 assertFalse("loaded before checksum", im.getData().isDeferred());
173 fits.setChecksum();
174
175 String sum2 = im.getHeader().getStringValue(CHECKSUM);
176 assertEquals(sum1, sum2);
177 }
178
179 @Test
180 public void testCheckSumVerifyOfficial() throws Exception {
181 Fits fits = new Fits("src/test/resources/nom/tam/fits/test/checksum.fits");
182 fits.verifyIntegrity();
183
184
185 int n = fits.getNumberOfHDUs();
186
187 for (int i = 0; i < n; i++) {
188 assertTrue(fits.getHDU(i).verifyDataIntegrity());
189 assertTrue(fits.getHDU(i).verifyIntegrity());
190 }
191 }
192
193 @Test(expected = FitsIntegrityException.class)
194 public void testCheckSumVerifyModifiedHeaderFail() throws Exception {
195 File copy = new File("target/checksum-modhead.fits");
196
197 Files.copy(new File("src/test/resources/nom/tam/fits/test/checksum.fits").toPath(), copy.toPath(),
198 StandardCopyOption.REPLACE_EXISTING);
199
200 RandomAccessFile rf = new RandomAccessFile(copy, "rw");
201 rf.seek(FitsFactory.FITS_BLOCK_SIZE - 1);
202 rf.write('~');
203 rf.close();
204
205 try (Fits fits = new Fits(copy)) {
206 fits.verifyIntegrity();
207 }
208 }
209
210 @Test(expected = FitsIntegrityException.class)
211 public void testCheckSumVerifyModifiedDatasumFail() throws Exception {
212 File copy = new File("target/checksum-moddata.fits");
213
214 Files.copy(new File("src/test/resources/nom/tam/fits/test/checksum.fits").toPath(), copy.toPath(),
215 StandardCopyOption.REPLACE_EXISTING);
216
217 RandomAccessFile rf = new RandomAccessFile(copy, "rw");
218 rf.seek(rf.length() - 1);
219 rf.write('~');
220 rf.close();
221
222 try (Fits fits = new Fits(copy)) {
223 fits.verifyIntegrity();
224 }
225 }
226
227 @Test
228 public void testCheckSumVerifyNoSum() throws Exception {
229 Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits");
230 fits.verifyIntegrity();
231 assertFalse(fits.getHDU(0).verifyIntegrity());
232 assertFalse(fits.getHDU(0).verifyDataIntegrity());
233
234 }
235
236 @Test
237 public void testCheckSumVerifyStream() throws Exception {
238 try (Fits fits = new Fits(new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
239 fits.verifyIntegrity();
240 }
241
242 }
243
244 @Test
245 public void testDatasumVerifyStream() throws Exception {
246 try (Fits fits = new Fits(new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
247 assertTrue(fits.getHDU(0).verifyDataIntegrity());
248 }
249 }
250
251 @Test
252 public void testCheckSumReadHDUStream() throws Exception {
253 try (FitsInputStream in = new FitsInputStream(
254 new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
255 ImageHDU hdu = new ImageHDU(null, null);
256 hdu.read(in);
257 hdu.verifyDataIntegrity();
258 hdu.verifyIntegrity();
259 }
260
261 }
262
263 @Test
264 public void testCheckSumReadHDUFile() throws Exception {
265 try (FitsFile in = new FitsFile("src/test/resources/nom/tam/fits/test/checksum.fits", "r")) {
266 ImageHDU hdu = new ImageHDU(null, null);
267 hdu.read(in);
268 hdu.verifyDataIntegrity();
269 hdu.verifyIntegrity();
270 }
271
272 }
273
274 @Test
275 public void testCStreamheckSumReads() throws Exception {
276 try (FitsInputStream in = new FitsInputStream(
277 new FileInputStream(new File("src/test/resources/nom/tam/fits/test/checksum.fits")))) {
278 assertEquals(0, in.nextChecksum());
279 for (int i = 0; i < FitsFactory.FITS_BLOCK_SIZE; i++) {
280 in.read();
281 }
282 assertNotEquals(0, in.nextChecksum());
283 }
284
285 }
286
287 @Test
288 public void testCheckSumVerifyFail() throws Exception {
289 Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits");
290 fits.read();
291 fits.setChecksum();
292
293 ImageHDU im = (ImageHDU) fits.getHDU(0);
294
295 short[][] data = (short[][]) im.getData().getData();
296 data[0][0]++;
297
298
299 assertNotEquals(FitsCheckSum.checksum(im.getData()), im.getStoredDatasum());
300 assertNotEquals(FitsCheckSum.checksum(im), im.getStoredChecksum());
301 assertNotEquals(fits.calcChecksum(0), im.getStoredChecksum());
302
303
304 assertNotEquals(im.getData().calcChecksum(), im.getStoredDatasum());
305 assertNotEquals(im.calcChecksum(), im.getStoredChecksum());
306 }
307
308 @Test
309 public void testCheckSumIncrement() throws Exception {
310 Fits fits = new Fits("src/test/resources/nom/tam/fits/test/test.fits");
311 fits.read();
312 fits.setChecksum();
313
314 ImageHDU im = (ImageHDU) fits.getHDU(0);
315 Header h = im.getHeader();
316
317 short[][] data = (short[][]) im.getData().getData();
318
319 data[0][0]++;
320
321 FitsCheckSum.setDatasum(h, FitsCheckSum.checksum(im.getData()));
322
323
324 assertEquals(FitsCheckSum.checksum(im.getData()), im.getStoredDatasum());
325 assertEquals(FitsCheckSum.checksum(im), im.getStoredChecksum());
326 assertEquals(fits.calcChecksum(0), im.getStoredChecksum());
327
328
329 im.setChecksum();
330 assertEquals(im.getData().calcChecksum(), im.getStoredDatasum());
331 assertEquals(im.calcChecksum(), im.getStoredChecksum());
332 }
333
334 @Test
335 public void testCheckSumDecode() throws Exception {
336 long sum = 20220829;
337 assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum)));
338 assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum, false), false));
339 assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.encode(sum, true), true));
340 assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.checksumEnc(sum, false), false));
341 assertEquals(sum, FitsCheckSum.decode(FitsCheckSum.checksumEnc(sum, true), true));
342 }
343
344 @Test(expected = IllegalArgumentException.class)
345 public void testCheckSumDecodeInvalidLength() throws Exception {
346 FitsCheckSum.decode("");
347 }
348
349 @Test(expected = IllegalArgumentException.class)
350 public void testCheckSumDecodeInvalidChars() throws Exception {
351 byte[] b = new byte[16];
352 Arrays.fill(b, (byte) 0x2f);
353 FitsCheckSum.decode(new String(b));
354 }
355
356 @Test(expected = FitsException.class)
357 public void testCheckSumNoDatasum() throws Exception {
358 FitsCheckSum.getStoredDatasum(new Header());
359 }
360
361 @Test(expected = FitsException.class)
362 public void testCheckSumNoChecksum() throws Exception {
363 FitsCheckSum.getStoredChecksum(new Header());
364 }
365
366 @Test
367 public void testCheckSumwWrap() throws Exception {
368 assertEquals(0, FitsCheckSum.sumOf(Integer.MAX_VALUE, Integer.MAX_VALUE) & ~FitsIO.INTEGER_MASK);
369 }
370
371 @Test
372 public void testCheckSumAutoAdd() throws Exception {
373 Header h = new Header();
374 h.setSimple(true);
375 h.setBitpix(Bitpix.INTEGER);
376 h.setNaxes(0);
377 FitsCheckSum.checksum(h);
378 assertTrue(h.containsKey(CHECKSUM));
379 }
380
381 @Test
382 public void testCheckSumKeep() throws Exception {
383 Header h = new Header();
384 h.setSimple(true);
385 h.setBitpix(Bitpix.INTEGER);
386 h.setNaxes(0);
387 h.addValue(CHECKSUM, "blah");
388 FitsCheckSum.checksum(h);
389 assertEquals("blah", h.getStringValue(CHECKSUM));
390 }
391
392 @Test
393 public void testCheckSumSubtract() throws Exception {
394 long a = 20220829;
395 long b = 19740131;
396
397 long sum = FitsCheckSum.sumOf(a, b);
398
399 assertEquals(b, FitsCheckSum.differenceOf(sum, a));
400 assertEquals(a, FitsCheckSum.differenceOf(sum, b));
401 }
402
403 @Test(expected = FitsException.class)
404 public void testSetChecksumFitsException() throws Exception {
405 ImageData data = new ImageData() {
406 @Override
407 public void write(ArrayDataOutput bdos) throws FitsException {
408 throw new FitsException("not implemented");
409 }
410 };
411
412 Header h = new Header();
413 h.setSimple(true);
414 h.setBitpix(Bitpix.INTEGER);
415 h.setNaxes(0);
416
417 ImageHDU im = new ImageHDU(h, data);
418 FitsCheckSum.setChecksum(im);
419 }
420
421 @Test
422 public void testChecksumFitsLoaded() throws Exception {
423 Fits fits = new Fits(new File("src/test/resources/nom/tam/fits/test/test.fits"));
424 fits.read();
425 fits.setChecksum();
426 BasicHDU<?> hdu = fits.getHDU(0);
427 Header h = hdu.getHeader();
428 assertTrue(h.containsKey(CHECKSUM));
429 assertTrue(h.containsKey(DATASUM));
430 assertNotEquals(0, hdu.getStoredChecksum());
431 assertNotEquals(0, hdu.getStoredDatasum());
432 }
433
434 @Test
435 public void testChecksumFitsUnloaded() throws Exception {
436 Fits fits = new Fits(new File("src/test/resources/nom/tam/fits/test/test.fits"));
437 fits.setChecksum();
438 BasicHDU<?> hdu = fits.getHDU(0);
439 Header h = hdu.getHeader();
440 assertTrue(h.containsKey(CHECKSUM));
441 assertTrue(h.containsKey(DATASUM));
442 assertNotEquals(0, hdu.getStoredChecksum());
443 assertNotEquals(0, hdu.getStoredDatasum());
444 }
445
446 @Test
447 public void testChecksumFitsCreated() throws Exception {
448 int[][] data = new int[5][5];
449 data[0][0] = 1;
450 Fits fits = new Fits();
451 fits.addHDU(FitsFactory.hduFactory(data));
452 fits.setChecksum();
453 BasicHDU<?> hdu = fits.getHDU(0);
454 Header h = hdu.getHeader();
455 assertTrue(h.containsKey(CHECKSUM));
456 assertTrue(h.containsKey(DATASUM));
457 assertNotEquals(0, hdu.getStoredChecksum());
458 assertNotEquals(0, hdu.getStoredDatasum());
459 }
460
461 @Test
462 public void testChecksumNullFile() throws Exception {
463 assertEquals(0, FitsCheckSum.checksum((RandomAccess) null, 0, 1000));
464 }
465
466 @Test
467 public void testDeferredChecksumRange() throws Exception {
468 int[][] im = new int[10][10];
469
470 for (int i = 0; i < 10; i++) {
471 for (int j = 0; j < 10; j++) {
472 im[i][j] = i + j;
473 }
474 }
475
476 ImageHDU hdu = (ImageHDU) FitsFactory.hduFactory(im);
477 long sum = hdu.getData().calcChecksum();
478
479 Fits fits = new Fits();
480 fits.addHDU(hdu);
481 fits.addHDU(hdu);
482
483 fits.write("target/checksumRangeTest.fits");
484 fits.close();
485
486 fits = new Fits("target/checksumRangeTest.fits");
487 assertEquals(sum, fits.calcDatasum(0));
488 fits.close();
489 }
490 }