/* render/image.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include "sys/sys.h" #include "render/image.h" #include "render/tgafile.h" #include "render/pngfile.h" #include "render/jpgfile.h" namespace render { Image::Image(unsigned int width, unsigned int height, unsigned int channels) { image_width = width; image_height = height; image_channels = channels; image_data = (unsigned char *) malloc(size()); clear(); } Image::~Image() { free(image_data); } void Image::clear() { memset(image_data, 0, size()); } void Image::swap_channels() { for (size_t y = 0; y < image_height; y++) { for (size_t x = 0; x < image_width; x++) { size_t offset = y * image_width * image_channels + x * image_channels; unsigned char tmp = image_data[offset]; image_data[offset] = image_data[offset + 2]; image_data[offset + 2] = tmp; } } } void Image::pad() { unsigned int w = width(); unsigned int h = height(); if ((w % 8) != 0) { image_width = w + (8 - (w % 8)); } if ((w % 8) != 0) { image_height = h + (8 - (h % 8)); } unsigned char *image_new = (unsigned char *) malloc(size()); memset(image_new, 0, size()); for (size_t y = 0; y < h; y++) { memcpy((void *)&image_new[y * image_width * image_channels], (void *)&image_data[y * w * image_channels], (size_t) w); } free(image_data); image_data = image_new; } void Image::flip_vertical() { unsigned char line[image_width*image_channels]; for (size_t y = 0; y < image_height / 2; y++) { memcpy(line, &image_data[y*image_width*image_channels], image_width*image_channels); memcpy(&image_data[y*image_width*image_channels], &image_data[(image_height-1-y)*image_width*image_channels], image_width*image_channels); memcpy(&image_data[(image_height-1-y)*image_width*image_channels], line, image_width*image_channels); } } void Image::flip_horizontal() { unsigned char pixel_data[image_channels]; for (size_t y = 0; y < image_height; y++) { for (size_t x = 0; x < image_width / 2; x++) { void *src = pixel(x,y); // &image_data[(y * image_width + x) * image_channels]; void *dst = pixel(image_width - x - 1, y); // (&image_data[((y+1) * image_width - x - 1) * image_channels]; memcpy(pixel_data, dst, image_channels); memcpy(dst, src, image_channels); memcpy(src, pixel_data, image_channels); } } } Image *Image::load(const std::string & name) { std::string filename; Image *image = 0; if (!image) { // try the png version filename.assign(name); filename.append(".png"); image = PNG::load(filename.c_str()); } if (!image) { // try the tga version filename.assign(name); filename.append(".tga"); image = TGA::load(filename.c_str()); } if (!image) { // try the jpg version filename.assign(name); filename.append(".jpg"); image = JPG::load(filename.c_str()); } if (!image) { con_warn << "Could not open image " << name << std::endl; return 0; } return image; } }