es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Gran `biSize` al leer encabezados de archivo BMP en c

Estoy intentando leer manualmente la cabecera de archivos BMP en C. He utilizado algunas imágenes para probarlo pero encuentro que el tamaño de biSize en la estructura BITMAPINFOHEADER de las imágenes es extremadamente grande.

En primer lugar, desafortunadamente no estoy en una máquina Windows, por lo que tengo que definir los tipos de datos (como WORD, DWORD, LONG y BYTE) de acuerdo con los documentos de MS-DTYP. Tal vez esto podría llevar a algunos problemas.

En segundo lugar, creo que no estoy completamente consciente de cómo se almacenan y formatean los números al ser impresos en C. Por lo tanto, el resultado podría ser correcto pero simplemente soy yo quien no lo puede entender.

Por último, he descubierto que el tamaño de struct BITMAPFILEHEADER no es de 14 bytes como la suma de los tamaños de los miembros en la estructura. ¿Es posible que la función fread() lea más bytes a la estructura de los que debería?

Código

typedef unsigned long DWORD;
typedef long LONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct tagBITMAPFILEHEADER {
  WORD  bfType;
  DWORD bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD bfOffBits;  // bit from the beginning of this struct to bitmap
} BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
    DWORD biSize;
    LONG  biWidth;      // width of image in pixels
    LONG  biHeight;     // height of image in pixels
    WORD  biPlanes;
    WORD  biBitCount;   // size of each pixel in bits
    DWORD biCompression;
    DWORD biSizeImage;
    LONG  biXPelsPerMeter;
    LONG  biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

bool
ReadBmp(char <em>path){
/</em>
parameter:
    char *path: el camino (string) al bmp objetivo

return:
    Verdadero: si tiene éxito
    Falso: si falla
*/

<pre><code>// obtiene el puntero del archivo bmp
FILE * f_ptr;
if((f_ptr = fopen(path, "rb"))==NULL){
    perror("ReadBmp falló al leer el bmp: ");
    return false;
}

// carga la cabecera de archivo en fhead
BITMAPFILEHEADER fhead; // cabecera de archivo
fread(&fhead, sizeof(BITMAPFILEHEADER), 1, f_ptr);

// carga la DIB en dib
BITMAPINFOHEADER dib;
fread(&dib, sizeof(BITMAPINFOHEADER), 1, f_ptr);

printf("tamaño: %lu\n", dib.biSize);
</code></pre>

}

int
main(void){
    ReadBmp("../imgs/master_yoda.bmp");

<pre><code>return 0;
</code></pre>

}

Resultado

tamaño: 1063975552894894080

Mientras que el tamaño real de master_yoda.bmp es de 2.2MB. También he revisado bfType en BITMAPFILEHEADER y funciona bien con un resultado de 19778 == 0x4D42, que es el identificador para archivos bmp.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema podría estar en la definición de los tipos de datos en una máquina no Windows. El tamaño de struct BITMAPFILEHEADER no es simplemente la suma de sus miembros, lo que puede afectar la lectura del encabezado del archivo. Además, la salida de dib.biSize parece ser significativamente mayor de lo esperado.

    Algunas sugerencias para abordar estos problemas incluyen definir correctamente los tipos de datos para la máquina de destino, tener en cuenta el relleno en struct BITMAPFILEHEADER y verificar el orden de bytes de la salida.

Comments are closed.