PDA

Visualizza la versione completa : [C] Destrutturazione e ristritturazione bitmap: problema!


MonsterMash
18-05-2008, 12:17
Dunque, io ho bisogno di scomporre una bitmap in celle di dimensione data da una costante, fare delle elaborazioni su queste celle, e quindi ricreare la bitmap con le celle elaborate.
Il mio problema Ŕ che anche senza modificare le celle, semplicemente leggendole da un file origine, e scrivendole in un file destinazione, la bitmap che ne viene fuori risulta distorta rispetto all'originale.

Qui di seguito vi allego un codice che dovrebbe solo leggere in sequenza tutte le celle dal file origine, e scriverle nel file destinazione.
All'apparenza sembra un problema di posizionamento nella lettura e/o scrittura dei byte, ma non riesco a trovare l'errore. Non dovrebbe invece essere un problema di interpretazione dei dati, perchŔ se leggo un singolo pixel alla volta (impostando DIM_CELLA a 1), il bitmap destinazione non risulta distorto.
Il programmino funziona solo con bitmap da 24 bit per pixel non compresse, e le cui dimensioni (x ed y) siano multiple di 4, o in generale al valore che si da' alla costante DIM_CELLA.

Grazie a tutti.


#include <stdio.h>
#include <math.h>
#include <STDDEF.H>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <time.h>

#define DIM_CELLA 4 //Lato in pixel di una cella



typedef struct
{
unsigned char pixel[3];
} punto;

typedef struct
{
unsigned int pos;
punto cella[DIM_CELLA][DIM_CELLA];
} struct_cella;



void salva_header (char[], unsigned char*, int);
int header_lenght (char[]);
int get_cella(struct_cella*, char*, int, int, int);
void scrivi_cella(struct_cella*, char*, int, int, int);
void crea_bitmap (char[], char[], int, int, int);



int main (int num, char** arg)
{
int offset, num_celle;
int x, y, m;
unsigned char* header;
FILE* bitmap;
struct_cella cella;
if (num != 3)
{
printf("\nUtilizzo: %s origine.bmp destinazione.bmp\n\n", arg[0]);
return 0;
}
offset = header_lenght (arg[1]); //Determina la lunghezza dell'header del bitmap passato come primo argomento
printf("\nIl bitmap comincerÓ al byte: %d\n", offset);
header = malloc(offset);
salva_header (arg[1], header, offset); //Salva in memoria l'header del bitmap passato come primo argomento
memcpy (&x, &header[18], 4); //Salva in x la larghezza in pixel del bitmap passato
memcpy (&y, &header[22], 4); //Salva in y l'altezza in pixel del bitmap passato

num_celle = (x*y/(DIM_CELLA*DIM_CELLA)); //Calcola il numero delle celle contenuto nel bitmap

printf("\nAltezza del bitmap: %d\n", x);
printf("\nLarghezza del bitmap: %d\n", y);

crea_bitmap(arg[2], header, x, y, offset); //Crea un nuovo file il cui nome Ŕ il secondo argomento. In testa al file copia l'header del bitmap
for (m=0;m<num_celle;m++)
{
cella.pos=m;
printf("\nCella %d di %d", m, num_celle);
get_cella (&cella, arg[1], offset, x, y); //Legge la m-esima cella dal bitmap di origine
scrivi_cella (&cella, arg[2], offset, x, y); //Scrive la cella appena letta nel bitmap di destinazione
}
return 0;
}


void crea_bitmap (char nome_file[], char header[], int x, int y, int offset)
{
FILE* bitmap = fopen(nome_file, "w");
fwrite(header, offset, 1, bitmap);
fclose(bitmap);
}


int get_cella(struct_cella* cella, char* nome_file, int offset, int x, int y)
{
int i, k, j;
int pos_x, pos_y;
FILE* bitmap;
pos_x = (DIM_CELLA*cella->pos)%x; //pos_x e pos_y determinano la posizione sul file del primo byte
pos_y = DIM_CELLA * ((int)(DIM_CELLA*cella->pos/x)); //della cella che sto andando a leggere
bitmap = fopen(nome_file, "r");
fseek(bitmap, offset + 3*(x*pos_y + pos_x), 0);
for(i=0;i<DIM_CELLA;i++)
{
for(k=0;k<DIM_CELLA;k++)
for(j=0;j<3;j++)
fscanf(bitmap, "%c", &cella->cella[i][k].pixel[j]); //Leggo tutti i byte della riga della cella
fseek(bitmap, 3*(x - DIM_CELLA), SEEK_CUR); //Mi posiziono sulla riga successiva della cella
}
fclose(bitmap);
return 1;
}


void scrivi_cella(struct_cella* cella, char* nome_file, int offset, int x, int y)
{
int i, k, j;
int pos_x, pos_y;
pos_x = (DIM_CELLA*cella->pos)%x; //pos_x e pos_y determinano la posizione sul file del primo byte
pos_y = DIM_CELLA * ((int) (DIM_CELLA*cella->pos/x)); //della cella che sto andando a scrivere
FILE* bitmap = fopen(nome_file, "rb+");
FILE* log;
fseek(bitmap, offset + 3*(x*pos_y + pos_x), 0); //Mi posiziono sul primo byte da scrivere
for(i=0;i<DIM_CELLA;i++)
{
for(k=0;k<DIM_CELLA;k++)
for(j=0;j<3;j++)
fprintf(bitmap, "%c", cella->cella[i][k].pixel[j]); //Scrivo tutti i byte della riga della cella
fseek(bitmap, 3 * (x - DIM_CELLA), SEEK_CUR); //Mi posiziono sulla riga successiva della cella
}
fclose(bitmap);
}



void salva_header (char nome_file[], unsigned char* header, int offset)
{
FILE* bitmap = fopen(nome_file, "r");
fread (header, offset, 1, bitmap);
fclose(bitmap);
}


int header_lenght (char nome_file[])
{
int offset;
char offset_c[5];
FILE* bitmap = fopen(nome_file, "r");
fseek (bitmap, 10, 0); //A partire dal decimo byte ci sono le informazioni sulla lunghezza complessiva dell'header
fread (&offset, 4, 1, bitmap);
fclose(bitmap);
return offset;
}

MonsterMash
18-05-2008, 18:19
Nessuno mi sa aiutare? Io non so proprio pi¨ dove sbattere la testa...

shodan
18-05-2008, 18:26
Quando apri il file devi farlo in modo binario, non di testo.
Es. La crea_bitmap.

MonsterMash
18-05-2008, 19:27
Grazie mille, davvero, non so come posso ancora sbagliare queste cose...

Ciao!

Loading