#include <math.h>
#define GDK_PIXBUF_ENABLE_BACKEND
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk-pixbuf/gdk-pixdata.h>
+#include <gtk/gtk.h>
#include "rbgobject.h"
#define _SELF(s) GDK_PIXBUF(RVAL2GOBJ(s))
+#include <libexif/exif-data.h>
+
static VALUE
whitebalance(self, level)
VALUE self, level;
return self;
}
+static ExifEntry* exif_entry(VALUE filename, ExifTag tag, ExifData** data) {
+ unsigned int i;
+
+ *data = exif_data_new_from_file(StringValuePtr(filename));
+ if (*data == NULL) {
+ fprintf(stderr, "libexif failed loading file '%s'\n", StringValuePtr(filename));
+ return NULL;
+ }
+
+ for (i = 0; i < EXIF_IFD_COUNT; i++) {
+ ExifEntry* entry = exif_content_get_entry((*data)->ifd[i], tag);
+ if (entry)
+ return entry;
+ }
+
+ return NULL;
+}
+
+static VALUE exif_orientation(VALUE module, VALUE filename) {
+ ExifData* data = NULL;
+ ExifEntry* entry;
+
+ entry = exif_entry(filename, EXIF_TAG_ORIENTATION, &data);
+
+ if (entry != NULL) {
+ VALUE ret;
+ ExifByteOrder o;
+ ExifShort v_short;
+ if (!entry || !entry->parent || !entry->parent->parent)
+ return Qnil;
+ o = exif_data_get_byte_order(entry->parent->parent);
+ v_short = exif_get_short(entry->data, o);
+ ret = INT2NUM(v_short);
+ exif_data_free(data);
+ return ret;
+ }
+
+ if (data)
+ exif_data_free(data);
+ return Qnil;
+}
+
+static VALUE exif_datetimeoriginal(VALUE module, VALUE filename) {
+ ExifData* data = NULL;
+ ExifEntry* entry;
+
+ entry = exif_entry(filename, EXIF_TAG_DATE_TIME_ORIGINAL, &data);
+
+ if (entry != NULL) {
+ VALUE ret = rb_str_new((const char*) entry->data, entry->size);
+ exif_data_free(data);
+ return ret;
+ }
+
+ if (data)
+ exif_data_free(data);
+ return Qnil;
+}
+
+static VALUE draw_borders(VALUE self, VALUE pixbuf, VALUE x1, VALUE x2, VALUE ystart, VALUE yend) {
+ GdkDrawable* drawable = GDK_DRAWABLE(RVAL2GOBJ(self));
+ int y = NUM2INT(ystart);
+ int yend_ = NUM2INT(yend);
+ GdkPixbuf* pb = GDK_PIXBUF(RVAL2GOBJ(pixbuf));
+ int height = gdk_pixbuf_get_height(pb);
+ while (y < yend_) {
+ int render_height = MIN(height, yend_ - y);
+ gdk_draw_pixbuf(drawable, NULL, pb, 0, 0, NUM2INT(x1), y, -1, render_height, GDK_RGB_DITHER_NONE, -1, -1);
+ gdk_draw_pixbuf(drawable, NULL, pb, 0, 0, NUM2INT(x2), y, -1, render_height, GDK_RGB_DITHER_NONE, -1, -1);
+ y += height;
+ }
+ return self;
+}
+
+
void
-Init_gtkadds()
+Init_libadds()
{
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);
+
+ cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GDK_TYPE_DRAWABLE, Qnil);
+ rb_define_method(cinfo->klass, "draw_borders", draw_borders, 5);
+
+ VALUE exif = rb_define_module("Exif");
+ rb_define_module_function(exif, "orientation", exif_orientation, 1);
+ rb_define_module_function(exif, "datetimeoriginal", exif_datetimeoriginal, 1);
}