-rw-r--r-- | agg-plot/Makefile | 2 | ||||
-rw-r--r-- | agg-plot/agg-pixfmt-config.h | 16 | ||||
-rw-r--r-- | agg-plot/agg_platform_support_win32.cpp | 414 | ||||
-rw-r--r-- | agg-plot/bitmap-plot.cpp | 60 | ||||
-rw-r--r-- | agg-plot/bitmap-plot.h | 12 | ||||
-rw-r--r-- | agg-plot/lua-plot.cpp | 2 | ||||
-rw-r--r-- | agg-plot/platform_support_ext.h | 2 |
diff --git a/agg-plot/Makefile b/agg-plot/Makefile index 0f937d12..d9a3040a 100644 --- a/agg-plot/Makefile +++ b/agg-plot/Makefile @@ -44,7 +44,7 @@ endif INCLUDES += $(AGG_INCLUDES) -I$(GSH_BASE_DIR) -I$(LUADIR)/src -AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp colors.cpp markers.cpp lua-draw.cpp lua-text.cpp text.cpp agg-parse-trans.cpp window.cpp lua-plot.cpp canvas-window.cpp +AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp colors.cpp markers.cpp lua-draw.cpp lua-text.cpp text.cpp agg-parse-trans.cpp window.cpp lua-plot.cpp canvas-window.cpp bitmap-plot.cpp AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o) diff --git a/agg-plot/agg-pixfmt-config.h b/agg-plot/agg-pixfmt-config.h new file mode 100644 index 00000000..01ffabba --- /dev/null +++ b/agg-plot/agg-pixfmt-config.h @@ -0,0 +1,16 @@ +#ifndef AGG_PIXFMT_CONFIG_H +#define AGG_PIXFMT_CONFIG_H + +#include "platform/agg_platform_support.h" + +namespace gslshell +{ + const agg::pix_format_e pixel_format = agg::pix_format_bgr24; + const bool flip_y = true; + + extern unsigned bpp; + extern agg::pix_format_e sys_pixel_format; + extern unsigned sys_bpp; +} + +#endif diff --git a/agg-plot/agg_platform_support_win32.cpp b/agg-plot/agg_platform_support_win32.cpp index 751ecca5..ca1550a5 100644 --- a/agg-plot/agg_platform_support_win32.cpp +++ b/agg-plot/agg_platform_support_win32.cpp @@ -26,6 +26,7 @@ #include <string.h> #include <pthread.h> #include <new> +#include "agg-pixfmt-config.h" #include "platform_support_ext.h" #include "platform/win32/agg_win32_bmp.h" #include "util/agg_color_conv_rgb8.h" @@ -37,11 +38,93 @@ namespace agg { static inline void pixel_map_attach (pixel_map& pm, rendering_buffer *rbuf, - bool flip_y) + bool flip_y) { int stride = pm.stride(); rbuf->attach(pm.buf(), pm.width(), pm.height(), flip_y ? stride : -stride); } + + //------------------------------------------------------------------------ + template <class RenBufDst, class RenBufSrc> + static void convert_pmap(RenBufDst* dst, const RenBufSrc* src, + pix_format_e format, bool copy_req) + { + switch(format) + { + case pix_format_gray8: + case pix_format_bgr24: + if (copy_req) + dst->copy_from(*src); + break; + + case pix_format_gray16: + my_color_conv(dst, src, color_conv_gray16_to_gray8()); + break; + + case pix_format_rgb565: + my_color_conv(dst, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_rgbAAA: + my_color_conv(dst, src, color_conv_rgbAAA_to_bgr24()); + break; + + case pix_format_bgrAAA: + my_color_conv(dst, src, color_conv_bgrAAA_to_bgr24()); + break; + + case pix_format_rgbBBA: + my_color_conv(dst, src, color_conv_rgbBBA_to_bgr24()); + break; + + case pix_format_bgrABB: + my_color_conv(dst, src, color_conv_bgrABB_to_bgr24()); + break; + + case pix_format_rgb24: + my_color_conv(dst, src, color_conv_rgb24_to_bgr24()); + break; + + case pix_format_rgb48: + my_color_conv(dst, src, color_conv_rgb48_to_bgr24()); + break; + + case pix_format_bgr48: + my_color_conv(dst, src, color_conv_bgr48_to_bgr24()); + break; + + case pix_format_abgr32: + my_color_conv(dst, src, color_conv_abgr32_to_bgra32()); + break; + + case pix_format_argb32: + my_color_conv(dst, src, color_conv_argb32_to_bgra32()); + break; + + case pix_format_rgba32: + my_color_conv(dst, src, color_conv_rgba32_to_bgra32()); + break; + + case pix_format_bgra64: + my_color_conv(dst, src, color_conv_bgra64_to_bgra32()); + break; + + case pix_format_abgr64: + my_color_conv(dst, src, color_conv_abgr64_to_bgra32()); + break; + + case pix_format_argb64: + my_color_conv(dst, src, color_conv_argb64_to_bgra32()); + break; + + case pix_format_rgba64: + my_color_conv(dst, src, color_conv_rgba64_to_bgra32()); + break; + + default: + /* */; + } + } //------------------------------------------------------------------------ HINSTANCE g_windows_instance = 0; @@ -59,7 +142,7 @@ namespace agg rendering_buffer* wnd); void display_pmap(HDC dc, const rendering_buffer* src, - const agg::rect_base<int> *rect = 0); + const agg::rect_base<int> *rect = 0); bool load_pmap(const char* fn, unsigned idx, rendering_buffer* dst); @@ -103,14 +186,14 @@ namespace agg m_bpp(0), m_sys_bpp(0), m_hwnd(0), - m_bmp_draw(0), + m_bmp_draw(0), m_cur_x(0), m_cur_y(0), m_input_flags(0), m_redraw_flag(true), m_current_dc(0), - m_is_mapped(false), - m_is_ready(false) + m_is_mapped(false), + m_is_ready(false) { switch(m_format) @@ -181,13 +264,13 @@ namespace agg m_sys_bpp = 32; break; - default: - /* */; + default: + /* */; } ::QueryPerformanceFrequency(&m_sw_freq); ::QueryPerformanceCounter(&m_sw_start); - pthread_mutex_init (m_mutex, NULL); + pthread_mutex_init (m_mutex, NULL); } //------------------------------------------------------------------------ @@ -211,140 +294,57 @@ namespace agg rendering_buffer* wnd) { m_pmap_window.create(width, height, org_e(m_bpp)); - pixel_map_attach (m_pmap_window, wnd, m_flip_y); + pixel_map_attach (m_pmap_window, wnd, m_flip_y); - if (m_bmp_draw) - delete [] (unsigned char*) m_bmp_draw; - m_bmp_draw = pixel_map::create_bitmap_info(width, height, - org_e(m_sys_bpp)); + if (m_bmp_draw) + delete [] (unsigned char*) m_bmp_draw; + m_bmp_draw = pixel_map::create_bitmap_info(width, height, + org_e(m_sys_bpp)); } - - //------------------------------------------------------------------------ - template <class RenBufDst, class RenBufSrc> - static void convert_pmap(RenBufDst* dst, const RenBufSrc* src, - pix_format_e format, bool copy_req) - { - switch(format) - { - case pix_format_gray8: - case pix_format_bgr24: - if (copy_req) - dst->copy_from(*src); - break; - - case pix_format_gray16: - my_color_conv(dst, src, color_conv_gray16_to_gray8()); - break; - - case pix_format_rgb565: - my_color_conv(dst, src, color_conv_rgb565_to_rgb555()); - break; - - case pix_format_rgbAAA: - my_color_conv(dst, src, color_conv_rgbAAA_to_bgr24()); - break; - - case pix_format_bgrAAA: - my_color_conv(dst, src, color_conv_bgrAAA_to_bgr24()); - break; - - case pix_format_rgbBBA: - my_color_conv(dst, src, color_conv_rgbBBA_to_bgr24()); - break; - - case pix_format_bgrABB: - my_color_conv(dst, src, color_conv_bgrABB_to_bgr24()); - break; - - case pix_format_rgb24: - my_color_conv(dst, src, color_conv_rgb24_to_bgr24()); - break; - - case pix_format_rgb48: - my_color_conv(dst, src, color_conv_rgb48_to_bgr24()); - break; - - case pix_format_bgr48: - my_color_conv(dst, src, color_conv_bgr48_to_bgr24()); - break; - - case pix_format_abgr32: - my_color_conv(dst, src, color_conv_abgr32_to_bgra32()); - break; - - case pix_format_argb32: - my_color_conv(dst, src, color_conv_argb32_to_bgra32()); - break; - - case pix_format_rgba32: - my_color_conv(dst, src, color_conv_rgba32_to_bgra32()); - break; - - case pix_format_bgra64: - my_color_conv(dst, src, color_conv_bgra64_to_bgra32()); - break; - - case pix_format_abgr64: - my_color_conv(dst, src, color_conv_abgr64_to_bgra32()); - break; - - case pix_format_argb64: - my_color_conv(dst, src, color_conv_argb64_to_bgra32()); - break; - - case pix_format_rgba64: - my_color_conv(dst, src, color_conv_rgba64_to_bgra32()); - break; - - default: - /* */; - } - } - //------------------------------------------------------------------------ void platform_specific::display_pmap(HDC dc, const rendering_buffer* src, - const agg::rect_base<int> *ri) + const agg::rect_base<int> *ri) { if(m_sys_format == m_format && ri == 0) { - m_pmap_window.draw(dc); + m_pmap_window.draw(dc); } else { - agg::rect_base<int> r(0, 0, src->width(), src->height()); - if (ri) - r = agg::intersect_rectangles(r, *ri); + agg::rect_base<int> r(0, 0, src->width(), src->height()); + if (ri) + r = agg::intersect_rectangles(r, *ri); - int w = r.x2 - r.x1, h = r.y2 - r.y1; + int w = r.x2 - r.x1, h = r.y2 - r.y1; - bitmap_info_resize (m_bmp_draw, w, h); + bitmap_info_resize (m_bmp_draw, w, h); - pixel_map pmap; - pmap.attach_to_bmp(m_bmp_draw); + pixel_map pmap; + pmap.attach_to_bmp(m_bmp_draw); - rendering_buffer rbuf_tmp; - pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); + rendering_buffer rbuf_tmp; + pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); - rendering_buffer_ro src_view; - rendering_buffer_get_const_view(src_view, *src, r, m_bpp / 8, m_flip_y); + rendering_buffer_ro src_view; + rendering_buffer_get_const_view(src_view, *src, r, m_bpp / 8, m_flip_y); - convert_pmap(&rbuf_tmp, &src_view, m_format, true); + convert_pmap(&rbuf_tmp, &src_view, m_format, true); - unsigned int wh = m_pmap_window.height(); - RECT wrect; - wrect.left = r.x1; - wrect.right = r.x2; - wrect.bottom = wh - r.y1; - wrect.top = wh - r.y2; + unsigned int wh = m_pmap_window.height(); + RECT wrect; + wrect.left = r.x1; + wrect.right = r.x2; + wrect.bottom = wh - r.y1; + wrect.top = wh - r.y2; - RECT brect; - brect.left = 0; - brect.right = w; - brect.bottom = h; - brect.top = 0; + RECT brect; + brect.left = 0; + brect.right = w; + brect.bottom = h; + brect.top = 0; - pmap.draw(dc, &wrect, &brect); + pmap.draw(dc, &wrect, &brect); } } @@ -354,18 +354,18 @@ namespace agg bool platform_specific::save_pmap(const char* fn, unsigned idx, const rendering_buffer* src) { - pixel_map& img = m_pmap_img[idx]; + pixel_map& img = m_pmap_img[idx]; if(m_sys_format == m_format) { - return img.save_as_bmp(fn); + return img.save_as_bmp(fn); } pixel_map pmap; pmap.create(img.width(), img.height(), org_e(m_sys_bpp)); rendering_buffer rbuf_tmp; - pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); + pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); convert_pmap(&rbuf_tmp, src, m_format, false); return pmap.save_as_bmp(fn); @@ -377,16 +377,16 @@ namespace agg bool platform_specific::load_pmap(const char* fn, unsigned idx, rendering_buffer* dst) { - pixel_map& img = m_pmap_img[idx]; + pixel_map& img = m_pmap_img[idx]; pixel_map pmap; if(!pmap.load_from_bmp(fn)) return false; rendering_buffer rbuf_tmp; - pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); + pixel_map_attach (pmap, &rbuf_tmp, m_flip_y); img.create(pmap.width(), pmap.height(), org_e(m_bpp), 0); - pixel_map_attach (img, dst, m_flip_y); + pixel_map_attach (img, dst, m_flip_y); switch(m_format) { @@ -518,8 +518,8 @@ namespace agg } break; - default: - return false; + default: + return false; } return true; @@ -630,23 +630,23 @@ namespace agg //-------------------------------------------------------------------- case WM_SIZE: - try - { - app->m_specific->create_pmap(LOWORD(lParam), HIWORD(lParam), - &app->rbuf_window()); - - app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam)); - app->on_resize(LOWORD(lParam), HIWORD(lParam)); - app->force_redraw(); - } - catch (std::bad_alloc&) - { - ::PostQuitMessage(1); - } - - app->m_specific->m_is_ready = false; - - break; + try + { + app->m_specific->create_pmap(LOWORD(lParam), HIWORD(lParam), + &app->rbuf_window()); + + app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam)); + app->on_resize(LOWORD(lParam), HIWORD(lParam)); + app->force_redraw(); + } + catch (std::bad_alloc&) + { + ::PostQuitMessage(1); + } + + app->m_specific->m_is_ready = false; + + break; //-------------------------------------------------------------------- case WM_ERASEBKGND: @@ -666,8 +666,8 @@ namespace agg app->m_specific->m_current_dc = 0; ::EndPaint(hWnd, &ps); - app->m_specific->m_is_mapped = true; - app->m_specific->m_is_ready = true; + app->m_specific->m_is_mapped = true; + app->m_specific->m_is_ready = true; break; //-------------------------------------------------------------------- @@ -748,31 +748,31 @@ namespace agg } - try - { - RECT rct; - ::GetClientRect(m_specific->m_hwnd, &rct); + try + { + RECT rct; + ::GetClientRect(m_specific->m_hwnd, &rct); - ::MoveWindow(m_specific->m_hwnd, // handle to window - 100, // horizontal position - 100, // vertical position - width + (width - (rct.right - rct.left)), - height + (height - (rct.bottom - rct.top)), - FALSE); + ::MoveWindow(m_specific->m_hwnd, // handle to window + 100, // horizontal position + 100, // vertical position + width + (width - (rct.right - rct.left)), + height + (height - (rct.bottom - rct.top)), + FALSE); - ::SetWindowLong(m_specific->m_hwnd, GWL_USERDATA, (LONG)this); - m_specific->create_pmap(width, height, &m_rbuf_window); - m_initial_width = width; - m_initial_height = height; - on_init(); - m_specific->m_redraw_flag = true; - ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show); - ::SetForegroundWindow(m_specific->m_hwnd); - } - catch (std::bad_alloc&) - { - return false; - } + ::SetWindowLong(m_specific->m_hwnd, GWL_USERDATA, (LONG)this); + m_specific->create_pmap(width, height, &m_rbuf_window); + m_initial_width = width; + m_initial_height = height; + on_init(); + m_specific->m_redraw_flag = true; + ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show); + ::SetForegroundWindow(m_specific->m_hwnd); + } + catch (std::bad_alloc&) + { + return false; + } return true; } @@ -787,25 +787,25 @@ namespace agg { if(m_wait_mode) { - bool status; - - if (m_specific->m_is_ready) - { - pthread_mutex_unlock (m_specific->m_mutex); - status = ::GetMessage(&msg, 0, 0, 0); - pthread_mutex_lock (m_specific->m_mutex); - } - else - { - status = ::GetMessage(&msg, 0, 0, 0); - } - - if(! status) + bool status; + + if (m_specific->m_is_ready) + { + pthread_mutex_unlock (m_specific->m_mutex); + status = ::GetMessage(&msg, 0, 0, 0); + pthread_mutex_lock (m_specific->m_mutex); + } + else + { + status = ::GetMessage(&msg, 0, 0, 0); + } + + if(! status) { - break; + break; } - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); } else { @@ -885,9 +885,9 @@ namespace agg if(width == 0) width = m_specific->m_pmap_window.width(); if(height == 0) height = m_specific->m_pmap_window.height(); - pixel_map& pmap = m_specific->m_pmap_img[idx]; + pixel_map& pmap = m_specific->m_pmap_img[idx]; pmap.create(width, height, org_e(m_specific->m_bpp)); - pixel_map_attach (pmap, &m_rbuf_img[idx], m_flip_y); + pixel_map_attach (pmap, &m_rbuf_img[idx], m_flip_y); return true; } return false; @@ -925,6 +925,38 @@ namespace agg void platform_support::on_post_draw(void* raw_handler) {} } +agg::pix_format_e gslshell::sys_pixel_format = agg::pix_format_bgr24; +unsigned gslshell::bpp = 24; +unsigned gslshell::sys_bpp = 24; + +bool +platform_support_ext::save_image_file (agg::rendering_buffer& src, const char *fn) +{ + unsigned slen = strlen (fn); + char *fnext = new char[slen+5]; + sprintf (fnext, "%s.bmp", fn); + + agg::pixel_map pmap; + try + { + pmap.create(src.width(), src.height(), agg::org_e(gslshell::sys_bpp)); + + agg::rendering_buffer rbuf_tmp; + pixel_map_attach (pmap, &rbuf_tmp, gslshell::flip_y); + + agg::convert_pmap (&rbuf_tmp, &src, gslshell::pixel_format, true); + } + catch (std::bad_alloc&) + { + delete [] fnext; + return false; + } + + bool status = pmap.save_as_bmp (fnext); + delete [] fnext; + return status; +} + void platform_support_ext::prepare() { diff --git a/agg-plot/bitmap-plot.cpp b/agg-plot/bitmap-plot.cpp new file mode 100644 index 00000000..faef9710 --- /dev/null +++ b/agg-plot/bitmap-plot.cpp @@ -0,0 +1,60 @@ + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +} + +#include "bitmap-plot.h" +#include "lua-cpp-utils.h" +#include "lua-plot-cpp.h" +#include "gs-types.h" +#include "canvas.h" +#include "colors.h" +#include "agg-pixfmt-config.h" +#include "platform_support_ext.h" + +int +bitmap_save_image (lua_State *L) +{ + lua_plot *p = object_check<lua_plot>(L, 1, GS_PLOT); + const char *fn = luaL_checkstring (L, 2); + int w = luaL_optint (L, 3, 480), h = luaL_optint (L, 4, 480); + + if (w <= 0 || w > 1024 * 8) + luaL_error (L, "width out of range"); + + if (h <= 0 || h > 1024 * 8) + luaL_error (L, "height out of range"); + + unsigned char * buffer = 0; + try + { + agg::rendering_buffer rbuf_tmp; + unsigned row_size = w * (gslshell::bpp / 8); + unsigned buf_size = h * row_size; + buffer = new unsigned char[buf_size]; + rbuf_tmp.attach(buffer, w, h, gslshell::flip_y ? row_size : -row_size); + + canvas can(rbuf_tmp, w, h, colors::white); + agg::trans_affine mtx(w, 0.0, 0.0, h, 0.0, 0.0); + + agg::rect_base<int> r = rect_of_slot_matrix<int>(mtx); + can.clear_box(r); + + p->draw(can, mtx); + + if (! platform_support_ext::save_image_file (rbuf_tmp, fn)) + { + delete [] buffer; + return luaL_error (L, "error saving image in filename %s", fn); + } + } + catch (std::bad_alloc&) + { + if (buffer == 0) delete [] buffer; + return luaL_error (L, "out of virtual memory"); + } + + delete [] buffer; + return 0; +} diff --git a/agg-plot/bitmap-plot.h b/agg-plot/bitmap-plot.h new file mode 100644 index 00000000..68aa9e08 --- /dev/null +++ b/agg-plot/bitmap-plot.h @@ -0,0 +1,12 @@ +#ifndef BITMAP_PLOT_H +#define BITMAP_PLOT_H + +extern "C" { + +#include "lua.h" + +extern int bitmap_save_image (lua_State *L); + +} + +#endif diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp index af130527..12971bb7 100644 --- a/agg-plot/lua-plot.cpp +++ b/agg-plot/lua-plot.cpp @@ -25,6 +25,7 @@ extern "C" { #include "lua-plot.h" #include "lua-plot-cpp.h" +#include "bitmap-plot.h" #include "window.h" #include "gs-types.h" #include "lua-utils.h" @@ -83,6 +84,7 @@ static const struct luaL_Reg plot_methods[] = { {"pushlayer", plot_push_layer }, {"poplayer", plot_pop_layer }, {"clear", plot_clear }, + {"save", bitmap_save_image }, {"__index", plot_index }, {"__newindex", plot_newindex }, {"__gc", plot_free }, diff --git a/agg-plot/platform_support_ext.h b/agg-plot/platform_support_ext.h index e3d8f320..21b32e11 100644 --- a/agg-plot/platform_support_ext.h +++ b/agg-plot/platform_support_ext.h @@ -19,6 +19,8 @@ public: void do_window_update (); static void prepare(); + + static bool save_image_file (agg::rendering_buffer& src, const char *fn); }; template<class RenBufDst, class RenBufSrc, class CopyRow> |