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