Hallo Forum,
ich habe PNG (libpng) auf meinem STM32 zum laufen gebracht. Darin
enthalten ist ja die zlib und diese bringt die adler32() Prüfsumme mit.
Funktioniert soweit prima, bis auf das die Prüfsumme nicht mit der Summe
des png-Bildes übereinstimmt.
Wenn ich die Überprüfung abschalte (ganz am Ende) wird der Bildinhalt
korrekt ausgegeben, keine Fehler.
Hat jemand sowas schonmal gemacht? Gibts da irgendwas zu beachten?
1 | #define BASE 65521 /* largest prime smaller than 65536 */
|
2 | #define NMAX 5552
|
3 | #define MOD(a) a %= BASE
|
4 | #define MOD28(a) a %= BASE
|
5 |
|
6 | #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
7 | #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
8 | #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
9 | #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
10 | #define DO16(buf) DO8(buf,0); DO8(buf,8);
|
11 |
|
12 | u32 adler32(u32 adler, const u8 *buf, u32 len)
|
13 | {
|
14 | u32 sum2;
|
15 | u32 n;
|
16 |
|
17 | /* split Adler-32 into component sums */
|
18 | sum2 = (adler >> 16) & 0xffff;
|
19 | adler &= 0xffff;
|
20 |
|
21 | /* in case user likes doing a byte at a time, keep it fast */
|
22 | if (len == 1) {
|
23 | adler += buf[0];
|
24 | if (adler >= BASE)
|
25 | adler -= BASE;
|
26 | sum2 += adler;
|
27 | if (sum2 >= BASE)
|
28 | sum2 -= BASE;
|
29 | return adler | (sum2 << 16);
|
30 | }
|
31 |
|
32 | /* initial Adler-32 value (deferred check for len == 1 speed) */
|
33 | if (buf == NULL)
|
34 | return 1L;
|
35 |
|
36 | /* in case short lengths are provided, keep it somewhat fast */
|
37 | if (len < 16) {
|
38 | while (len--) {
|
39 | adler += *buf++;
|
40 | sum2 += adler;
|
41 | }
|
42 | if (adler >= BASE)
|
43 | adler -= BASE;
|
44 | MOD28(sum2); /* only added so many BASE's */
|
45 | return adler | (sum2 << 16);
|
46 | }
|
47 |
|
48 | /* do length NMAX blocks -- requires just one modulo operation */
|
49 | while (len >= NMAX) {
|
50 | len -= NMAX;
|
51 | n = NMAX / 16; /* NMAX is divisible by 16 */
|
52 | do {
|
53 | DO16(buf); /* 16 sums unrolled */
|
54 | buf += 16;
|
55 | } while (--n);
|
56 | MOD(adler);
|
57 | MOD(sum2);
|
58 | }
|
59 |
|
60 | /* do remaining bytes (less than NMAX, still just one modulo) */
|
61 | if (len) { /* avoid modulos if none remaining */
|
62 | while (len >= 16) {
|
63 | len -= 16;
|
64 | DO16(buf);
|
65 | buf += 16;
|
66 | }
|
67 | while (len--) {
|
68 | adler += *buf++;
|
69 | sum2 += adler;
|
70 | }
|
71 | MOD(adler);
|
72 | MOD(sum2);
|
73 | }
|
74 |
|
75 | /* return recombined sums */
|
76 | return adler | (sum2 << 16);
|
77 | }
|
Initialisieren muss man den ja scheinbar nicht, denn im case "HEAD"
steht:
1 | Tracev((stderr, "inflate: zlib header ok\n"));
|
2 | strm->adler = state->check = adler32(0L, NULL, 0);
|