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*ます。

mmap からの char* とその + オフセットに等しい別のポインターの 2 つのポインターを使用することを提案する私のコードを次に示します。

main
c 関数
ヘッダー
makefile

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

mmap'd ブロックの開始点へのポインターと、そこに必要なデータの開始点へのポインターの 2 つのポインターを保持する必要があります。次のように:

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*

これでよろしければ、どのような注意が必要ですか?たとえば、イグナシオ・バスケス・エイブラムスが言ったように

于 2010-11-24T01:55:51.577 に答える
-1

ええと、あなたはあなたがゼロで供給している「オフセット」パラメータに気づきましたか?あなたが望むものの絶対オフセットを知っていると仮定して、あなたはそれを渡します。

于 2010-11-24T01:47:11.093 に答える