#include "ppmImage.h" #include /** * Constructor */ ppmImage::ppmImage() : pixels(NULL) { imageW = imageH = 0; } /** * Destrctor */ ppmImage::~ppmImage() { if (pixels) free(pixels); } /** * */ bool ppmImage::readFile(const std::string& filename) { FILE * file = fopen(filename.c_str(), "rb"); if (file == NULL) { std::cerr << "Unable to open " << filename << " for reading\n"; return false; } char buffer[100]; // read file identifier (magic number) fgets (buffer, sizeof (buffer), file); if ((buffer[0] != 'P') || (buffer[1] != '6')) { std::cerr << "Not a ppm file\n"; return false; } // read image size do fgets (buffer, sizeof (buffer), file); // Skip all comments "#" // Also skip any newlines that might (but shouldn't) be there // thanks Stephen Nerbetski for finding this bug. while (buffer[0] == '#' || buffer[0] == 10); // Read the width and height of the image sscanf (buffer, "%d %d", &imageW, &imageH); // Allocate the buffer if (pixels) delete pixels; // don't leak!! pixels = new unsigned char[imageW*imageH*3*sizeof(char)]; // 3 bytes per pixel // read maximum pixel value (usually 255) and ignore do fgets (buffer, sizeof (buffer), file); while (buffer[0] == '#'); int maxval; sscanf (buffer, "%d", &maxval); // Read in the pixel array row-by-row: 1st row = top scanline, so flip for openGL int rowsize = imageW * 3*sizeof(char); // the sized of each row unsigned char *ptr = pixels + (imageH-1) * rowsize; for (int i = imageH; i > 0; --i) { fread(ptr, sizeof(char), rowsize, file); ptr -= rowsize; } fclose(file); return true; } /** * Write the pixel buffer to disk using the ppm formate */ bool ppmImage::writeFile(const std::string& filename) { FILE * file = fopen(filename.c_str(), "wb"); if (file == NULL) { std::cerr << "Unable to open " << filename << " for writing\n"; return false; } char tmp[20]; tmp[0] = 'P'; tmp[1] = '6'; tmp[2] = 10; fwrite(tmp, sizeof(char), 3, file); sprintf(tmp, "%d %d", imageW, imageH); fwrite(tmp, strlen(tmp), 1, file); tmp[0] = 10; tmp[1] = '2'; tmp[2] = '5'; tmp[3] = '5'; tmp[4] = 10; fwrite(tmp, sizeof(char), 5, file); // Write the image row by row, flip back for ppm int rowsize = imageW * 3; // the sized of each row unsigned char *ptr = pixels + (imageH-1) * rowsize; for (int i = imageH; i > 0; --i) { fwrite((void *)ptr, sizeof(unsigned char), rowsize, file); ptr -= rowsize; } fclose(file); return true; }