X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fimage.cc;h=818b686744a658d17cf6da35d7c63ee2b3c3a999;hb=HEAD;hp=2bfdbd868574bce2a9d1a6b13a74d773c5d4fefc;hpb=77e44c5424bd5e6e7c6a706151fa786a56270e12;p=demo diff --git a/src/image.cc b/src/image.cc index 2bfdbd8..818b686 100644 --- a/src/image.cc +++ b/src/image.cc @@ -1,3 +1,4 @@ +#include #include #include "imago2.h" @@ -5,22 +6,29 @@ Image::Image() { - w = h = 0; + w = h = psz = 0; pixels = 0; + + is_float = false; } Image::~Image() { - delete [] pixels; + free(pixels); } Image::Image(const Image &image) { w = image.w; h = image.h; + is_float = image.is_float; + psz = image.psz; - pixels = new unsigned char[w * h * 4]; - memcpy(pixels, image.pixels, w * h * 4); + if(!(pixels = malloc(w * h * psz))) { + fprintf(stderr, "Failed to allocate pixels.\n"); + abort(); + } + memcpy(pixels, image.pixels, w * h * psz); } Image &Image::operator =(const Image &image) @@ -28,13 +36,18 @@ Image &Image::operator =(const Image &image) if(&image == this) return *this; - delete [] pixels; + free(pixels); w = image.w; h = image.h; + psz = image.psz; + is_float = image.is_float; - pixels = new unsigned char[w * h * 4]; - memcpy(pixels, image.pixels, w * h * 4); + if(!(pixels = malloc(w * h * psz))) { + fprintf(stderr, "Failed to allocate pixels.\n"); + abort(); + } + memcpy(pixels, image.pixels, w * h * psz); return *this; } @@ -43,6 +56,8 @@ Image::Image(Image &&image) { w = image.w; h = image.h; + psz = image.psz; + is_float = image.is_float; pixels = image.pixels; image.pixels = 0; @@ -53,10 +68,12 @@ Image &Image::operator =(Image &&image) if(&image == this) return *this; - delete [] pixels; + free(pixels); w = image.w; h = image.h; + psz = image.psz; + is_float = image.is_float; pixels = image.pixels; image.pixels = 0; @@ -66,17 +83,92 @@ Image &Image::operator =(Image &&image) bool Image::load(const char *fname) { - unsigned char *imago_pixels; - if(!(imago_pixels = (unsigned char *)img_load_pixels(fname, &w, &h))) { - fprintf(stderr, "Failed to load pixels from file: %s.\n", fname); + free(pixels); + + img_pixmap ipm; + img_init(&ipm); + + if(img_load(&ipm, fname) == -1) { + fprintf(stderr, "Failed to load image: %s.\n", fname); + + img_destroy(&ipm); + return false; + } + + printf("Successfully loaded image: %s\n", fname); + + img_fmt format = img_is_float(&ipm) ? IMG_FMT_RGBAF : IMG_FMT_RGBA32; + if(img_convert(&ipm, format) == -1) { + fprintf(stderr, "Failed to convert image %s.\n", fname); + + img_destroy(&ipm); return false; } - delete [] pixels; - pixels = new unsigned char[w * h * 4]; - memcpy(pixels, imago_pixels, w * h * 4); + w = ipm.width; + h = ipm.height; + psz = ipm.pixelsz; + is_float = img_is_float(&ipm) ? true : false; + + if(!(pixels = malloc(w * h * psz))) { + fprintf(stderr, "Failed to allocate pixels for image: %s.\n", fname); + return false; + } - img_free_pixels(imago_pixels); + memcpy(pixels, ipm.pixels, w * h * psz); + img_destroy(&ipm); return true; +} + +Vec4 Image::get_pixel(int x, int y) const +{ + if(is_float) { + return ((Vec4 *)pixels)[y * w + x]; + } + + Vec4 color; + unsigned char *pptr = ((unsigned char *)pixels) + (y * w + x) * 4; + color.x = pptr[0] / 255.0; + color.y = pptr[1] / 255.0; + color.z = pptr[2] / 255.0; + color.w = pptr[3] / 255.0; + + return color; +} + +Vec4 Image::lookup_nearest(float u, float v) const +{ + int x = (int)(u * w) % w; + int y = (int)(v * h) % h; + + return get_pixel(x, y); +} + +Vec4 Image::lookup_linear(float u, float v, float du, float dv) const +{ + /* bottom left */ + int x0 = (int)(u * w) % w; + int y0 = (int)(v * h) % h; + int x1 = (x0 + 1) % w; + int y1 = (y0 + 1) % h; + + /* uv coordinates at the img corners */ + float u0 = (float)x0 / (float)w; + float v0 = (float)y0 / (float)h; + float u1 = (float)(x0 + 1) / (float)w; + float v1 = (float)(y0 + 1) / (float)h; + + float tu = (u - u0) / (u1 - u0); + float tv = (v - v0) / (v1 - v0); + + Vec4 p00 = get_pixel(x0, y0); + Vec4 p01 = get_pixel(x0, y1); + Vec4 p11 = get_pixel(x1, y1); + Vec4 p10 = get_pixel(x1, y0); + + Vec4 ptop = lerp(p01, p11, tu); + Vec4 pbot = lerp(p00, p10, tu); + + return lerp(pbot, ptop, tv); } \ No newline at end of file