Ripara ora
- Trascina il file
- La riparazione avviene in locale
- Scarica il risultato
Quando un visualizzatore, pngcheck, libpng o ImageMagick rifiuta un PNG con un "CRC error" — quasi sempre libpng error: IDAT: CRC error — significa che i byte di un chunk non corrispondono più alla somma di controllo salvata accanto a loro. Il file è cambiato dopo essere stato scritto. Trascina il .png qui sopra e lo strumento analizza la struttura dei chunk nel tuo browser, ricalcola ogni CRC-32 per capire quale chunk si è rotto davvero, e ricostruisce un file valido attorno a ciò che sopravvive — dicendoti con onestà se il tuo caso è del tipo deterministico e senza perdita o del tipo parziale, senza che l'immagine lasci mai il tuo dispositivo.
Cos'è realmente un "CRC error" in un PNG
Un PNG inizia con una firma fissa di 8 byte — i byte 89 50 4E 47 0D 0A 1A 0A — e tutto ciò che segue è una catena di chunk. Ogni chunk ha la stessa disposizione: una lunghezza di 4 byte big-endian (che conta solo i dati), un tipo ASCII di 4 byte come IHDR, IDAT o IEND, i dati veri e propri, e un CRC-32 finale di 4 byte. Questa somma di controllo si calcola sul tipo e sui dati del chunk — non sulla sua lunghezza — usando il polinomio standard ISO-3309 / ITU-T V.42 (nella sua forma riflessa, 0xEDB88320). Un "CRC error" significa che un decodificatore ha ricalcolato quel valore e non coincideva con i quattro byte sul disco: la prova che i byte del chunk sono cambiati da quando il file è stato scritto.
Ogni strumento lo esprime a modo suo. pngcheck stampa CRC error in chunk IDAT (computed 12ab34cd, expected 89ef01ab); libpng solleva libpng error: IDAT: CRC error o il più laconico Read Error; ImageMagick lascia trasparire lo strato zlib sottostante come IDAT: invalid distance too far back; e un browser semplicemente non disegna nulla. Il chunk citato nel messaggio ti dice cosa c'è in gioco. Un CRC error su un chunk ausiliario (ancillary) — tEXt, gAMA, pHYs, sRGB, il cui tipo inizia con una minuscola — è cosmetico e l'immagine si decodifica comunque. Un CRC error su un chunk critico (i quattro il cui tipo inizia con una maiuscola: IHDR, PLTE, IDAT, IEND) è ciò che davvero impedisce al file di aprirsi.
I tre chunk che trasportano l'immagine sono IHDR, IDAT e IEND. IHDR ha esattamente 13 byte: larghezza e altezza (4 byte ciascuna), poi la profondità di bit, il tipo di colore (0 scala di grigi, 2 colore reale, 3 indicizzato, 4 grigi+alfa, 6 RGBA), il metodo di compressione, il metodo di filtro e il metodo di interlacciamento. IDAT contiene i pixel compressi e spesso è suddiviso tra diversi chunk consecutivi che vanno concatenati prima di decomprimere. IEND è un marcatore vuoto, di lunghezza zero, che indica che il file è completo. Lo strumento legge questa struttura in locale, verifica ogni CRC e individua il chunk colpevole prima di cambiare un solo byte.
Il danno che un PNG può annullare con esattezza
Poiché ogni chunk porta la propria somma di controllo, un'intera categoria di danni in un PNG ha una correzione deterministica — la risposta corretta si conosce dalla matematica, non si tira a indovinare.
Un CRC sbagliato su dati intatti. Il guasto più benigno: i dati del chunk sono corretti byte per byte, ma il loro CRC-32 salvato è obsoleto — risultato tipico di un editor che ha riscritto i dati senza aggiornare la somma di controllo, o di un singolo bit invertito all'interno dello stesso campo di 4 byte del CRC. Ricalcolare il CRC a partire dal tipo e dai dati e riscriverlo rende il file di nuovo valido, senza alcuna perdita. La somma di controllo era l'unica cosa sbagliata.
Dimensioni azzerate o mescolate. Se la larghezza o l'altezza in IHDR si corrompe, nessun decodificatore può allocare un'area di disegno e il file non si apre — spesso come libpng error: Invalid IHDR data. Ma IHDR conserva il proprio CRC, calcolato quando le dimensioni erano ancora corrette. Questo trasforma il recupero in una ricerca: si provano coppie candidate di larghezza/altezza, si ricalcola il CRC-32 del chunk di 13 byte per ciascuna, e ci si ferma quando coincide con il valore salvato. Le dimensioni originali escono direttamente dall'aritmetica, esatte, senza tirare a indovinare.
Pasticci con i fine riga e con il bit alto. La firma di 8 byte è stata progettata come trappola per la corruzione in modalità testo: la coppia 0D 0A intercetta una conversione CRLF→LF, il 0A finale intercetta LF→CRLF, e l'89 iniziale (con il bit alto attivo) intercetta un trasferimento a 7 bit che lo ha eliminato. Quando un PNG è passato per un client FTP in modalità ASCII, o per uno script che lo ha riscritto come testo, la sostituzione è coerente e reversibile — si annulla la trasformazione e i byte originali tornano in tutto il file, non solo nella firma.
IDAT, deflate e dove si ferma il recupero
All'interno dei chunk IDAT i pixel formano un unico flusso di dati zlib: un'intestazione di 2 byte (di solito 78 9C), un corpo compresso con deflate e una somma di controllo Adler-32 di 4 byte alla fine. Prima di comprimere, ogni linea di scansione (scanline) è preceduta da un byte di tipo di filtro (0 None, 1 Sub, 2 Up, 3 Average, 4 Paeth) che predice ogni pixel a partire dai suoi vicini. Le righe si scrivono dall'alto verso il basso, e questo singolo fatto decide cosa si può recuperare una volta che sono danneggiati i dati stessi — non solo una somma di controllo.
Troncamento. La rottura più comune: un download che si è interrotto in anticipo, una copia interrotta togliendo un'unità, un arresto imprevisto a metà scrittura. La parte anteriore del file è intatta e la coda — di solito compresi IEND e l'Adler-32 — semplicemente manca, così i decodificatori segnalano EOF while reading IDAT o l'incorrect data check di zlib. Poiché deflate decodifica dall'alto verso il basso, lo strumento recupera ogni linea di scansione completa fino al taglio, scrive un IEND nuovo e valido, e ti consegna un parziale onesto: i tuoi pixel reali, fin dove arrivano i byte.
Corruzione a metà flusso. Quando il danno cade all'interno del corpo deflate e non alla fine, il limite è duro. Deflate è un flusso continuo senza marcatori periodici di risincronizzazione, così non appena inflate incontra un byte difettoso perde il filo — vedrai invalid distance too far back, invalid literal/length code o invalid block type — e tutto ciò che segue si decodifica come rumore. Un singolo byte corrotto a metà altezza può costare tutte le righe sottostanti, non solo una linea. Lo strumento conserva le righe che si sono decodificate in modo pulito sopra la ferita; non può ricucire il flusso al di sotto, e un file interlacciato (Adam7) perde inoltre le passate successive che avrebbero affinato la parte inferiore dell'immagine.
Due casi persi, a essere onesti. Un file di 0 byte o tutto a zeri non ha immagine da ricostruire — questo è un problema di recupero dati dallo storage, non una riparazione. E quando i dati di un chunk (e non solo il suo CRC) sono stati sovrascritti, la somma di controllo può dimostrare il danno ma non invertirlo mai. Tutto quanto sopra viene eseguito interamente nella scheda del tuo browser — l'analizzatore è TypeScript senza dipendenze — così un PNG che magari è una foto privata, uno screenshot o un documento scansionato non viene mai copiato su un server: apri la scheda Rete (Network) e conferma che escono 0 byte.
Cosa può e cosa non può riparare
Può riparare
- Un chunk il cui CRC-32 salvato non coincide più con il suo tipo+dati mentre i byte sono intatti — si ricalcola e si riscrive senza alcuna perdita
- Un PNG con la larghezza/altezza di IHDR azzerata o mescolata — le dimensioni originali si recuperano a forza bruta a partire dal CRC di IHDR salvato
- File rovinati dalla conversione dei fine riga CRLF↔LF o dall'eliminazione del bit alto in un trasferimento in modalità testo — si annulla la sostituzione reversibile
- Un PNG troncato a cui mancano la coda e l'IEND — si recuperano le linee di scansione superiori che si sono decodificate e si scrive un IEND valido
- Le righe sopra un impatto a metà di IDAT — si conserva tutto ciò che deflate ha decodificato in modo pulito prima del byte corrotto
Non può riparare
- Le righe sotto una corruzione a metà di IDAT — deflate non può risincronizzarsi, così tutto ciò che segue il byte danneggiato si decodifica come rumore
- Le linee di scansione successive al taglio in un file troncato — quei byte non sono mai stati scritti sul disco
- Un file di 0 byte o tutto a zeri — non c'è immagine da ricostruire; è un problema di recupero dati, non una riparazione
- I colori esatti di un chunk i cui dati (non solo il suo CRC) sono stati sovrascritti — il CRC dimostra solo il danno, non può invertirlo
- Le passate interlacciate (Adam7) successive che restano sotto una rottura a metà flusso — il dettaglio che aggiungono è andato perso
Se una riparazione fallisce, ti diciamo perché (dati mancanti rispetto a struttura danneggiata), e non ti viene mai addebitato nulla per una riparazione fallita.