Fread возвращает 0, читает пиксели из файла BMP - PullRequest
2 голосов
/ 02 августа 2011

Я использую этот код для получения пикселей из файла BMP.Я уже прочитал заголовки и палитру в предыдущих строках, поэтому мой FILE * указывает на начало массива пикселей.Он читает первую строку ОК, возвращает 1000, что и должно быть, но когда он пытается прочитать вторую строку пикселей, он возвращает 0.

Это функция, которая получает ФАЙЛ *, читает строки пикселейи пытается сохранить их в bmp_type.fila_alineada - это выровненный размер строки, пришлось сделать это из-за заполнения.

bool leer_pixels_8bpp(   FILE *fbmp, bmp_t *imagen,
                            const uint32_t fila_alineada,
                            const bool btopdown ){
int32_t i;
long x, y;
int32_t height, width, contador;
uint8_t *ptmp;

uint8_t bufferfila[fila_alineada];

height = imagen->infoheader.height;
width  = imagen->infoheader.width;
contador  = height;

i = btopdown ? 1 : -1;
y = btopdown ? 0 : ( height - 1 );

for ( ; contador--; y += i ) /* row loop */
{
    /* reading row */
    if ( fread( bufferfila, sizeof( uint8_t ), fila_alineada, fbmp ) != fila_alineada )
    {    /* HERE is the PROBLEM, it reads ok once, but in the second loop it returns 0 */
        fprintf( stderr, "Error reading pixels row.\n" );
        return false;
    }

    ptmp = bufferfila;
        /* saving pixels into bmp_t */
    for ( x = 0L; x < width; x++ )
    {
        imagen->pixels[y][x] = imagen->paleta.colores[ *ptmp++ ];
    }

}

return true;

}

Я пробовал с разными bmp!Проблема здесь или я должен рассмотреть обзор всего кода?Надеюсь, кто-нибудь может мне помочь, заранее спасибо.

1 Ответ

2 голосов
/ 02 августа 2011

Из вашего кода видно, что вы не читаете, что такое width изображения ... скорее, вы читаете сумму fila_alineada. Вы упомянули, что fila_alineada был выровненный размер строки из-за «заполнения», но BMP-файлы должны иметь достаточное количество отступов в конце, чтобы расширить каждую строку до нескольких 4-х байтов ... это должно быть значение, хотя это легко вычисляется из BITMAPINFOHEADER путем деления фактического размера данных массива пикселей на количество строк в изображении. Размер данных массива пикселей сохраняется в смещении 0x22 в заголовке. Высота, как я уверен, вы правильно вывели, имеет смещение 0x16. Таким образом, аргумент fila_alineada в значительной степени избыточен (то есть вы можете удалить его), и вы можете неправильно рассчитать это значение. Я бы просто использовал информацию в заголовке для расчета размера буфера, необходимого для сохранения информации в данной строке изображения.

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

...