#include
#include
#include
#include "image.h"
// ====================================================================
// ====================================================================
// some helper functions for save & load
unsigned char ReadByte(FILE *file) {
unsigned char b;
int success = fread((void*)&b,sizeof(unsigned char),1,file);
assert (success == 1);
return b;
}
void WriteByte(FILE *file, unsigned char b) {
int success = fwrite((void*)&b,sizeof(unsigned char),1,file);
assert (success == 1);
}
unsigned char ClampColorComponent(float c) {
int tmp = int (c*255);
if (tmp < 0) tmp = 0;
if (tmp > 255) tmp = 255;
return (unsigned char)tmp;
}
// ====================================================================
// ====================================================================
// Save and Load data type 2 Targa (.tga) files
// (uncompressed, unmapped RGB images)
void Image::SaveTGA(const char *filename) const {
assert(filename != NULL);
// must end in .tga
const char *ext = &filename[strlen(filename)-4];
assert(!strcmp(ext,".tga"));
FILE *file = fopen(filename,"wb");
// misc header information
for (int i = 0; i < 18; i++) {
unsigned char tmp;
if (i == 2) WriteByte(file,2);
else if (i == 12) WriteByte(file,width%256);
else if (i == 13) WriteByte(file,width/256);
else if (i == 14) WriteByte(file,height%256);
else if (i == 15) WriteByte(file,height/256);
else if (i == 16) WriteByte(file,24);
else if (i == 17) WriteByte(file,32);
else WriteByte(file,0);
}
// the data
// flip y so that (0,0) is bottom left corner
for (int y = height-1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
Vec3f v = GetPixel(x,y);
// note reversed order: b, g, r
WriteByte(file,ClampColorComponent(v.b()));
WriteByte(file,ClampColorComponent(v.g()));
WriteByte(file,ClampColorComponent(v.r()));
}
}
fclose(file);
}
Image* Image::LoadTGA(const char *filename) {
assert(filename != NULL);
// must end in .tga
const char *ext = &filename[strlen(filename)-4];
assert(!strcmp(ext,".tga"));
FILE *file = fopen(filename,"rb");
// misc header information
int width = 0;
int height = 0;
for (int i = 0; i < 18; i++) {
unsigned char tmp;
tmp = ReadByte(file);
if (i == 2) assert(tmp == 2);
else if (i == 12) width += tmp;
else if (i == 13) width += 256*tmp;
else if (i == 14) height += tmp;
else if (i == 15) height += 256*tmp;
else if (i == 16) assert(tmp == 24);
else if (i == 17) assert(tmp == 32);
else assert(tmp == 0);
}
// the data
Image *answer = new Image(width,height);
// flip y so that (0,0) is bottom left corner
for (int y = height-1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
unsigned char r,g,b;
// note reversed order: b, g, r
b = ReadByte(file);
g = ReadByte(file);
r = ReadByte(file);
Vec3f color(r/255.0,g/255.0,b/255.0);
answer->SetPixel(x,y,color);
}
}
fclose(file);
return answer;
}
// ====================================================================
// ====================================================================
// Save and Load PPM image files using magic number 'P6'
// and having one comment line
void Image::SavePPM(const char *filename) const {
assert(filename != NULL);
// must end in .ppm
const char *ext = &filename[strlen(filename)-4];
assert(!strcmp(ext,".ppm"));
FILE *file = fopen(filename, "w");
// misc header information
assert(file != NULL);
fprintf (file, "P6\n");
fprintf (file, "# Creator: Image::SavePPM()\n");
fprintf (file, "%d %d\n", width,height);
fprintf (file, "255\n");
// the data
// flip y so that (0,0) is bottom left corner
for (int y = height-1; y >= 0; y--) {
for (int x=0; x= 0; y--) {
for (int x = 0; x < width; x++) {
unsigned char r,g,b;
r = fgetc(file);
g = fgetc(file);
b = fgetc(file);
Vec3f color(r/255.0,g/255.0,b/255.0);
answer->SetPixel(x,y,color);
}
}
fclose(file);
return answer;
}
// ====================================================================
// ====================================================================