Is it possible to display only part of a file using mmap?

I have an input file that has a header like this:

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

and then the structure is written, pixel *, to this file to be displayed.

So, I want to skip the header and make my mmap function return ptr to this structure. How can i do this? with lseek, maybe? Could you give some examples?

I will leave part of my code here:

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

As you can see, right now my ppm image is being mapped to data char*, but I want to skip the header and display only a part pixel*.

Here is my code suggesting using 2 pointers, char * from mmap, and the other is + offset.

main
c function
header
makefile

+3
5

, , , , , offset .

+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 - .

+1

mmap, , off_t offset. :

... "len" , , "fd", .

, , , .

0

So, from what I understand, can I do something like this?

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

and from this, I could map my file to whatever type I want, in this case pixel*

If everything is in order, what safety measures should be taken? For example, for example, Ignacio Vasquez-Abrams said

0
source

Um, did you notice the 'offset' parameter that you supply with zero? Assuming that you know the absolute bias of what you want, you transmit it.

-1
source

Source: https://habr.com/ru/post/1776595/


All Articles