Можно ли отобразить только часть файла с помощью mmap? - PullRequest
3 голосов
/ 24 ноября 2010

У меня есть входной файл с таким заголовком:

P6\n
width\n
height\n
depth\n

, а затем в этот файл записывается структура pixel *, которая будет отображаться.

Итак, я хочу пропустить заголовок и заставить мою функцию mmap вернуть ptr в эту структуру.Как я могу это сделать?с lseek что ли?Не могли бы вы привести пример?

Я оставлю часть моего кода здесь:

printf("Saving header to output file\n");
    if (writeImageHeader(h, fpout) == -1) {
        printf("Could not write to output file\n");
        return -1;
    }

    last_index = (int)ftell(fpout);
    //printf("offset after header= %d\n",last_index);

    //alloc mem space for one row (width * size of one pixel struct)
    row = malloc(h->width * sizeof (pixel));

    /*Create a copy of the original image to the output file, which will be inverted*/
    printf("Starting work\n");
    for (i = 0; i < h->height; i++) {
        printf("Reading row... ");
        if (getImageRow(h->width, row, fpin) == -1) {
            printf("Error while reading row\n");
        }
        printf("Got row %d || ", (i + 1));

        printf("Saving row... ");
        if (writeRow(h->width, row, fpout) == -1) {
            printf("Error while reading row\n");
        }
        printf("Done\n");
    }


    /*Open file descriptor of the ouput file.
     * O_RDWR -  Read and Write operations both permitted
     * O_CREAT - Create file if it doesn't already exist
     * O_TRUNC - Delete existing contents of file*/
    if ((fdout = open(argv[2], O_RDWR, FILE_MODE)) < 0) {
        fprintf(stderr, "Can't create %s for writing\n", argv[2]);
        exit(1);
    }

    /*Get size of the output file*/
    if (fstat(fdout, &sbuf) == -1) {
        perror("Stat error ---------->\n");
        exit(1);
    }
    //printf("Size of output file: %d\n",(int)sbuf.st_size);

    /*Maps output file to memory*/
    if ((data = mmap((caddr_t) 0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == (caddr_t) (-1)) {
        perror("Error mmaping");
        exit(EXIT_FAILURE);
    }

Как видите, сейчас мое изображение в ppm сопоставлено с данными char*, но я хочупропустите заголовок и сопоставьте только с частью pixel*.

Вот мой код с предложением использовать 2 указателя, char * из mmap и еще один, равный + смещение.

main
c функциями
header
makefile

Ответы [ 5 ]

1 голос
/ 24 ноября 2010

Вам просто нужно сохранить 2 указателя - указатель на начало блока mmap 'и указатель на начало данных, которые вы хотите внутри. Как в:

unsigned char *block = mmap(0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0);
unsigned char *data = block + offset;

где offset - это смещение в файле к нужным данным.

1 голос
/ 24 ноября 2010

Если вы прочитаете справочную страницу для mmap, вы обнаружите, что ее последний параметр - off_t offset. Описание:

... продолжение или не более 'len' байтов для отображения из объекта, описанного 'fd', начиная со смещения байта 'offset'.

Я подозреваю, что если вы передадите свое смещение в качестве этого параметра, он будет делать то, что вы хотите.

1 голос
/ 24 ноября 2010

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

0 голосов
/ 24 ноября 2010

Итак, насколько я понимаю, я могу сделать что-то подобное?

off_t offset_after_header = lseek(fdout, last_index, SEEK_SET);
    printf("Pointer is on %d\n",(int)offset_after_header);
    /*Maps output file to memory*/
    if ((data = mmap((caddr_t) 0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, offset_after_header)) == (caddr_t) (-1)) {
        perror("Error mmaping");
        exit(EXIT_FAILURE);
    }

и после этого я могу сопоставить свой файл с любым типом, который я хочу, в этом случае pixel*

Если это нормально, какие предостережения мне следует предпринять? Например, как те, кто сказал Игнасио Васкес-Абрамс

0 голосов
/ 24 ноября 2010

Хм, вы заметили параметр 'offset', который вы вводите с нулем?Предполагая, что вы знаете абсолютное смещение того, что вы хотите, вы передаете его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...