From 75009ad49c6edb1b4957ba289b84b3f5b5002116 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 5 Dec 2016 12:40:27 +0100 Subject: [PATCH] Initial work on using FreeImage --- CMakeLists.txt | 20 +++++++++--------- Image.cpp | 57 ++++++++++++++++++++++++-------------------------- Image.h | 4 ++-- README.rst | 2 +- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cbd462..1934055 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,15 +45,15 @@ if(NOT CUSTOM_DOCDIR STREQUAL "") endif() -# Libraries: gd +# Libraries: freeimage -find_library(LIBGD_LIBRARY gd) -find_path(LIBGD_INCLUDE_DIR gd.h) -message (STATUS "libgd library: ${LIBGD_LIBRARY}") -message (STATUS "libgd headers: ${LIBGD_INCLUDE_DIR}") -if(NOT LIBGD_LIBRARY OR NOT LIBGD_INCLUDE_DIR) - message(FATAL_ERROR "libgd not found!") -endif(NOT LIBGD_LIBRARY OR NOT LIBGD_INCLUDE_DIR) +find_library(FREEIMAGE_LIBRARY freeimage) +find_path(FREEIMAGE_INCLUDE_DIR FreeImage.h) +message (STATUS "FreeImage library: ${FREEIMAGE_LIBRARY}") +message (STATUS "FreeImage headers: ${FREEIMAGE_INCLUDE_DIR}") +if(NOT FREEIMAGE_LIBRARY OR NOT FREEIMAGE_INCLUDE_DIR) + message(FATAL_ERROR "FreeImage not found!") +endif(NOT FREEIMAGE_LIBRARY OR NOT FREEIMAGE_INCLUDE_DIR) # Libraries: zlib @@ -127,7 +127,7 @@ include_directories( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${SQLITE3_INCLUDE_DIR} - ${LIBGD_INCLUDE_DIR} + ${FREEIMAGE_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) @@ -165,7 +165,7 @@ target_link_libraries( ${SQLITE3_LIBRARY} ${LEVELDB_LIBRARY} ${REDIS_LIBRARY} - ${LIBGD_LIBRARY} + ${FREEIMAGE_LIBRARY} ${ZLIB_LIBRARY} ) diff --git a/Image.cpp b/Image.cpp index b4973b9..23d86fd 100644 --- a/Image.cpp +++ b/Image.cpp @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include "Image.h" @@ -22,40 +20,41 @@ // ARGB but with inverted alpha -static inline int color2int(Color c) +static inline RGBQUAD color2rgbquad(Color c) { - u8 a = 255 - c.a; - return (a << 24) | (c.r << 16) | (c.g << 8) | c.b; + RGBQUAD c2; + c2.rgbRed = c.r; + c2.rgbGreen = c.g; + c2.rgbBlue = c.b; + return c2; } -static inline Color int2color(int c) +static inline Color rgbquad2color(RGBQUAD c) { - Color c2; - u8 a; - c2.b = c & 0xff; - c2.g = (c >> 8) & 0xff; - c2.r = (c >> 16) & 0xff; - a = (c >> 24) & 0xff; - c2.a = 255 - a; - return c2; + return Color(c.rgbRed, c.rgbGreen, c.rgbBlue); } Image::Image(int width, int height) : m_width(width), m_height(height), m_image(NULL) { - m_image = gdImageCreateTrueColor(m_width, m_height); + // FIXME: This works because minetestmapper only creates one image + FreeImage_Initialise(); + printf("Using FreeImage v%s\n", FreeImage_GetVersion()); + + m_image = FreeImage_Allocate(width, height, 24); } Image::~Image() { - gdImageDestroy(m_image); + FreeImage_Unload(m_image); } void Image::setPixel(int x, int y, const Color &c) { SIZECHECK(x, y); - m_image->tpixels[y][x] = color2int(c); + RGBQUAD col = color2rgbquad(c); + FreeImage_SetPixelColor(m_image, x, y, &col); } Color Image::getPixel(int x, int y) @@ -64,43 +63,41 @@ Color Image::getPixel(int x, int y) if(x < 0 || x > m_width || y < 0 || y > m_height) throw std::out_of_range("sizecheck"); #endif - return int2color(m_image->tpixels[y][x]); + RGBQUAD c; + FreeImage_GetPixelColor(m_image, x, y, &c); + return rgbquad2color(c); } void Image::drawLine(int x1, int y1, int x2, int y2, const Color &c) { SIZECHECK(x1, y1); SIZECHECK(x2, y2); - gdImageLine(m_image, x1, y1, x2, y2, color2int(c)); + // TODO } void Image::drawText(int x, int y, const std::string &s, const Color &c) { SIZECHECK(x, y); - gdImageString(m_image, gdFontGetMediumBold(), x, y, (unsigned char*) s.c_str(), color2int(c)); + // TODO } void Image::drawFilledRect(int x, int y, int w, int h, const Color &c) { SIZECHECK(x, y); SIZECHECK(x + w - 1, y + h - 1); - gdImageFilledRectangle(m_image, x, y, x + w - 1, y + h - 1, color2int(c)); + RGBQUAD col = color2rgbquad(c); + for(int xx = 0; xx < w; xx++) + for(int yy = 0; yy < h; yy++) + FreeImage_SetPixelColor(m_image, x + xx, y + yy, &col); } void Image::drawCircle(int x, int y, int diameter, const Color &c) { SIZECHECK(x, y); - gdImageArc(m_image, x, y, diameter, diameter, 0, 360, color2int(c)); + // TODO } void Image::save(const std::string &filename) { - FILE *f = fopen(filename.c_str(), "wb"); - if(!f) { - std::ostringstream oss; - oss << "Error writing image file: " << std::strerror(errno); - throw std::runtime_error(oss.str()); - } - gdImagePng(m_image, f); // other formats? - fclose(f); + FreeImage_Save(FIF_PNG, m_image, filename.c_str()); // other formats? } diff --git a/Image.h b/Image.h index ae21ce8..8397409 100644 --- a/Image.h +++ b/Image.h @@ -3,7 +3,7 @@ #include "types.h" #include -#include +#include struct Color { Color() : r(0), g(0), b(0), a(0) {}; @@ -29,7 +29,7 @@ private: Image(const Image&); int m_width, m_height; - gdImagePtr m_image; + FIBITMAP *m_image; }; #endif // IMAGE_HEADER diff --git a/README.rst b/README.rst index c142155..b505283 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ This version is both faster and provides more features than the now deprecated P Requirements ------------ -* libgd +* FreeImage * sqlite3 * leveldb (optional, set ENABLE_LEVELDB=1 in CMake to enable leveldb support) * hiredis (optional, set ENABLE_REDIS=1 in CMake to enable redis support)