Skip to content
Snippets Groups Projects
pnm.cpp 4.63 KiB
#include "pnm.h"
#include <iostream>
#include <stdio.h>
#include <string.h>

// pnm
// The PNM format is just an abstraction of the PBM, PGM, and PPM formats. I.e. the name "PNM" refers collectively to PBM, PGM, and PPM.
// pam has the advanced header

RGBAPNMObject * readPPM(const char* fileName) {
    RGBAPNMObject *data=new RGBAPNMObject;
    // open the file to read just the header reading
    FILE* fr = fopen(fileName, "r");
    if (!fr) {
        std::cout << "Can't open " << fileName << std::endl;
        return nullptr;
    }

    // formatted read of header
    char fileType[11];
    int res=0;
    res = fscanf(fr, "%9s", fileType);
    data->magicNum=fileType;

    //std::cout << "fileType:" << fileType << std::endl;
    
    unsigned char bits = 0;

    // check to see if it's a PPM image file
    if (strncmp(fileType, "P4" , 2) == 0) {
        bits = 1; // PBM
    } else if (strncmp(fileType, "P5" , 2) == 0) {
        bits = 8; // PGM
    } else if (strncmp(fileType, "P6" , 2) == 0) {
        bits = 24; // PPM
    } else if (strncmp(fileType, "P8" , 2) == 0) {
        bits = 32; // PPM
    }
    //std::cout << "bits:" << bits << std::endl;

    // read the rest of header
    unsigned int width, height;
    res = fscanf(fr, "%u\n %u\n", &width, &height);
    data->width = width;
    data->height = height;
    

    // read maximum
    data->maxColVal = 255; // just set a default
    if (bits != 1) {
        unsigned int maximum;
        res = fscanf(fr, "%u\n", &maximum);
        data->maxColVal = height;
    }
    unsigned int size = width * height;
    if (bits != 1) {
        size *= bits/8;
    }

    // allocate array for pixels
    char* pixels = new char[size];

    // unformatted read of binary pixel data
    res = fread(pixels, sizeof(int), size, fr);
    data->m_Ptr = pixels;

    // close file
    fclose(fr);

    // return the array
    return data;
} // end of readPPM

void writePBM4(const char *filename, const RGBAPNMObject &data) {
  FILE *fp = fopen(filename, "wb"); /* b - binary mode */
  fprintf(fp, "P6\n%d %d\n255\n", data.width, data.height);
  for (unsigned int j = 0; j < data.height; ++j) {
    for (unsigned int i = 0; i < data.width; ++i) {
      static unsigned char color[1];
      unsigned int pos = ((i * 4) + (j * 4 * 1024));
      //color[0] = data.m_Ptr[pos + 0];  /* red */
      //color[1] = data.m_Ptr[pos + 1];  /* green */
      //color[2] = data.m_Ptr[pos + 2];  /* blue */
      color[0] = static_cast<unsigned char>(data.m_Ptr[pos + 3]);  /* 
alpha */
      fwrite(color, 1, 1, fp);
    }
  }
  fclose(fp);
}

void writePGM5(const char *filename, const RGBAPNMObject &data) {
  FILE *fp = fopen(filename, "wb"); /* b - binary mode */
  fprintf(fp, "P5\n%d %d\n255\n", data.width, data.height);
  for (unsigned int j = 0; j < data.height; ++j) {
    for (unsigned int i = 0; i < data.width; ++i) {
      static unsigned char color[1];
      unsigned int pos = ((i * 4) + (j * 4 * 1024));
      color[0] = static_cast<unsigned char>(data.m_Ptr[pos + 0]);  /* red 
*/
      //color[1] = data.m_Ptr[pos + 1];  /* green */
      //color[2] = data.m_Ptr[pos + 2];  /* blue */
      //color[3] = data.m_Ptr[pos + 3];  /* alpha */
      fwrite(color, 1, 1, fp);
    }
  }
  fclose(fp);
}

void writePPM6(const char *filename, const RGBAPNMObject &data) {
  FILE *fp = fopen(filename, "wb"); /* b - binary mode */
  fprintf(fp, "P6\n%d %d\n255\n", data.width, data.height);
  for (unsigned int j = 0; j < data.height; ++j) {
    for (unsigned int i = 0; i < data.width; ++i) {
      static unsigned char color[3];
      unsigned int pos = ((i * 4) + (j * 4 * 1024));
      color[0] = static_cast<unsigned char>(data.m_Ptr[pos + 0]);  /* red */
      color[1] = static_cast<unsigned char>(data.m_Ptr[pos + 1]);  /* green */
      color[2] = static_cast<unsigned char>(data.m_Ptr[pos + 2]);  /* blue */
      //color[3] = data.m_Ptr[pos + 3];  /* alpha */
      fwrite(color, 1, 3, fp);
    }
  }
  fclose(fp);
}

void writePPM8(const char *filename, const RGBAPNMObject &data) {
  FILE *fp = fopen(filename, "wb"); /* b - binary mode */
  fprintf(fp, "P8\n%d %d\n255\n", data.width, data.height);
  for (unsigned int j = 0; j < data.height; ++j) {
    for (unsigned int i = 0; i < data.width; ++i) {
      static unsigned char color[4];
      unsigned int pos = ((i * 4) + (j * 4 * 1024));
      color[0] = static_cast<unsigned char>(data.m_Ptr[pos + 0]);  /* red */
      color[1] = static_cast<unsigned char>(data.m_Ptr[pos + 1]);  /* green */
      color[2] = static_cast<unsigned char>(data.m_Ptr[pos + 2]);  /* blue */
      color[3] = static_cast<unsigned char>(data.m_Ptr[pos + 3]);  /* alpha */
      fwrite(color, 1, 4, fp);
    }
  }
  fclose(fp);
}