2010-11-24 6 views
3

У меня есть входной файл, который имеет заголовок, как это:Можно ли отобразить только часть файла с помощью mmap?

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

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

Итак, я хочу пропустить заголовок и сделать свою функцию 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); 
    } 

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

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

main
c functions
header
makefile

+1

Почему бы просто не использовать немного арифметики указателя и еще одну переменную указателя? – thkala 2010-11-24 01:51:16

+0

Обратите внимание, что `caddr_t` является устаревшим вздохом от pre-ANSI C. Тип, используемый с` mmap`, является `void *`. – 2010-11-24 02:11:17

+0

@R ..: Итак, как я могу правильно называть mmap? Это было из примера учителя, lol – neverMind 2010-11-24 02:36:55

ответ

-1

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

0

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

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

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

1

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

0

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

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*

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

1

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

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

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

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