Giter VIP home page Giter VIP logo

Comments (17)

rageworx avatar rageworx commented on May 29, 2024

Support limits

  • it is experimental
  • only availed for fltk-custom, not fltk/fltk.

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Changes of Fl_Image.H

  • included new features for
/** \enum Fl_RGB_Scaling
 The scaling algorithm to use for RGB images.
*/
enum Fl_RGB_Scaling {
  FL_RGB_SCALING_NEAREST = 0, ///< default RGB image scaling algorithm
#ifndef FLTK_EXT_VERSION
  FL_RGB_SCALING_BILINEAR     ///< more accurate, but slower RGB image scaling algorithm
#else
  FL_RGB_SCALING_BILINEAR = 1,
  FL_RGB_SCALING_USER
#endif /// of FLTK_EXT_VERSION    
};

#ifdef FLTK_EXT_VERSION
/** User scaling callback type definition for FL_RGB_SCALING_USER */
typedef void (Fl_Image_UserScale)(Fl_RGB_Image*, int, int, int, int, Fl_RGB_Image**);
typedef Fl_Image_UserScale* Fl_Image_UserScale_p; // needed for BORLAND
#endif /// of FLTK_EXT_VERSION    
  • and in a Fl_Image.H class
class FL_EXPORT Fl_Image {
  friend class Fl_Graphics_Driver;
public:
  static const int ERR_NO_IMAGE       = -1;
  static const int ERR_FILE_ACCESS    = -2;
  static const int ERR_FORMAT         = -3;
  static const int ERR_MEMORY_ACCESS  = -4;

private:
  int w_, h_, d_, ld_, count_;
  int data_w_, data_h_;
  const char * const *data_;
  static Fl_RGB_Scaling RGB_scaling_; // method used when copying RGB images
  static Fl_RGB_Scaling scaling_algorithm_; // method used to rescale RGB source images before drawing
#ifdef FLTK_EXT_VERSION
  static Fl_Image_UserScale_p user_scaling_; /// user scaling callback method.
#endif /// of FLTK_EXT_VERSION
...
  /** Sets what algorithm is used when resizing a source image to draw it.
   The default algorithm is FL_RGB_SCALING_BILINEAR.
   Drawing an Fl_Image is sometimes performed by first resizing the source image
   and then drawing the resized copy. This occurs, e.g., when drawing to screen under X11
   without Xrender support after having called scale().
   This function controls what method is used when the image to be resized is an Fl_RGB_Image.
   \version 1.4
   */
#ifndef FLTK_EXT_VERSION
  static void scaling_algorithm(Fl_RGB_Scaling algorithm) {scaling_algorithm_ = algorithm; }
#else 
  /** In version of FLTK-custom provides FL_RGB_SCALING_USER with userscale callback method,
   to better image quality. userscale only needed when algorithm set to FL_RGB_SCALING_USER.
   */
  static void scaling_algorithm(Fl_RGB_Scaling algorithm, Fl_Image_UserScale* userscale = NULL) 
  {
      scaling_algorithm_ = algorithm;
      user_scaling_ = userscale;
  }
  
  static Fl_Image_UserScale* user_scaling_algorithm() { return user_scaling_; }
#endif /// of FLTK_EXT_VERSION    

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Changes of Fl_GDI_Graphics_Driver_Image.cxx

  • function draw_rgb()
void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
  if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
    return;
  }
  if ((rgb->d() % 2) == 0 && !fl_can_do_alpha_blending()) {
    Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
    return;
  }
  if (!*Fl_Graphics_Driver::id(rgb)) {
    cache(rgb);
  }
  push_clip(XP, YP, WP, HP);
  XP -= cx; YP -= cy;
  WP = rgb->w(); HP = rgb->h();
  cache_size(rgb, WP, HP);
  HDC new_gc = CreateCompatibleDC(gc_);
  int save = SaveDC(new_gc);
  SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
#ifdef FLTK_EXT_VERSION
  int sclsucc = 0;
  Fl_Image_UserScale_p usrscl = Fl_Image::user_scaling_algorithm();
  if ( (Fl_Image::scaling_algorithm() == FL_RGB_SCALING_USER) && (usrscl != NULL ) ) {
    Fl_RGB_Image* sclrgb = NULL;    
    usrscl( rgb, this->floor(XP), this->floor(YP), WP, HP, &sclrgb );
    if ( sclrgb != NULL ) {
      cache(sclrgb);
      WP = sclrgb->w();
      HP = sclrgb->h();
      cache_size(rgb, WP, HP);
      SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(sclrgb));
      if ( (sclrgb->d() % 2) == 0 ) {
        alpha_blend_(this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, sclrgb->data_w(), sclrgb->data_h());
      } else {
        SetStretchBltMode(gc_, HALFTONE);
        StretchBlt(gc_, this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, sclrgb->data_w(), sclrgb->data_h(), SRCCOPY);
      }
      delete sclrgb;
      
      sclsucc = 1;
    }
  }
  
  if (sclsucc == 0)
  {
#endif /// of FLTK_EXT_VERSION
    if ( (rgb->d() % 2) == 0 ) {
      alpha_blend_(this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
    } else {
      SetStretchBltMode(gc_, HALFTONE);
      StretchBlt(gc_, this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
    }
#ifdef FLTK_EXT_VERSION  
  }
#endif /// of FLTK_EXT_VERSION
  
  RestoreDC(new_gc, save);
  DeleteDC(new_gc);
  pop_clip();
}

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Implementation

void usr_scale(Fl_RGB_Image* s, int x, int y, int w, int h, Fl_RGB_Image** o)
{
    printf( "(debug)usr_scale( %p, %d, %d, %d, %d, .. );\n",
            s, x, y, w, h );

    if ( s != NULL )
    {
        printf( "(debug)s->w() = %d, s->h() = %d\n", s->w(), s->h() );
        Fl_RGB_Image* r = fl_imgtk::rescale( s, w, h, fl_imgtk::BICUBIC );
        printf( "(debug)o->w() = %d, o->h() = %d\n", r->w(), r->h() );
        *o = r;
    }
    
    fflush( stdout );
}

void presetFLTKenv()
{
    Fl::set_font( FL_FREE_FONT, convLng );
    Fl_Double_Window::default_xclass( DEF_APP_CLSNAME );

#ifdef FLTK_EXT_VERSION
    Fl::scheme( "flat" );
    
    Fl_Image:: scaling_algorithm( FL_RGB_SCALING_USER, usr_scale );
#else
    Fl::scheme( "gtk+" );
    // Default RGB image scaling for high-DPI, but not works on Windows.
    Fl_Image::scaling_algorithm( FL_RGB_SCALING_BILINEAR );
#endif /// of FLTK_EXT_VERSION

}

Debugging Status,

  • Looks somewhere memory leakage occurs.
  • Wrong draw area.

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Fixed draw_rgb()

void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
  if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
    return;
  }
  if ((rgb->d() % 2) == 0 && !fl_can_do_alpha_blending()) {
    Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
    return;
  }
  if (!*Fl_Graphics_Driver::id(rgb)) {
    cache(rgb);
  }
  push_clip(XP, YP, WP, HP);
  XP -= cx; YP -= cy;
  WP = rgb->w(); HP = rgb->h();
  cache_size(rgb, WP, HP);
  HDC new_gc = CreateCompatibleDC(gc_);
  int save = SaveDC(new_gc);
  SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
#ifdef FLTK_EXT_VERSION
  int sclsucc = 0;
  Fl_Image_UserScale_p usrscl = Fl_Image::user_scaling_algorithm();
  if ( (Fl_Image::scaling_algorithm() == FL_RGB_SCALING_USER) && (usrscl != NULL ) ) {
    Fl_RGB_Image* sclrgb = NULL;    
    usrscl( rgb, this->floor(XP), this->floor(YP), WP, HP, &sclrgb );
    if ( sclrgb != NULL ) {
      cache(sclrgb);
      //WP = sclrgb->w();
      //HP = sclrgb->h();
      //cache_size(rgb, WP, HP);
      SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(sclrgb));
      if ( (sclrgb->d() % 2) == 0 ) {
        alpha_blend_(this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, sclrgb->data_w(), sclrgb->data_h());
      } else {
        SetStretchBltMode(gc_, HALFTONE);
        StretchBlt(gc_, this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, sclrgb->data_w(), sclrgb->data_h(), SRCCOPY);
      }
      delete sclrgb;
      DeleteObject(new_gc);
      
      sclsucc = 1;
    }
  }
  
  if (sclsucc == 0)
  {
#endif /// of FLTK_EXT_VERSION
    if ( (rgb->d() % 2) == 0 ) {
      alpha_blend_(this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
    } else {
      SetStretchBltMode(gc_, HALFTONE);
      StretchBlt(gc_, this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
    }
#ifdef FLTK_EXT_VERSION  
  }
#endif /// of FLTK_EXT_VERSION
  
  RestoreDC(new_gc, save);
  DeleteDC(new_gc);
  pop_clip();
}

Testing by scaling up with Ctrl+"+" key to 170%, BICUBIC.

image

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Downscaling

image

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Memory leakage, by user scaling ?

image

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Leakage reason,

  • new scaled image to be cached by Fl_GDI_Graphcs_Driver::cache(Fl_RGB_Image* img).
  • In Fl_GDI_Graphcs_Driver::cache(Fl_RGB_Image* img),
    • Creates a Fl_Offscreen,
    • And set *Fl_Graphics_Driver::id(img) to offscreen.

Question,

  • Where release *Fl_Graphics_Driver::id() ?

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Leakage trace ...

  • In a start time,
    image
  • Scaling up and down in multiple time
    image

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Sources are being updated to branch of https://github.com/rageworx/fltk-custom/tree/1.4.0-dev-usr-scaling.

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Leakage solved, and tested.

at ce086ca.

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

New error reported,

  • some other application unexpected termination by
Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Error occurs on void Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img).

  • void Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img) don't test Fl_Image_Surface* surface as NULL.

fl_draw_image() signal segment fault ?

    if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) {
      fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld());
    } else {
      fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d(), img->ld());
      if (img->d() == 2 || img->d() == 4) {
        *Fl_Graphics_Driver::mask(img) = (fl_uintptr_t)create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
      }
    }

from ...

cache->1,2,3,4,5,done
usr_scale, 0, 0, 1109, 50 ...
(debug)s(0000013d526a6c80, 1109x50x3) ->scaled?(0) : o(1109x50x3) == 0000013d526a6da0
(debug)draw_rgb, user scale debug ...
(debug) .. caching Fl_RGB_Image(0000013d526a6da0) ...
cache->1,2,3,4,5,done
(debug) ... step #2
(debug) ... step #3
(debug) ... step #4
(debug) ... step #5
(debug) ... step #6
(debug) ... step #7
cache->1,2,3,4,5,done
usr_scale, 22, 12, 25, 25 ...
(debug)s(0000013d5269b870, 25x25x4) ->scaled?(0) : o(25x25x4) == 0000013d526b5fe0
(debug)draw_rgb, user scale debug ...
(debug) .. caching Fl_RGB_Image(0000013d526b5fe0) ...
cache->1,2,%                                                           

Segment fault in ..

fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld());

and it calls to ...

void Fl_Scalable_Graphics_Driver::draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) {
  if (scale() == 1) {
    draw_image_unscaled(buf, X,Y,W,H,D,L);
  } else {
    draw_image_rescale((void*)buf, NULL, X, Y, W, H, D, L, false);
  }
}

in Fl_Graphics_Driver -> Fl_GDI_Graphics_Driver_Image, innards().

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Segment fault caused by null buffer reference in innards().

(debug)void innards( 0000000000000000, 0, 0, 25, 25, delta=4, ld=0, d=4, 0000000000000000, 0000000000000000, HDC=2181115365

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

25x25 image may a SVG, and it must be converted to RGBA, but why not contains array ?

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Error fixed, to check sclrgb->array has pointer.

from fltk-custom.

rageworx avatar rageworx commented on May 29, 2024

Final testing almost completed in another commercial project that runs on Windows GDI( and GDI+) and fl_imgtk fixed bug library for refer to Fl_RGB_Image data width and height.
Most of changes committed to v1.4.0-dev-user-scaling branch.

from fltk-custom.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.