[Image processing] ppm file format

https://en.wikipedia.org/wiki/Netpbm_format

PortablePixMap 의 약자이며, 3채널의 RGB 정보를 담는 무손실 이미지 포맷이다.

매직 넘버가 P6 인 이진 ppm 이미지의 R/W 코드는 아래와 같다.

이차원 배열을 어떻게 할당했는지도 한번 살펴보아라.

#include<iostream>
struct PPMImage {  
    char** img;
    int width, height;
};
int ReadPPM(const char* file_name, PPMImage* img) {  
    FILE* fp = NULL;
    if (file_name == NULL)return 0;
    fp=fopen(file_name, "rb");
    if (fp == NULL)return 0;
    char M, N;
    int R;
    fscanf(fp, "%c%c\n", &M, &N);
    if (M != 'P' || N != '6')return 0;
    fscanf(fp, "%d%d\n", &img->width, &img->height);
    fscanf(fp, "%d\n", &R);
    if (R != 255)return 0;
    img->img = (char**)malloc(sizeof(char*)*img->height + img->width * 3 * img->height);
    printf("%d\n", sizeof(char*)*img->height + img->width * 3 * img->height);
    for (int y = 0; y < img->height; y++) {
        img->img[y] = (char*)((char*)img->img + (sizeof(char*)*img->height) + (img->width * 3 * y));
        for (int x = 0; x < img->width * 3; x++) {
            fread(&img->img[y][x], sizeof(unsigned char), 1, fp);
        }
    }
    return 1;
}
int WritePPM(const char* file_name, PPMImage* img) {  
    FILE* fp = NULL;
    if (file_name == NULL)return 0;
    fp = fopen(file_name, "wb");
    if (fp == NULL)return 0;
    fprintf(fp, "P6\n%d %d\n%d\n", img->width, img->height, 255);
    for (int y = 0; y < img->height; y++) {
        for (int x = 0; x < img->width*3; x++) {
            fwrite(&img->img[y][x], sizeof(unsigned char), 1, fp);
        }
    }
    fclose(fp);
    return 1;
}
int main() {  
    PPMImage img;
    ReadPPM("bear.ppm", &img);
    WritePPM("copy.ppm", &img);
    free(img.img);
    return 0;
}