diff options
Diffstat (limited to 'src/fl_read_image.cxx')
| -rw-r--r-- | src/fl_read_image.cxx | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx index e7d91b865..d3d32877f 100644 --- a/src/fl_read_image.cxx +++ b/src/fl_read_image.cxx @@ -3,7 +3,7 @@ // // X11 image reading routines for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2016 by Bill Spitzak and others. +// Copyright 1998-2018 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -17,6 +17,7 @@ // #include <FL/Fl.H> +#include <FL/platform.H> #include <FL/Fl_Screen_Driver.H> /** @@ -36,8 +37,55 @@ and the value that is placed in the alpha channel. If 0, no alpha channel is generated. */ -uchar *fl_read_image(uchar *p, int X, int Y, int W, int H, int alpha) { - return Fl::screen_driver()->read_image(p, X, Y, W, H, alpha); +uchar *fl_read_image(uchar *p, int X, int Y, int w, int h, int alpha) { + uchar *image_data = NULL; + Fl_RGB_Image *img; + if (fl_find(fl_window) == 0) { // read from off_screen buffer + img = Fl::screen_driver()->read_win_rectangle(X, Y, w, h); + if (!img) { + return NULL; + } + img->alloc_array = 1; + } else { + img = Fl::screen_driver()->traverse_to_gl_subwindows(Fl_Window::current(), X, Y, w, h, NULL); + } + int depth = alpha ? 4 : 3; + if (img->d() != depth) { + uchar *data = new uchar[img->w() * img->h() * depth]; + if (depth == 4) memset(data, alpha, img->w() * img->h() * depth); + uchar *d = data; + const uchar *q; + int ld = img->ld() ? img->ld() : img->w() * img->d(); + for (int r = 0; r < img->h(); r++) { + q = img->array + r * ld; + for (int c = 0; c < img->w(); c++) { + d[0] = q[0]; + d[1] = q[1]; + d[2] = q[2]; + d += depth; q += img->d(); + } + } + Fl_RGB_Image *img2 = new Fl_RGB_Image(data, img->w(), img->h(), depth); + img2->alloc_array = 1; + delete img; + img = img2; + } + if (img) { + if (img->w() != w || img->h() != h) { + Fl_RGB_Image *img2 = (Fl_RGB_Image*)img->copy(w, h); + delete img; + img = img2; + } + img->alloc_array = 0; + image_data = (uchar*)img->array; + delete img; + } + if (p && image_data) { + memcpy(p, image_data, w * h * depth); + delete[] image_data; + image_data = p; + } + return image_data; } // |
