Ahora vamos a ver un ejemplo un poco más sofisticado: vamos a abrir un fichero que sea una imagen en formato BMP y a mostrar en pantalla si está comprimido o no.
Para eso necesitamos antes saber cómo se guarda la información en un fichero BMP, pero esto es algo fácil de localizar:
FICHEROS .BMP
Un fichero BMP está compuesto por las siguientes partes: una cabecera de fichero, una cabecera del bitmap, una tabla de colores y los bytes que definirán la imagen.
En concreto, los datos que forman la cabecera de fiochero y la cabecera de bitmap son los siguientes:
POSICIÓN EN EL ARCHIVO |
|
Tipo de fichero (letras BM) |
0-1 |
Tamaño del archivo |
2-5 |
Reservado |
6-7 |
Reservado |
8-9 |
Inicio de los datos de la imagen |
10-13 |
Tamaño de la cabecera de bitmap |
14-17 |
Anchura (píxeles) |
18-21 |
Altura (píxeles) |
22-25 |
Número de planos |
26-27 |
Tamaño de cada punto |
28-29 |
Compresión (0=no comprimido) |
30-33 |
Tamaño de la imagen |
34-37 |
Resolución horizontal |
38-41 |
Resolución vertical |
42-45 |
Tamaño de la tabla de color |
46-49 |
Contador de colores importantes |
50-53 |
Con esta información nos basta para nuestro propósito: la compresión se indica en la posición 30 del fichero, ocupa 4 bytes (lo mismo que un “int” en los sistemas operativos de 32 bits), y si es un 0 querrá decir que la imagen no está comprimida.
Entonces lo podríamos comprobar así:
/*---------------------------*/
/* Ejemplo en C nº 59: */
/* C059.C */
/* */
/* Información sobre un */
/* fichero BMP (1) */
/* */
/* Curso de C, */
/* Nacho Cabanes */
/*---------------------------*/
#include
int main(){
char nombre[60];
FILE* fichero;
int compresion;
puts("Comprobador de imágenes BMP\n");
printf("Dime el nombre del fichero: ");
gets(nombre);
fichero = fopen(nombre, "rb");
if (fichero==NULL)
puts("No encontrado\n");
else {
fseek(fichero, 30, SEEK_SET);
fread(&compresion, 1, 4, fichero);
fclose(fichero);
if (compression == 0)
puts("Sin compresión");
else
puts ("BMP Comprimido ");
}
return 0;
}
Ya que estamos, podemos mejorarlo un poco para que además nos muestre el ancho y el alto de la imagen, y que compruebe antes si realmente se trata de un fichero BMP:
/*---------------------------*/
/* Ejemplo en C nº 60: */
/* C060.C */
/* */
/* Información sobre un */
/* fichero BMP (2) */
/* */
/* Curso de C, */
/* Nacho Cabanes */
/*---------------------------*/
#include
int main(){
char nombre[60];
FILE* fichero;
int compresion, ancho, alto;
char marca1, marca2;
puts("Comprobador de imágenes BMP\n");
printf("Dime el nombre del fichero: ");
gets(nombre);
fichero = fopen(nombre, "rb");
if (fichero==NULL)
puts("No encontrado\n");
else {
marca1 = fgetc(fichero); /* Leo los dos primeros bytes */
marca2 = fgetc(fichero);
if ((marca1 =='B') && (marca2 =='M')) { /* Si son BM */
printf("Marca del fichero: %c%c\n",
marca1, marca2);
fseek(fichero, 18, SEEK_SET); /* Posición 18: ancho */
fread(&ancho, 1, 4, fichero);
printf("Ancho: %d\n", ancho);
fread(&alto, 1, 4, fichero); /* Siguiente dato: alto */
printf("Alto: %d\n", alto);
fseek(fichero, 4, SEEK_CUR); /* 4 bytes después: compresión */
fread(&compresion, 1, 4, fichero);
fclose(fichero);
switch (compresion) {
case 0: puts("Sin compresión"); break;
case 1: puts("Compresión RLE 8 bits"); break;
case 2: puts("Compresión RLE 4 bits"); break;
}
} else
printf("No parece un fichero BMP\n"); /* Si la marca no es BM */
}
return 0;
}
Ejercicios propuestos: