#include <math.h>
+#include <exiv2/image.hpp>
+#include <exiv2/exif.hpp>
+
#define GDK_PIXBUF_ENABLE_BACKEND
#include <gtk/gtk.h>
#include "rbgobject.h"
#define _SELF(s) GDK_PIXBUF(RVAL2GOBJ(s))
-#include <libexif/exif-data.h>
-
static VALUE whitebalance(VALUE self, VALUE level) {
double red_filter[256], blue_filter[256];
int i, x, y;
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;
+static VALUE exif_orientation(VALUE module, VALUE filename) {
+ try {
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(StringValuePtr(filename));
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+ if (exifData.empty()) {
+ return Qnil;
+ }
+ Exiv2::ExifData::const_iterator i = exifData.findKey(Exiv2::ExifKey("Exif.Image.Orientation"));
+ if (i != exifData.end()) {
+ return INT2NUM(i->value().toLong());
+ }
+ return Qnil;
+ } catch (Exiv2::AnyError& e) {
+ std::cout << "Caught Exiv2 exception: " << e << "\n";
+ return Qnil;
}
-
- 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);
+static VALUE exif_set_orientation(VALUE module, VALUE filename, VALUE val) {
+ try {
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(StringValuePtr(filename));
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+ exifData["Exif.Image.Orientation"] = uint16_t(NUM2INT(val));
+ image->writeMetadata();
+ } catch (Exiv2::AnyError& e) {
+ std::cout << "Caught Exiv2 exception: " << e << "\n";
+ }
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;
+ try {
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(StringValuePtr(filename));
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+ if (exifData.empty()) {
+ return Qnil;
+ }
+ Exiv2::ExifData::const_iterator i = exifData.findKey(Exiv2::ExifKey("Exif.Photo.DateTimeOriginal"));
+ if (i != exifData.end()) {
+ return rb_str_new2(i->value().toString().c_str());
+ }
+ return Qnil;
+ } catch (Exiv2::AnyError& e) {
+ std::cout << "Caught Exiv2 exception: " << e << "\n";
+ return Qnil;
+ }
}
// internalize drawing "video" borders, it is too slow in ruby (0.12 secs on my p4 2.8 GHz, whereas it's barely measurable with this implementation)
// (bugged as of rg2 0.16.0)
static VALUE rotate_noleak(VALUE self, VALUE angle) {
VALUE ret;
- GdkPixbuf* dest = gdk_pixbuf_rotate_simple(_SELF(self), RVAL2GENUM(angle, GDK_TYPE_PIXBUF_ROTATION));
+ GdkPixbuf* dest = gdk_pixbuf_rotate_simple(_SELF(self), (GdkPixbufRotation) RVAL2GENUM(angle, GDK_TYPE_PIXBUF_ROTATION));
if (dest == NULL)
return Qnil;
ret = GOBJ2RVAL(dest);
// internalize allowing to pass Qnil to RVAL2BOXED to have NULL passed to Gtk
// (bugged as of rg2 0.16.0)
static VALUE modify_bg(VALUE self, VALUE state, VALUE color) {
- gtk_widget_modify_bg(GTK_WIDGET(RVAL2GOBJ(self)), RVAL2GENUM(state, GTK_TYPE_STATE_TYPE),
+ gtk_widget_modify_bg(GTK_WIDGET(RVAL2GOBJ(self)), (GtkStateType) RVAL2GENUM(state, GTK_TYPE_STATE_TYPE),
NIL_P(color) ? NULL : (GdkColor*) RVAL2BOXED(color, GDK_TYPE_COLOR));
return self;
}
+extern "C" {
void
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);
- rb_define_method(cinfo->klass, "rotate", rotate_noleak, 1);
+ rb_define_method(cinfo->klass, "whitebalance!", (VALUE (*)(...)) whitebalance, 1);
+ rb_define_method(cinfo->klass, "gammacorrect!", (VALUE (*)(...)) gammacorrect, 1);
+ rb_define_method(cinfo->klass, "rotate", (VALUE (*)(...)) rotate_noleak, 1);
cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GDK_TYPE_DRAWABLE, Qnil);
- rb_define_method(cinfo->klass, "draw_borders", draw_borders, 5);
+ rb_define_method(cinfo->klass, "draw_borders", (VALUE (*)(...)) draw_borders, 5);
cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GTK_TYPE_WIDGET, Qnil);
- rb_define_method(cinfo->klass, "modify_bg", modify_bg, 2);
+ rb_define_method(cinfo->klass, "modify_bg", (VALUE (*)(...)) modify_bg, 2);
VALUE exif = rb_define_module("Exif");
- rb_define_module_function(exif, "orientation", exif_orientation, 1);
- rb_define_module_function(exif, "datetimeoriginal", exif_datetimeoriginal, 1);
+ rb_define_module_function(exif, "orientation", (VALUE (*)(...)) exif_orientation, 1);
+ rb_define_module_function(exif, "set_orientation", (VALUE (*)(...)) exif_set_orientation, 2);
+ rb_define_module_function(exif, "datetimeoriginal", (VALUE (*)(...)) exif_datetimeoriginal, 1);
+}
}