add gamma correction suggested by coni
[booh] / ext / rbbooh.c
index 12285ed5b1020ed4c3ae0b7d4d55352d48454313..2d886888f2ab7b1449518472414486c5afe09b4c 100644 (file)
@@ -59,9 +59,40 @@ whitebalance(self, level)
         return self;
 }
 
+static VALUE
+gammacorrect(self, level)
+    VALUE self, level; 
+{
+        double filter[256];
+        int i, x, y;
+        guchar* pixels = gdk_pixbuf_get_pixels(_SELF(self));
+        int rowstride = gdk_pixbuf_get_rowstride(_SELF(self));
+
+        double factor = 1 + fabs(NUM2DBL(level))/100;
+        if (NUM2DBL(level) > 0) {
+                factor = 1/factor;
+        }
+
+        for (i = 0; i < 256; i++) {
+                filter[i] = pow(((double)i)/255, factor) * 255;
+        }
+    
+        for (y = 0; y < gdk_pixbuf_get_height(_SELF(self)); y++) {
+                guchar* pixline = &(pixels[rowstride*y]);
+                for (x = 0; x < gdk_pixbuf_get_width(_SELF(self)); x++) {
+                        pixline[x*3]   = filter[pixline[x*3]];
+                        pixline[x*3+1] = filter[pixline[x*3+1]];
+                        pixline[x*3+2] = filter[pixline[x*3+2]];
+                }
+        }
+
+        return self;
+}
+
 void 
 Init_gtkadds()
 {
     RGObjClassInfo* cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GDK_TYPE_PIXBUF, Qnil);
     rb_define_method(cinfo->klass, "whitebalance!", whitebalance, 1); 
+    rb_define_method(cinfo->klass, "gammacorrect!", gammacorrect, 1); 
 }