From 1a8478acb600f848f0b24eaa9b65ebd07017d7a5 Mon Sep 17 00:00:00 2001
From: Lars Kanis <lars@greiz-reinsdorf.de>
Date: Mon, 17 Mar 2014 10:29:10 +0100
Subject: [PATCH] FXImage: Move code that ensures, that non owned pixel data
 isn't GC'ed to Ruby space.

This way it also works for derived classes like FXJPGImage.
---
 ext/fox16_c/include/FXRbImage.h |  4 +---
 ext/fox16_c/markfuncs.cpp       |  3 ---
 lib/fox16/core.rb               | 14 ++++++++++++++
 swig-interfaces/FXImage.i       |  5 +----
 test/TC_FXBMPImage.rb           | 13 +++++++++++++
 5 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/ext/fox16_c/include/FXRbImage.h b/ext/fox16_c/include/FXRbImage.h
index f2d6582..c071d8d 100644
--- a/ext/fox16_c/include/FXRbImage.h
+++ b/ext/fox16_c/include/FXRbImage.h
@@ -143,11 +143,9 @@ protected:
 #include "FXRbIdVirtuals.h"
 #include "FXRbDrawableVirtuals.h"
 #include "FXRbImageVirtuals.h"
-
-  VALUE data_string;
 public:
   /// Create an image
-  FXRbImage(FXApp* a,const FXColor* pix=NULL,FXuint opts=0,FXint w=1,FXint h=1):FXImage(a,pix,opts,w,h),data_string(Qnil){
+  FXRbImage(FXApp* a,const FXColor* pix=NULL,FXuint opts=0,FXint w=1,FXint h=1):FXImage(a,pix,opts,w,h){
     FXRbRegisterAppSensitiveObject(this);
     }
 
diff --git a/ext/fox16_c/markfuncs.cpp b/ext/fox16_c/markfuncs.cpp
index 65d2422..e001bbb 100644
--- a/ext/fox16_c/markfuncs.cpp
+++ b/ext/fox16_c/markfuncs.cpp
@@ -121,9 +121,6 @@ void FXRbIcon::markfunc(FXIcon* icon){
 
 void FXRbImage::markfunc(FXImage* image){
   FXRbDrawable::markfunc(image);
-  if( image ){
-    rb_gc_mark(dynamic_cast<FXRbImage*>(image)->data_string);
-    }
   }
 
 
diff --git a/lib/fox16/core.rb b/lib/fox16/core.rb
index 48ed0d4..18e56bb 100755
--- a/lib/fox16/core.rb
+++ b/lib/fox16/core.rb
@@ -696,5 +696,19 @@ module Fox
 =end
 
   end
+
+  class FXImage
+    alias initialize_without_data_string initialize
+    def initialize(a, pix, *args)
+      initialize_without_data_string(a, pix, *args)
+      @data_string = (options & IMAGE_OWNED) != 0 ? nil : pix
+    end
+
+    alias setPixels_without_data_string setPixels
+    def setPixels(pix, *args)
+      setPixels_without_data_string(pix, *args)
+      @data_string = (options & IMAGE_OWNED) != 0 ? nil : pix
+    end
+  end
 end
 
diff --git a/swig-interfaces/FXImage.i b/swig-interfaces/FXImage.i
index d01dc08..c472d73 100644
--- a/swig-interfaces/FXImage.i
+++ b/swig-interfaces/FXImage.i
@@ -64,9 +64,7 @@ public:
         }
         pix=FXRbConvertToFXColors(string_or_ary, &opts);
       }
-      FXRbImage *img = new FXRbImage(a,pix,opts,w,h);
-      img->data_string = (opts & IMAGE_OWNED) ? Qnil : string_or_ary;
-      return img;
+      return new FXRbImage(a,pix,opts,w,h);
     }
 
     /// To get to the pixel data
@@ -101,7 +99,6 @@ public:
       }
 
       FXColor* pix=FXRbConvertToFXColors(string_or_ary, &opts);
-      (dynamic_cast<FXRbImage*>(self))->data_string = (opts & IMAGE_OWNED) ? Qnil : string_or_ary;
       if( NIL_P(w) || NIL_P(h) ){
         self->setData(pix,opts);
       }else{
diff --git a/test/TC_FXBMPImage.rb b/test/TC_FXBMPImage.rb
index fc95f95..89050f2 100755
--- a/test/TC_FXBMPImage.rb
+++ b/test/TC_FXBMPImage.rb
@@ -12,4 +12,17 @@ class TC_FXBMPImage < Fox::TestCase
   def test_fileExt
     assert_equal("bmp", FXBMPImage.fileExt)
   end
+
+  def test_image_from_pixel_data
+    img = FXBMPImage.new app
+    img.setPixels "rgbaRGBA", 0, 1, 2
+    bmp_data = FXMemoryStream.open(FXStreamSave, nil) do |outfile|
+      img.savePixels(outfile)
+      outfile.takeBuffer
+    end
+    assert_not_equal "rgbaRGBA", bmp_data
+
+    img2 = FXBMPImage.new app, bmp_data
+    assert_equal "rgbaRGBA", img2.pixel_string
+  end
 end
-- 
GitLab