2016-06-12 3 views
0

Я пытаюсь прочитать заголовок изображения растрового изображения (.bmp) в файле struct в c.fread в struct неправильно считывает данные

typedef unsigned short WORD; 
typedef unsigned long DWORD; 

typedef struct _BITMAPFILEHEADER { 
    WORD Type; 
    DWORD Size; 
    WORD Reserved1; 
    WORD Reserved2; 
    DWORD OffBits; 
} BITMAPFILEHEADER; 

Мой код для чтения файла растрового

FILE *fp; 
BITMAPFILEHEADER header; 

fp = fopen(file,"rb"); 
if (fp == NULL) { 
    printf("cannot open file!\n"); 
    return 1; 
} 

fread(&header, sizeof(BITMAPFILEHEADER), 1, fp); 

printf("Type: %02x\n", header.Type); 
printf("Size: %04x\n", header.Size); 
printf("Reserved: %02x\n", header.Reserved1); 
printf("Reserved: %02x\n", header.Reserved2); 
printf("Offset: %04x\n", header.OffBits); 

Что все должно равняться:
Тип: 0x424d
Размер: 0x00060436
Reserved1: 0x00
Reserved2: 0x00
Смещение: 0x00000436

Что на самом деле happning (выход PRINTF):
Тип: 0x424d
Размер: 0x0006
Зарезервировано: 0x002
Зарезервировано: 0x436
Offset: 0x280000

(мой os - 32-разрядный ubuntu, если это помогает)

+1

Если вам нужны фиксированные целые числа, используйте те, которые предусмотрены стандартом. Не используйте доморощенные типы. Также читайте abolut 'struct' layout и как правильно (de) сериализовать/marshall поток октетов. – Olaf

+5

http://c-faq.com/struct/io.html, http://c-faq.com/struct/padding.html – melpomene

+2

Как были записаны данные в файл? Вам нужно подражать тому, как это было написано при чтении данных.Если структура имеет дополнение (это почти наверняка делает), но данные были написаны по частям (как будто не было прокладки - это почти наверняка было), тогда данные не могут быть прочитаны, как вы это сделали. Вам нужно будет прочитать каждый элемент в свою очередь в отдельной операции 'fread()', и вы должны проверить, что каждый 'fread()' будет успешным, прежде чем использовать то, что, по вашему мнению, он вернул. –

ответ

0

При чтении таких файлов я считаю, что хороший подход состоит в том, чтобы сначала прочитать их как поток байтов (unsigned char), а затем, если необходимо, интерпретировать часть содержимого файла в соответствии с правильными типами данных.

В вашем случае, например, я бы определил BITMAPFILEHEADER-структуру, как это:

typedef struct _BITMAPFILEHEADER { 
    unsigned char Type[ 2 ]; 
    unsigned int Size;   // Size of the BMP file in bytes 
    unsigned char Reserved1[ 2 ]; 
    unsigned char Reserved2[ 2 ]; 
    unsigned int OffBits;  // Starting address of the pixel array 
} BITMAPFILEHEADER; 

Тогда я бы прочитать содержимое заголовка в виде блока 14 байт и, наконец, я хотел бы перейти к правильно заполните структуру BITMAPFILEHEADER.

Ниже вы можете найти простую программу, которая читает заголовок BMP-файла и печатает его на экране.

int main 
    (
    ) 
    { 
    // Defines a few variables 
    FILE*   fp = 0; 
    unsigned char h[ 14 ]; 

    // Opens the BMP file 
    fp = fopen("img.bmp", "rb"); 

    if (fp == NULL) 
     { 
     printf("Cannot open file\n"); 
     return -1; 
     } 

    // Reads the BMP header (14 bytes) 
    fread(h, 14, 1, fp); 

    // Prints the header contents 
    printf("Type:  %02x%02x\n", h[ 0 ], h[ 1 ]); 
    printf("Size:  %02x%02x%02x%02x\n", h[ 2 ], h[ 3 ], h[ 4 ], h[ 5 ]); 
    printf("Reserved: %02x%02x\n", h[ 6 ], h[ 7 ]); 
    printf("Reserved: %02x%02x\n", h[ 8 ], h[ 9 ]); 
    printf("Offset: %02x%02x%02x%02x\n", h[ 10 ], h[ 11 ], h[ 12 ], h[ 13 ]); 

    return 0; 
    } 

Примечание 1 - Обивка: Из спецификации формата файла BMP, мы знаем, что заголовок 14 байт длиной в то время как printf("%d", sizeof(BITMAPFILEHEADER)) покажет другой (больше!) Число из-за заполнения (см комментарии к ваш вопрос).

ПРИМЕЧАНИЕ 2. - Endiannes: При написании двух или четырех байтов в короткий или длинный соответственно, вы должны учитывать endiannes. Это означает, что вам нужно знать, как значения записываются в файл (как для заголовка Bitmap, они представлены с использованием маленькой конечной нотации) и как они обрабатываются вашей машиной (возможно, в маленькой концевой нотации).

+1

'unsigned char [2] Type;' является синтаксической ошибкой –

+1

Предполагая, что вы имели в виду 'unsigned char Type [2];', ваше определение структуры действительно не помогает, поскольку до 'Size' все равно будет заполняться. Было бы лучше читать необработанный буфер буфера ожидаемого размера, как в вашей примерной программе. Но у вашей программы есть проблемы с контентом. –

+1

Файлы BMP всегда находятся на малоэтажном афайке. – rici

Смежные вопросы