diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-19 01:06:45 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-19 01:06:45 +0000 |
| commit | 1acc39c5d8d5b3db88abfd008699dadb8aade2b9 (patch) | |
| tree | c35a486fc713b48c85286ce42291aa88e6652e7e /src/Fl_Image.cxx | |
| parent | 681ded73c20af217254a8dfb7838b612b17b126c (diff) | |
OK, lots of changes to the Fl_Image, Fl_Bitmap, Fl_Pixmap, and Fl_RGB_Image
classes: new copy(), copy(w,h), desaturate(), color_average(), and
inactive() methods, alloc_xyz member for copied data, etc.
Updated test programs to use inactive() and copy() methods to create
inactive images for the test buttons, plus the inactive button to toggle
it...
Added start of separate image classes, a la 2.0, for various image formats.
FLUID will also be updated for it...
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1703 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Image.cxx')
| -rw-r--r-- | src/Fl_Image.cxx | 176 |
1 files changed, 173 insertions, 3 deletions
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx index e2e7bd843..3663e4224 100644 --- a/src/Fl_Image.cxx +++ b/src/Fl_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.cxx,v 1.5.2.3.2.2 2001/11/18 20:52:28 easysw Exp $" +// "$Id: Fl_Image.cxx,v 1.5.2.3.2.3 2001/11/19 01:06:45 easysw Exp $" // // Image drawing code for the Fast Light Tool Kit (FLTK). // @@ -39,6 +39,16 @@ Fl_Image::~Fl_Image() { void Fl_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { } +Fl_Image *Fl_Image::copy(int W, int H) { + return new Fl_Image(W, H); +} + +void Fl_Image::color_average(Fl_Color c, float i) { +} + +void Fl_Image::desaturate() { +} + void Fl_Image::label(Fl_Widget* w) { w->image(this); } @@ -48,6 +58,166 @@ void Fl_Image::label(Fl_Menu_Item* m) { Fl_RGB_Image::~Fl_RGB_Image() { if (id) fl_delete_offscreen((Fl_Offscreen)id); + if (alloc_array) delete[] array; +} + +Fl_Image *Fl_RGB_Image::copy(int W, int H) { + // Optimize the simple copy where the width and height are the same... + if (W == w() && H == h()) return new Fl_RGB_Image(array, w(), h(), d, ld); + + // OK, need to resize the image data; allocate memory and + Fl_RGB_Image *new_image; // New RGB image + uchar *new_array, // New array for image data + *new_ptr; // Pointer into new array + const uchar *old_ptr; // Pointer into old array + int c, // Channel number + sy, // Source coordinate + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep; // X & Y step increments + + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = (w() / W) * d; + ymod = h() % H; + ystep = h() / H; + + // Allocate memory for the new image... + new_array = new uchar [W * H * d]; + new_image = new Fl_RGB_Image(new_array, W, H, d); + new_image->alloc_array = 1; + + // Scale the image using a nearest-neighbor algorithm... + for (dy = h(), sy = 0, yerr = H / 2, new_ptr = new_array; dy > 0; dy --) { + for (dx = w(), xerr = W / 2, old_ptr = array + sy * (w() * d + ld); + dx > 0; + dx --) { + for (c = 0; c < d; c ++) *new_ptr++ = old_ptr[c]; + + old_ptr += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + old_ptr += d; + } + } + + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + return new_image; +} + +void Fl_RGB_Image::color_average(Fl_Color c, float i) { + // Delete any existing pixmap/mask objects... + if (id) { + fl_delete_offscreen(id); + id = 0; + } + + if (mask) { + fl_delete_bitmask(mask); + mask = 0; + } + + // Allocate memory as needed... + uchar *new_array, + *new_ptr; + + if (!alloc_array) new_array = new uchar[h() * w() * d]; + else new_array = (uchar *)array; + + // Get the color to blend with... + uchar r, g, b; + unsigned ia, ir, ig, ib; + + Fl::get_color(c, r, g, b); + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + ia = (unsigned)(256 * i); + ir = r * (256 - ia); + ig = g * (256 - ia); + ib = b * (256 - ia); + + // Update the image data to do the blend... + const uchar *old_ptr; + int x, y; + + if (d < 3) { + ig = (r * 31 + g * 61 + b * 8) / 100 * (256 - ia); + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + if (d > 1) *new_ptr++ = *old_ptr++; + } + } else { + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ir) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ib) >> 8; + if (d > 3) *new_ptr++ = *old_ptr++; + } + } + + // Set the new pointers/values as needed... + if (!alloc_array) { + array = new_array; + alloc_array = 1; + ld = 0; + } +} + +void Fl_RGB_Image::desaturate() { + // Can only desaturate color images... + if (d < 3) return; + + // Delete any existing pixmap/mask objects... + if (id) { + fl_delete_offscreen(id); + id = 0; + } + + if (mask) { + fl_delete_bitmask(mask); + mask = 0; + } + + // Allocate memory for a grayscale image... + uchar *new_array, + *new_ptr; + int new_d; + + new_d = d - 2; + new_array = new uchar[h() * w() * new_d]; + + // Copy the image data, converting to grayscale... + const uchar *old_ptr; + int x, y; + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld) + for (x = 0; x < w(); x ++, old_ptr += d) { + *new_ptr++ = (31 * old_ptr[0] + 61 * old_ptr[1] + 8 * old_ptr[2]) / 100; + if (d > 3) *new_ptr++ = old_ptr[3]; + } + + // Free the old array as needed, and then set the new pointers/values... + if (alloc_array) delete[] array; + + array = new_array; + alloc_array = 1; + d = new_d; + ld = 0; } void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { @@ -113,7 +283,7 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { // definitely fast... memset(bitmap, 0, bmw * h()); - for (dataptr = array + d - 1, y = 0; y < h(); y ++) + for (dataptr = array + d - 1, y = 0; y < h(); y ++, dataptr += ld) for (bitptr = bitmap + y * bmw, bit = 128, x = 0; x < w(); x ++, dataptr += d) { if (*dataptr > dither[x & 15][y & 15]) *bitptr |= bit; @@ -224,5 +394,5 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) { // -// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.2 2001/11/18 20:52:28 easysw Exp $". +// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.3 2001/11/19 01:06:45 easysw Exp $". // |
