C не читает весь файл BMP - fopen - PullRequest
0 голосов
/ 29 марта 2019

Итак, я пытаюсь прочитать файл .bmp на языке C. Позже я собираюсь зашифровать файл с помощью библиотек openssl - но это только справочная информация.

Мне нужно открыть файл в двоичном режиме (очевидно) но по какой-то причине, когда я пытаюсь открыть файл, он читает только в 4 байта.Когда я пытаюсь вывести этот точный файл, который я только что открыл (для проверки ошибок), он выдает следующее - 88 24 AD FB.

. При устранении неполадок я решил попробовать это в текстовом файле (54 байта) и получаюточно такой же результат.

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){

    char * fileName="pic_original.bmp";

    //read the file from given filename in binary mode
    printf("Start to read the .bmp file \n");

    FILE *image;
    image = fopen(fileName,"rb");

    //print the size of the image (4 bytes every damn time)
    printf("Size of image: %d\n",sizeof(image));

    //output the exact file that was read (error testing)
    FILE *test;
    test = fopen("./test.bin", "w");
    fwrite(image, sizeof(image), 1, test);

    fclose(test);
    fclose(image);


    return 1;
}

Это изображение (по какой-то причине загруженное как png)

image

Не совсем точно, где я иду не такздесь, но я не очень опытный в C.

Приветствия, Лиам

РЕДАКТИРОВАТЬ 1:

//allocate memory for the header and image
char *headerBuf = (char *)malloc(54);
char *imageBuf = (char *)malloc(sizeof(image)-54); //this line is wrong - thanks to user EOF

//allocate memory for the final ciphertext
char *imagecipherCBC = (char *)malloc(sizeof(image)); //wrong also

//read first 54 bytes (header)
rewind(image);
fread(headerBuf,54,1,image);

//read the bitmap image until the end of the file
fread(imageBuf,sizeof(image),1,image); //also wrong

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Ну, Размер изображения, конечно, 4 байта, который является указателем файла на 32-битной машине.

Я думаю, что вы должны подготовить некоторый буфер изображения вашего bmp-файла в качестве простого примера, затем вы можете зашифровать и расшифровать содержимое этого буфера изображения, если ваш файл не слишком большой.

static void read_from_image(char *imageBuf, int fileLength)
{
    const char * outFileName="c:/DEV/temp/test.bin";
    char headerBuf[54];
    char *imagecipherCBC;

    FILE *test;
    test = fopen(outFileName, "wb");

    //allocate memory for the final ciphertext
    imagecipherCBC = (char *)malloc(fileLength *sizeof(char));

    //read first 54 bytes (header)
    //fread(headerBuf,54,1,image);
    memcpy(headerBuf, imageBuf, 54 * sizeof(char));

    //read the bitmap image until the end of the file
    //fread(imageBuf,sizeof(image),1,image); //also wrong

    fwrite(imageBuf, fileLength * sizeof(char), 1, test);
    fflush(test);
    fclose(test);

    free(imagecipherCBC),imagecipherCBC = NULL;
    free(imageBuf),imageBuf = NULL;

    return;
}

Вы можете иметь длину файла и буфер изображения в основной функции.

    int main(int argc, char *argv[])
{
    const char * fileName="c:/DEV/temp/pic_original.bmp";

    int fileLength = 0;

    FILE *image;
    char *imageBuffer;

    imageBuffer = NULL;
    image = fopen(fileName,"rb");

    printf("read the file from given filename in binary mode \n");
    printf("Start to read the .bmp file \n");

    //try to get a file length;
    fseek(image, 0, SEEK_END);
    fileLength = ftell(image);
    fseek(image, 0, SEEK_SET);
    rewind(image);

    imageBuffer = (char*)malloc(fileLength * sizeof(char));

    //print the size of the image (4 bytes every damn time)
    printf("read the file from given filename in binary mode \n");
    printf("Size of image file pointer: %d\n",sizeof(image));
    printf("Size of image: %d\n",fileLength);

    //output the exact file that was read (error testing)
    fread(imageBuffer,sizeof(char),fileLength*sizeof(char), image);

    fclose(image);

    read_from_image(imageBuffer, fileLength);

    return 0;
}

удачи

1 голос
/ 29 марта 2019

Если ваша цель - зашифровать файл, прочитайте весь файл в буфер, зашифруйте его и сохраните как двоичный файл. Вы можете найти размер файла, переместив указатель файла в конец. Пример:

int main()
{
    FILE *fin;
    fin = fopen("pic_original.bmp", "rb");
    fseek(fin, 0, SEEK_END);
    int filesize = ftell(fin);
    rewind(fin);

    char *buf = malloc(filesize);
    fread(buf, 1, filesize, fin);
    fclose(fin);

    //encrypt the buffer...

    FILE *fout = fopen("output.bmp", "wb");
    fwrite(buf, 1, filesize, fout);
    fclose(fout);

    return 0;
}

Это будет работать с любым файлом. OpenSSL уже имеет функции для непосредственного шифрования файлов.

Если по какой-то причине вы хотите оставить заголовок прежним и изменить только следующие биты, прочитайте заголовок отдельно:

int main()
{
    FILE *fin = fopen("input.bmp", "rb");
    if(!fin) { printf("cannot open input\n"); return 0; }

    FILE *fout = fopen("output.bmp", "wb");
    if(!fout) { printf("cannot open output\n"); return 0; }

    fseek(fin, 0, SEEK_END);
    int filesize = ftell(fin);
    if(filesize <= 54)
    {
        printf("wrong filesize\n");
        return 0;
    }
    rewind(fin);

    char *header = malloc(54);
    char *buf = malloc(filesize - 54);
    //encrypt buf...
    fread(header, 1, 54, fin);
    fread(buf, 1, filesize - 54, fin);
    fclose(fin);

    fwrite(header, 1, 54, fout);
    fwrite(buf, 1, filesize - 54, fout);
    fclose(fout);

    free(header);
    free(buf);
    return 0;
}

Полагаю, это имеет то преимущество, что зашифрованное растровое изображение все равно будет распознаваться как растровое. Но только методы шифрования не добавляют дополнительные байты к выводу.

Обратите внимание, что 8-битные, 4-битные и монохромные растровые изображения имеют палитру, которая идет после заголовка 54 байтов, а затем идет биты изображения.

...