/*
winnie - an experimental window system
Copyright (C) 2013 Eleni Maria Stea
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Author: Eleni Maria Stea
*/
#include "pixmap.h"
#include
#include
#include
Pixmap::Pixmap()
{
width = height = 0;
pixels = 0;
}
Pixmap::Pixmap(const Pixmap &pixmap)
{
width = height = 0;
pixels = 0;
set_image(pixmap.width, pixmap.height, pixmap.pixels);
}
Pixmap &
Pixmap::operator=(const Pixmap &pixmap)
{
if (this != &pixmap) {
set_image(pixmap.width, pixmap.height, pixmap.pixels);
}
return *this;
}
Pixmap::~Pixmap()
{
if (pixels) {
delete[] pixels;
}
}
int
Pixmap::get_width() const
{
return width;
}
int
Pixmap::get_height() const
{
return height;
}
Rect
Pixmap::get_rect() const
{
Rect rect(0, 0, width, height);
return rect;
}
bool
Pixmap::set_image(int x, int y, unsigned char *pix)
{
delete[] pixels;
pixels = new unsigned char[x * y * 4];
width = x;
height = y;
if (pix) {
memcpy(pixels, pix, x * y * 4);
}
return true;
}
const unsigned char *
Pixmap::get_image() const
{
return pixels;
}
unsigned char *
Pixmap::get_image()
{
return pixels;
}
bool
Pixmap::load(const char *fname)
{
FILE *fp;
int hdrline = 0;
if (!(fp = fopen(fname, "rb"))) {
fprintf(stderr, "failed to open pixmap: %s: %s\n", fname, strerror(errno));
return false;
}
/* read ppm header */
while (hdrline < 3) {
char buf[64];
if (!fgets(buf, sizeof buf, fp))
goto err;
/* skip comments */
if (buf[0] == '#')
continue;
switch (hdrline++) {
case 0:
/* first header line should be P6 */
if (strcmp(buf, "P6\n") != 0)
goto err;
break;
case 1:
/* second header line contains the pixmap dimensions */
if (sscanf(buf, "%d %d", &width, &height) != 2)
goto err;
break;
}
}
set_image(width, height, 0);
for (int i = 0; i < width * height * 4; i++) {
int c;
if (i % 4 != 3) {
c = fgetc(fp);
if (c < 0)
goto err;
} else {
c = 255;
}
pixels[i] = c;
}
fclose(fp);
return true;
err:
fprintf(stderr, "failed to load pixmap: %s\n", fname);
fclose(fp);
return false;
}
bool
Pixmap::save(const char *fname) const
{
if (!pixels) {
return false;
}
FILE *fp = fopen(fname, "wb");
if (!fp) {
fprintf(stderr, "failed to save pixmap: %s: %s\n", fname, strerror(errno));
return false;
}
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (int i = 0; i < width * height; i++) {
fputc(pixels[i * 4], fp);
fputc(pixels[i * 4 + 1], fp);
fputc(pixels[i * 4 + 2], fp);
}
fclose(fp);
return true;
}