nuclear@0: #include nuclear@0: #include "imago2.h" nuclear@0: #include "image.h" nuclear@0: #include "logger.h" nuclear@0: nuclear@0: nuclear@0: static int pixel_elements(Image::Format fmt); nuclear@0: static int elem_size(Image::Format fmt); nuclear@0: static int pixel_size(Image::Format fmt); nuclear@0: nuclear@0: Image::Image() nuclear@0: { nuclear@0: fmt = FMT_RGBA; nuclear@0: width = height = 0; nuclear@0: pixels = 0; nuclear@0: } nuclear@0: nuclear@0: Image::~Image() nuclear@0: { nuclear@0: delete [] (char*)pixels; nuclear@0: } nuclear@0: nuclear@0: int Image::get_width() const nuclear@0: { nuclear@0: return width; nuclear@0: } nuclear@0: nuclear@0: int Image::get_height() const nuclear@0: { nuclear@0: return height; nuclear@0: } nuclear@0: nuclear@0: Image::Format Image::get_format() const nuclear@0: { nuclear@0: return fmt; nuclear@0: } nuclear@0: nuclear@0: bool Image::create(int x, int y, Format fmt) nuclear@0: { nuclear@0: width = x; nuclear@0: height = y; nuclear@0: this->fmt = fmt; nuclear@0: nuclear@0: try { nuclear@0: pixels = new char[x * y * pixel_size(fmt)]; nuclear@0: } nuclear@0: catch(...) { nuclear@0: return false; nuclear@0: } nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool Image::set_pixels(int x, int y, void *pixels, Format fmt) nuclear@0: { nuclear@0: if(!create(x, y, fmt)) { nuclear@0: return false; nuclear@0: } nuclear@0: memcpy(this->pixels, pixels, x * y * pixel_size(fmt)); nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void *Image::get_pixels() const nuclear@0: { nuclear@0: return pixels; nuclear@0: } nuclear@0: nuclear@0: bool Image::load(const char *fname) nuclear@0: { nuclear@0: struct img_pixmap pixmap; nuclear@0: nuclear@0: img_init(&pixmap); nuclear@0: if(img_load(&pixmap, fname) == -1) { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: Format fmt; nuclear@0: switch(pixmap.fmt) { nuclear@0: case IMG_FMT_GREY8: nuclear@0: fmt = FMT_GREY; nuclear@0: break; nuclear@0: case IMG_FMT_RGB24: nuclear@0: fmt = FMT_RGB; nuclear@0: break; nuclear@0: case IMG_FMT_RGBA32: nuclear@0: fmt = FMT_RGBA; nuclear@0: break; nuclear@0: case IMG_FMT_GREYF: nuclear@0: fmt = FMT_GREY_FLOAT; nuclear@0: break; nuclear@0: case IMG_FMT_RGBF: nuclear@0: fmt = FMT_RGB_FLOAT; nuclear@0: break; nuclear@0: case IMG_FMT_RGBAF: nuclear@0: fmt = FMT_RGBA_FLOAT; nuclear@0: break; nuclear@0: default: nuclear@0: img_destroy(&pixmap); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: if(!set_pixels(pixmap.width, pixmap.height, pixmap.pixels, fmt)) { nuclear@0: img_destroy(&pixmap); nuclear@0: return false; nuclear@0: } nuclear@0: img_destroy(&pixmap); nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool Image::save(const char *fname) const nuclear@0: { nuclear@0: struct img_pixmap pixmap; nuclear@0: nuclear@0: img_init(&pixmap); nuclear@0: nuclear@0: switch(fmt) { nuclear@0: case FMT_GREY: nuclear@0: pixmap.fmt = IMG_FMT_GREY8; nuclear@0: break; nuclear@0: case FMT_GREY_FLOAT: nuclear@0: pixmap.fmt = IMG_FMT_GREYF; nuclear@0: break; nuclear@0: case FMT_RGB: nuclear@0: pixmap.fmt = IMG_FMT_RGB24; nuclear@0: break; nuclear@0: case FMT_RGB_FLOAT: nuclear@0: pixmap.fmt = IMG_FMT_RGBF; nuclear@0: break; nuclear@0: case FMT_RGBA: nuclear@0: pixmap.fmt = IMG_FMT_RGBA32; nuclear@0: break; nuclear@0: case FMT_RGBA_FLOAT: nuclear@0: pixmap.fmt = IMG_FMT_RGBAF; nuclear@0: break; nuclear@0: default: nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: pixmap.width = width; nuclear@0: pixmap.height = height; nuclear@0: pixmap.pixels = pixels; nuclear@0: pixmap.pixelsz = pixel_size(fmt); nuclear@0: nuclear@0: if(img_save(&pixmap, fname) == -1) { nuclear@0: return false; nuclear@0: } nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: static int pixel_elements(Image::Format fmt) nuclear@0: { nuclear@0: switch(fmt) { nuclear@0: case Image::FMT_GREY: nuclear@0: case Image::FMT_GREY_FLOAT: nuclear@0: return 1; nuclear@0: nuclear@0: case Image::FMT_RGB: nuclear@0: case Image::FMT_RGB_FLOAT: nuclear@0: return 3; nuclear@0: nuclear@0: case Image::FMT_RGBA: nuclear@0: case Image::FMT_RGBA_FLOAT: nuclear@0: return 4; nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: static int elem_size(Image::Format fmt) nuclear@0: { nuclear@0: switch(fmt) { nuclear@0: case Image::FMT_GREY: nuclear@0: case Image::FMT_RGB: nuclear@0: case Image::FMT_RGBA: nuclear@0: return 1; nuclear@0: nuclear@0: case Image::FMT_GREY_FLOAT: nuclear@0: case Image::FMT_RGB_FLOAT: nuclear@0: case Image::FMT_RGBA_FLOAT: nuclear@0: return sizeof(float); nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: static int pixel_size(Image::Format fmt) nuclear@0: { nuclear@0: return elem_size(fmt) * pixel_elements(fmt); nuclear@0: }