Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [C]Interpretare dati letti da un file binario...

    Salve,
    il problema nel caso specifico sta nel leggere l'header di un file bmp ed estrapolare le informazioni riguardanti la bitmap.

    Il mio problema è strano: leggendo l'header byte per byte, la maggior parte dei campi viene letto in modo corretto, mentre altri vengono letti con valori sbagliati. Mi spiego meglio:
    quello che faccio io in pratica è aprire il file bmp in lettura, leggere il campo dell'header che indica il numero dei byte totali dell'header stesso, quindi usare questa informazione per copiare l'intero header in un vettore di char, e scansionare poi questo vettore byte per byte alla ricerca delle informazioni che mi interessano (es: le dimensioni della bitmap, la profondità di colore dei pixel, etc, etc).
    Per verificare che l'header fosse stato copiato in maniera corretta nell'array di char, ho fatto un banalissimo ciclo for in cui facevo stampare in squenza tutti i byte come cifre esadecimali, e quindi ho confrontato lo stampato con quello che mi mostra un editor esadecimale.
    Ebbene, i due header sembra differiscano solo per alcuni byte, e non riesco proprio a capirne il motivo.

    Vi incollo qui di seguito il codice che ho scritto, e i due header, così come me lo mostrano il mio outputo e l'editor esadecimale:

    codice:
    #include <stdio.h>
    #include <math.h>
    #include <STDDEF.H>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    
    
    void salva_header (char[], char*, int);
    int header_lenght (char[]);
    
    
    
    int main (int num, char** arg)
    {
    	int offset;
    	int n;
    	char* header;
    	int n_cluster;
    	offset = header_lenght (arg[1]);
    
    	printf("\nL'header sarà lungo %d bytes\n", offset);
            header = malloc(offset);
    	salva_header (arg[1], header, offset);
    
    	printf("\nL'header completo del bitmap è dato dai seguenti byte:\n\n");
    	for(n = 0; n<offset; n++)
              printf("%X ", header[n]);
    	return 0;
    }
    
    
    void salva_header (char nome_file[], char* header, int offset)
    {
        int a;
        FILE* bitmap = fopen(nome_file, "r");
        rewind(bitmap);
        fread (header, 1, offset, bitmap);
        fclose(bitmap);
    }
    
    int header_lenght (char nome_file[])
    {
    	int offset;
    	FILE* bitmap = fopen(nome_file, "r");
    	fseek (bitmap, 10, 0);
    	fread (&offset, 4, 1, bitmap);
    	fclose(bitmap);
    	return offset;
    }
    Il mio output:

    42 4D FFFFFFE6 71 B 0 0 0 0 0 36 0 0 0 28 0 0 0 FFFFFFF4 1 0 0 FFFFFFF4 1 0 0 1
    0 18 0 0 0 0 0 FFFFFFB0 71 B 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    L'output dell'editor esadecimale:

    42 4D E6 71 0B 00 00 00 00 00 36 00 00 00 28 00 00 00 F4 01 00 00 F4 01 00 00 01 00 18 00 00 00 00 00 B0 71 0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Le uniche differenze sono in quelle "FFFFFFF" davanti ai valori del secondo, diciottesimo, ventiduesimo e trentaquattresimo byte. E guardacaso, proprio il diciottesimo ed il trentaduesimo byte sono quelli che indicano le dimensioni del bitmap, che è quello che più mi serve...

    Spero possiate darmi una mano.

    Grazie a tutti.

    Ciao

  2. #2

    Re: [C]Interpretare dati letti da un file binario...

    prova il seguente:
    Codice PHP:
    /*
    * 25 april 2008 (i am working)
    *
    * Compiled and tested by MacApp with:
    * i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
    *
    * output:
    * aUnsignedChar: E6;
    * aChar: FFFFFFE6;
    *
    */

    #include <stdio.h>

    int main (void){
        const 
    unsigned char aUnsignedChar = -26;
        const 
    char aChar = -26;
        
    printf ("aUnsignedChar: %X;\n"aUnsignedChar);
        
    printf ("aChar: %X;\n"aChar);
        return 
    0;


  3. #3
    Grazie, non c'è stato neanche bisogno di compilarlo, appena ho letto "unsigned", ho capito il mio errore...

    Grazie ancora, ciao

  4. #4
    Visto che ci sono chiedo anche un'altra cosa:

    come faccio a copiare due byte dell'array di unsigned char in un int? Se non sbaglio facendo:

    int a = (int) header[4];

    mi copia solo il quarto byte, ignorando il quinto.

    Grazie ancora! Ciao!

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da MonsterMash
    come faccio a copiare due byte dell'array di unsigned char in un int?
    Non fai prima (molto prima) ad usare delle strutture che rappresentano i vari header??
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Originariamente inviato da andbin
    Non fai prima (molto prima) ad usare delle strutture che rappresentano i vari header??
    Il problema è che non conosco a priori la dimensione dell'header, ne' i campi presenti. A quanto ho visto ci sono campi opzionali che a volte vengono inseriti, ed altre no. Per cui non saprei come strutturare la struct per fargli contenere l'intero header... E così uso una malloc per allocare la memoria che mi serve a contenere l'header, e posso farlo solo dopo aver letto nel campo specifico la sua lunghezza.

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da MonsterMash
    Il problema è che non conosco a priori la dimensione dell'header, ne' i campi presenti.
    Se intendi lavorare direttamente con i dati binari dei file bitmap (.bmp), allora devi conoscere le sue specifiche e il suo formato. E le strutture dati (header ecc...) sono ben precise, nonché documentate e reperibili in rete un po' dovunque!!

    Originariamente inviato da MonsterMash
    E così uso una malloc per allocare la memoria che mi serve a contenere l'header
    Fatica sprecata ... almeno per gli header che sono una "manciata" di byte.

    In Windows, se si lavora con il Platform SDK, ci sono già le strutture dati belle che pronte. Vuoi vedere come è quella iniziale di testata del file??

    Ecco:
    http://msdn2.microsoft.com/en-us/library/ms532321.aspx
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #8
    Originariamente inviato da MonsterMash
    come faccio a copiare due byte dell'array di unsigned char in un int? Se non sbaglio facendo:

    int a = (int) header[4];

    mi copia solo il quarto byte, ignorando il quinto.

    Grazie ancora! Ciao!
    Attenzione che gli int potrebbero essere (normalmente lo sono) a 4 byte NON a 2, verifica con sizeof.
    Se vuoi degli int a 2 byte allora usa degli short.
    Per copiare essenzialmente converti l'indirizzo del primo carattere in un puntatore a int e quindi lo valorizzi.

    Ad esempio:

    Codice PHP:
    /*
    * 25 april 2008 (i am working)
    *
    * Compiled and tested by MacApp with:
    * i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
    *
    * output:
    * aInt1: 1234;
    * aInt2: 1234;
    *
    */

    #include <stdio.h>
    #include <string.h>

    int main (void){
        const 
    int aIntSource 1234;
        const 
    char aArray = (const char *) &aIntSource;
        const 
    int aInt1 = *((const int *) &aArray [0]);
        
    int aInt2;
        
    memcpy (&aInt2aArraysizeof (aInt2));
        
    printf ("aInt1: %d;\n"aInt1);
        
    printf ("aInt2: %d;\n"aInt2);
        return 
    0;


  9. #9
    Originariamente inviato da MacApp
    Attenzione che gli int potrebbero essere (normalmente lo sono) a 4 byte NON a 2, verifica con sizeof.
    Se vuoi degli int a 2 byte allora usa degli short.
    Per copiare essenzialmente converti l'indirizzo del primo carattere in un puntatore a int e quindi lo valorizzi.

    Ad esempio:

    Codice PHP:
    /*
    * 25 april 2008 (i am working)
    *
    * Compiled and tested by MacApp with:
    * i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
    *
    * output:
    * aInt1: 1234;
    * aInt2: 1234;
    *
    */

    #include <stdio.h>
    #include <string.h>

    int main (void){
        const 
    int aIntSource 1234;
        const 
    char aArray = (const char *) &aIntSource;
        const 
    int aInt1 = *((const int *) &aArray [0]);
        
    int aInt2;
        
    memcpy (&aInt2aArraysizeof (aInt2));
        
    printf ("aInt1: %d;\n"aInt1);
        
    printf ("aInt2: %d;\n"aInt2);
        return 
    0;

    Grazie mille! Non mi ricordavo la funzione memcpy (sono anni che non programmo più)! Ora funziona tutto.
    Effettivamente gli interi sono a 4 byte, e a me serve che lo siano... mi ero spiegato male prima .

    A andbin dico che proprio leggendo quel documento vedo che non c'è una regola fissa sui campi dell'header di un file bmp. Può ad esempio mancare la sezione HeaderCoreInfo, o il campo riguardante la palette dei colori. Per cui mi conviene credo fare come sto facendo. Copio tutto senza preoccuparmi di cosa ci sia dentro...

    Grazie a tutti!

    Ciao!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.