zlib: adler32 Prüfsummer rechnet falsch

OP #5512508
Lesenswert?
• ▲
▼
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);
Gast #5512509
Lesenswert?
• ▲
▼
Auf PC und Controller mit den gleichen Eingabedaten aufrufen, bei jedem 
Schritt die Zwischenergebnisse ausgeben und vergleichen? Möglicherweise 
ein Problem mit unportablem Integer Verhalten. Mal mit "-Wall -Wextra 
-pedantic" kompilieren, vielleicht findet der Compiler das ja sogar...

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.