3

我有一个输入文件,其标题如下:

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);
    }

如您所见,现在我的 ppm 图像已映射到char*数据,但我想跳过标题并仅映射到pixel*部分。

这是我的代码,建议使用 2 个指针,一个来自 mmap 的 char*,另一个等于 + 偏移量。

主要
c 函数

文件

4

5 回答 5

1

如果您阅读 的手册页mmap,您会发现它的最后一个参数是off_t offset. 说明:

...从字节偏移量“offset”开始,从 'fd' 描述的对象继续或最多映射 'len' 个字节。

我怀疑如果您将偏移量作为该参数传递,它将执行您想要的操作。

于 2010-11-24T01:47:24.953 回答
1

如果您需要跳过的数量小于系统页面大小,则不能,因为offset在某些系统上必须是页面大小的倍数。

于 2010-11-24T01:48:52.790 回答
1

您只需要保留 2 个指针 - 指向mmap'd 块开头的指针,以及指向您想要的数据开头的指针。如:

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

offset文件中您想要的数据的偏移量在哪里。

于 2010-11-24T01:59:06.807 回答
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*

如果没问题,我应该注意什么?例如,就像 Ignacio Vazquez-Abrams 所说的那样

于 2010-11-24T01:55:51.577 回答
-1

嗯,您确实注意到您提供的“偏移”参数为零?假设你知道你想要的绝对偏移量,你就通过它。

于 2010-11-24T01:47:11.093 回答