ruby-exiv2 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/lib/exif.cpp ADDED
@@ -0,0 +1,127 @@
1
+ #include "exiv2.hpp"
2
+
3
+ VALUE exiv2_exif_get(VALUE self, VALUE key) {
4
+ __BEGIN
5
+ rbImage* image;
6
+ Data_Get_Struct(self, rbImage, image);
7
+
8
+ VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
9
+ Exiv2::ExifData &exifData = image->image->exifData();
10
+
11
+ if(exifData.empty()) {
12
+ return Qnil;
13
+ }
14
+
15
+ Exiv2::ExifKey exifKey(STR(strkey));
16
+ Exiv2::ExifData::const_iterator pos = exifData.findKey(exifKey);
17
+ if (pos == exifData.end()) {
18
+ return Qnil;
19
+ }
20
+
21
+ std::string v = pos->toString();
22
+ return rb_str_new(v.c_str(), v.length());
23
+ __NIL_END
24
+ }
25
+
26
+ VALUE exiv2_exif_set(VALUE self, VALUE key, VALUE value) {
27
+ __BEGIN
28
+ rbImage* image;
29
+ Data_Get_Struct(self, rbImage, image);
30
+
31
+ VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
32
+ VALUE strvalue = rb_funcall(value, rb_intern("to_s"), 0);
33
+ Exiv2::ExifData &exifData = image->image->exifData();
34
+
35
+ exifData[STR(strkey)] = STR(strvalue);
36
+ image->dirty = true;
37
+ return strvalue;
38
+ __NIL_END
39
+ }
40
+
41
+ VALUE exiv2_exif_each(int argc, VALUE *argv, VALUE self) {
42
+ __BEGIN
43
+ rbImage* image;
44
+ Data_Get_Struct(self, rbImage, image);
45
+
46
+ VALUE prefix;
47
+ rb_scan_args(argc, argv, "01", &prefix);
48
+
49
+ Exiv2::ExifData &exifData = image->image->exifData();
50
+ if(exifData.empty()) {
51
+ return self;
52
+ }
53
+
54
+ Exiv2::ExifData::const_iterator end = exifData.end();
55
+ for(Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
56
+ VALUE key = rb_str_new(i->key().c_str(), i->key().length());
57
+ VALUE val = rb_str_new(i->toString().c_str(), i->toString().length());
58
+ if(prefix != Qnil && INT2FIX(0) != rb_funcall(key, rb_intern("index"), 1, prefix)) {
59
+ continue;
60
+ }
61
+ rb_yield(rb_ary_new3(2, key, val));
62
+ }
63
+ return self;
64
+ __END
65
+ }
66
+
67
+ VALUE exiv2_exif_delete(VALUE self, VALUE key) {
68
+ __BEGIN
69
+ rbImage* image;
70
+ Data_Get_Struct(self, rbImage, image);
71
+
72
+ VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
73
+ Exiv2::ExifData &exifData = image->image->exifData();
74
+
75
+ if(exifData.empty()) {
76
+ return Qnil;
77
+ }
78
+
79
+ Exiv2::ExifKey exifKey(STR(strkey));
80
+ Exiv2::ExifData::const_iterator pos = exifData.findKey(exifKey);
81
+ if (pos == exifData.end()) {
82
+ return Qnil;
83
+ }
84
+
85
+ std::string v = pos->toString();
86
+ exifData.erase(pos);
87
+ return rb_str_new(v.c_str(), v.length());
88
+ __NIL_END
89
+ }
90
+
91
+ VALUE exiv2_exif_clear(VALUE self) {
92
+ __BEGIN
93
+ rbImage* image;
94
+ Data_Get_Struct(self, rbImage, image);
95
+
96
+ Exiv2::ExifData &exifData = image->image->exifData();
97
+
98
+ if(exifData.empty()) {
99
+ return Qnil;
100
+ }
101
+ exifData.clear();
102
+ return self;
103
+ __END
104
+ }
105
+
106
+
107
+ VALUE exiv2_exif_count(VALUE self) {
108
+ __BEGIN
109
+ rbImage* image;
110
+ Data_Get_Struct(self, rbImage, image);
111
+
112
+ Exiv2::ExifData &exifData = image->image->exifData();
113
+
114
+ return INT2FIX(exifData.count());
115
+ __END
116
+ }
117
+
118
+ VALUE exiv2_exif_empty(VALUE self) {
119
+ __BEGIN
120
+ rbImage* image;
121
+ Data_Get_Struct(self, rbImage, image);
122
+
123
+ Exiv2::ExifData &exifData = image->image->exifData();
124
+
125
+ return exifData.empty() ? Qtrue : Qfalse;
126
+ __NIL_END
127
+ }
data/lib/exiv2.cpp ADDED
@@ -0,0 +1,73 @@
1
+ // ***************************************************************** -*- C++ -*-
2
+ /*
3
+ * Copyright (C) 2006 Max Lapshin <max@maxidoors.ru>
4
+ *
5
+ * This program is part of the ruby-exiv2 distribution.
6
+ *
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License
9
+ * as published by the Free Software Foundation; either version 2
10
+ * of the License, or (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+ /*
22
+ Abstract: Driver for using exiv2 library (http://www.exiv2.org/) in ruby language
23
+
24
+ File: exiv2.cpp
25
+ Version: $Rev: 1 $
26
+ Author(s): Max Lapshin <max@maxidoors.ru>
27
+ */
28
+ // *****************************************************************************
29
+ #include "exiv2.hpp"
30
+
31
+
32
+ VALUE mExiv2, cImage, cExif, cIptc, cThumbnail;
33
+
34
+ #ifdef __cplusplus
35
+ extern "C"
36
+ #endif
37
+
38
+
39
+ void Init_exiv2() {
40
+ mExiv2 = rb_define_module("Exiv2");
41
+
42
+ cImage = rb_define_class_under(mExiv2, "Image", rb_cObject);
43
+ rb_define_alloc_func(cImage, exiv2_image_s_allocate);
44
+ rb_define_method(cImage, "initialize", VALUEFUNC(exiv2_image_initialize), 1);
45
+ rb_define_method(cImage, "exif", VALUEFUNC(exiv2_image_exif), 0);
46
+ /*
47
+ rb_define_method(cImage, "thumbnail", VALUEFUNC(exiv2_image_thumbnail), 0);
48
+ rb_define_method(cImage, "thumbnail=", VALUEFUNC(exiv2_image_thumbnail_set), 0);
49
+ */
50
+ rb_define_method(cImage, "save", VALUEFUNC(exiv2_image_save), 0);
51
+ rb_define_method(cImage, "clear", VALUEFUNC(exiv2_image_clear), 0);
52
+ rb_define_method(cImage, "comment", VALUEFUNC(exiv2_image_get_comment), 0);
53
+ rb_define_method(cImage, "comment=", VALUEFUNC(exiv2_image_set_comment), 1);
54
+
55
+ cExif = rb_define_class_under(mExiv2, "Exif", rb_cObject);
56
+ rb_define_method(cExif, "each", VALUEFUNC(exiv2_exif_each), -1);
57
+ rb_define_method(cExif, "[]", VALUEFUNC(exiv2_exif_get), 1);
58
+ rb_define_method(cExif, "[]=", VALUEFUNC(exiv2_exif_set), 2);
59
+ rb_define_method(cExif, "delete", VALUEFUNC(exiv2_exif_delete), 1);
60
+ rb_define_method(cExif, "clear", VALUEFUNC(exiv2_exif_clear), 0);
61
+ rb_define_method(cExif, "size", VALUEFUNC(exiv2_exif_size), 0);
62
+ rb_define_method(cExif, "empty?", VALUEFUNC(exiv2_exif_empty), 0);
63
+
64
+ /*
65
+ cThumbnail = rb_define_class_under(mExiv2, "Thumbnail", rb_cObject);
66
+ rb_define_method(cThumbnail, "extension", VALUEFUNC(exiv2_thumb_ext), 0);
67
+ rb_define_method(cThumbnail, "format", VALUEFUNC(exiv2_thumb_format), 0);
68
+ rb_define_method(cThumbnail, "clear", VALUEFUNC(exiv2_thumb_clear), 0);
69
+ rb_define_method(cThumbnail, "to_s", VALUEFUNC(exiv2_thumb_read), 0);
70
+ rb_define_method(cThumbnail, "read", VALUEFUNC(exiv2_thumb_read), 0);
71
+ rb_define_method(cThumbnail, "write", VALUEFUNC(exiv2_thumb_write), 1);
72
+ */
73
+ }
data/lib/exiv2.hpp ADDED
@@ -0,0 +1,118 @@
1
+ // ***************************************************************** -*- C++ -*-
2
+ /*
3
+ * Copyright (C) 2006 Max Lapshin <max@maxidoors.ru>
4
+ *
5
+ * This program is part of the ruby-exiv2 distribution.
6
+ *
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License
9
+ * as published by the Free Software Foundation; either version 2
10
+ * of the License, or (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+ /*
22
+ Abstract: Driver for using exiv2 library (http://www.exiv2.org/) in ruby language
23
+
24
+ File: exiv2.hpp
25
+ Version: $Rev: 1 $
26
+ Author(s): Max Lapshin <max@maxidoors.ru>
27
+ */
28
+
29
+ #ifndef EXIV2_HPP_
30
+ #define EXIV2_HPP_
31
+
32
+ // *****************************************************************************
33
+ // included header files
34
+ #include <image.hpp>
35
+ #include <exif.hpp>
36
+
37
+
38
+ #include <string>
39
+ #include <vector>
40
+ #include <iostream>
41
+ #include <fstream>
42
+ #include <iomanip>
43
+ #include <cstring>
44
+ #include <cassert>
45
+
46
+
47
+
48
+ #include "ruby.h"
49
+ #include "rubyio.h"
50
+ #ifdef __cplusplus
51
+ # ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
52
+ # define PROTECTFUNC(f) ((VALUE (*)()) f)
53
+ # define VALUEFUNC(f) ((VALUE (*)()) f)
54
+ # define VOIDFUNC(f) ((void (*)()) f)
55
+ # else
56
+ # ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
57
+ # define PROTECTFUNC(f) ((VALUE (*)()) f)
58
+ # define VALUEFUNC(f) ((VALUE (*)()) f)
59
+ # define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
60
+ # else /* These definitions should work for Ruby 1.7+ */
61
+ # define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
62
+ # define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
63
+ # define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
64
+ # endif
65
+ # endif
66
+ #else
67
+ # define VALUEFUNC(f) (f)
68
+ # define VOIDFUNC(f) (f)
69
+ #endif
70
+
71
+ #define STR(x) (RSTRING(x)->ptr)
72
+ #define SAFESTR(x) (x == Qnil ? NULL : RSTRING(x)->ptr)
73
+ #define CSTR(x) (const char *)(STR(x))
74
+ #define CBSTR(x) (const uint8_t *)(STR(x))
75
+ #define CSAFESTR(x) (const char *)(SAFESTR(x))
76
+ #define LEN(x) (RSTRING(x)->len)
77
+ #define RUN(x) if(!x) { return Qnil; }
78
+
79
+ #define __BEGIN try {
80
+ #define __END } catch(Exiv2::AnyError& e) { rb_raise(rb_eStandardError, "Error occured in exiv2 library: %s", e.what().c_str());}
81
+ #define __NIL_END } catch(Exiv2::AnyError& e) { return Qnil; }
82
+ #define __VOID_END } catch(Exiv2::AnyError& e) {}
83
+
84
+ #if defined(__cplusplus)
85
+ extern "C" {
86
+ #endif
87
+ void Init_exiv2(void);
88
+ extern VALUE mExiv2, cImage, cExif, cIptc;
89
+
90
+ #if defined(__cplusplus)
91
+ } /* extern "C" { */
92
+ #endif
93
+
94
+
95
+ struct rbImage {
96
+ bool dirty;
97
+ Exiv2::Image::AutoPtr image;
98
+ };
99
+
100
+
101
+ VALUE exiv2_image_s_allocate(VALUE klass);
102
+ VALUE exiv2_image_initialize(VALUE self, VALUE file);
103
+ VALUE exiv2_image_save(VALUE self);
104
+ VALUE exiv2_image_clear(VALUE self);
105
+ VALUE exiv2_image_exif(VALUE self);
106
+ VALUE exiv2_image_get_comment(VALUE self);
107
+ VALUE exiv2_image_set_comment(VALUE self, VALUE comment);
108
+
109
+ VALUE exiv2_exif_get(VALUE self, VALUE key);
110
+ VALUE exiv2_exif_set(VALUE self, VALUE key, VALUE value);
111
+ VALUE exiv2_exif_each(int argc, VALUE *argv, VALUE self);
112
+ VALUE exiv2_exif_delete(VALUE self, VALUE key);
113
+ VALUE exiv2_exif_size(VALUE self);
114
+ VALUE exiv2_exif_empty(VALUE self);
115
+ VALUE exiv2_exif_clear(VALUE self);
116
+
117
+
118
+ #endif /* EXIV2_HPP_ */
data/lib/extconf.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "mkmf"
4
+ CONFIG["CPP"] = "g++ -g -undefined suppress -flat_namespace "
5
+ CONFIG['LDSHARED'] = "g++ -g -dynamic -bundle -undefined suppress -flat_namespace"
6
+
7
+
8
+
9
+ $CPPFLAGS << " -Wall -I/usr/local/include/exiv2 "
10
+ $LDFLAGS << " -lstdc++ -L/usr/local/lib "
11
+ have_header "exif.hpp"
12
+ have_library "exiv2", "_ZN5Exiv29MetadatumD0Ev"
13
+ create_makefile 'exiv2'
14
+
data/lib/image.cpp ADDED
@@ -0,0 +1,118 @@
1
+ #include "exiv2.hpp"
2
+
3
+ static void image_real_save(rbImage* image);
4
+
5
+ static void image_delete(rbImage* image) {
6
+ __BEGIN
7
+ image_real_save(image);
8
+ delete image;
9
+ __VOID_END
10
+ }
11
+
12
+ static void image_leave(rbImage* image) {
13
+
14
+ }
15
+
16
+ VALUE exiv2_image_s_allocate(VALUE klass) {
17
+ __BEGIN
18
+ rbImage* image = new rbImage();
19
+ image->dirty = false;
20
+ return Data_Wrap_Struct(klass, 0, image_delete, image);
21
+ __END
22
+ }
23
+
24
+ VALUE exiv2_image_initialize(VALUE self, VALUE file) {
25
+ __BEGIN
26
+ rbImage* image;
27
+ Data_Get_Struct(self, rbImage, image);
28
+
29
+
30
+ try {
31
+ if(rb_respond_to(file, rb_intern("read"))) {
32
+ VALUE file_content = rb_funcall(file, rb_intern("read"), 0);
33
+ rb_iv_set(self, "file_content", file_content);
34
+ image->image = Exiv2::ImageFactory::open(CBSTR(file_content), LEN(file_content));
35
+ } else if(TYPE(file) == T_STRING) {
36
+ image->image = Exiv2::ImageFactory::open(CSTR(file));
37
+ }
38
+ image->image->readMetadata();
39
+ }
40
+ catch(const Exiv2::AnyError&) {
41
+ rb_raise(rb_eStandardError, "Cannot open file %s", STR(file));
42
+ }
43
+ return self;
44
+ __END
45
+ }
46
+
47
+
48
+ static void image_real_save(rbImage* image) {
49
+ if(image->dirty) {
50
+ image->image->writeMetadata();
51
+ image->dirty = false;
52
+ }
53
+ }
54
+
55
+ VALUE exiv2_image_save(VALUE self) {
56
+ __BEGIN
57
+ rbImage* image;
58
+ Data_Get_Struct(self, rbImage, image);
59
+ image_real_save(image);
60
+ return self;
61
+ __END
62
+ }
63
+
64
+
65
+ VALUE exiv2_image_clear(VALUE self) {
66
+ __BEGIN
67
+ rbImage* image;
68
+ Data_Get_Struct(self, rbImage, image);
69
+ image->image->clearMetadata();
70
+ image->dirty = true;
71
+ return self;
72
+ __END
73
+ }
74
+
75
+
76
+ VALUE exiv2_image_get_comment(VALUE self) {
77
+ __BEGIN
78
+ rbImage* image;
79
+ Data_Get_Struct(self, rbImage, image);
80
+ std::string comment = image->image->comment();
81
+ return rb_str_new(comment.c_str(), comment.length());
82
+ __END
83
+ }
84
+
85
+ VALUE exiv2_image_set_comment(VALUE self, VALUE comment) {
86
+ __BEGIN
87
+ rbImage* image;
88
+ Data_Get_Struct(self, rbImage, image);
89
+ switch(TYPE(comment)) {
90
+ case T_STRING: {
91
+ image->image->setComment(CSTR(comment));
92
+ image->dirty = true;
93
+ break;
94
+ }
95
+ case T_NIL: {
96
+ image->image->clearComment();
97
+ image->dirty = true;
98
+ break;
99
+ }
100
+ default: {
101
+ rb_raise(rb_eStandardError, "Can only set comment to string, or clear it with nil value");
102
+ }
103
+ }
104
+ return comment;
105
+ __END
106
+ }
107
+
108
+
109
+ VALUE exiv2_image_exif(VALUE self) {
110
+ __BEGIN
111
+ rbImage* image;
112
+ Data_Get_Struct(self, rbImage, image);
113
+ VALUE exif = Data_Wrap_Struct(cExif, 0, image_leave, image);
114
+ rb_iv_set(self, "image", self);
115
+ return exif;
116
+ __END
117
+ }
118
+
data/test/image.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/exiv2'
3
+ require 'tempfile'
4
+
5
+ class ImageTest < Test::Unit::TestCase
6
+
7
+ def test_file(filename)
8
+ test_file_name = File.dirname(__FILE__) + "/data/file_test"
9
+ open(test_file_name, "w+") do |f|
10
+ open(File.dirname(__FILE__) + "/data/#{filename}") do |real|
11
+ f << real.read
12
+ end
13
+ end
14
+ begin
15
+ yield test_file_name
16
+ rescue
17
+ end
18
+ File.unlink(test_file_name)
19
+ end
20
+
21
+ def test_open
22
+ test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
23
+ assert @img = Exiv2::Image.new(f)
24
+ assert_equal "FinePixS2Pro", @img.exif["Exif.Image.Model"]
25
+ assert_equal nil, @img.exif["zeze"]
26
+ assert_equal "3024", @img.exif["Exif.Photo.PixelXDimension"]
27
+ end
28
+ end
29
+
30
+ def test_write
31
+ test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
32
+ assert @img = Exiv2::Image.new(f)
33
+ assert_equal "*istDs", @img.exif["Exif.Image.Model"] = "*istDs"
34
+ assert @img.save
35
+
36
+ assert @img = Exiv2::Image.new(f)
37
+ assert_equal "*istDs", @img.exif["Exif.Image.Model"]
38
+ end
39
+ end
40
+
41
+ def test_comment
42
+ test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
43
+ assert @img = Exiv2::Image.new(f)
44
+ assert_equal "My funny comment", @img.comment = "My funny comment"
45
+ assert @img.save
46
+
47
+ assert @img = Exiv2::Image.new(f)
48
+ assert_equal "My funny comment", @img.comment
49
+ end
50
+ end
51
+
52
+ def test_each
53
+ test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
54
+ assert @img = Exiv2::Image.new(f)
55
+ i = 0
56
+ @img.exif.each do |key, value|
57
+ i = i + 1
58
+ assert key
59
+ assert value
60
+ end
61
+ assert_equal 74, i
62
+
63
+ i = 0
64
+ @img.exif.each "Exif.Fujifilm" do |key, value|
65
+ i = i + 1
66
+ assert key
67
+ assert value
68
+ end
69
+ assert_equal 16, i
70
+ end
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: ruby-exiv2
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2006-09-20 00:00:00 +04:00
8
+ summary: Exiv2 library ruby driver
9
+ require_paths:
10
+ - lib
11
+ email: max@maxidoors.ru
12
+ homepage: http://rubyforge.org/project/ruby-exiv2/
13
+ rubyforge_project: ruby-exiv2
14
+ description:
15
+ autorequire: intersys
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - Max Lapshin
30
+ files:
31
+ - test/data
32
+ - test/image.rb
33
+ - test/data/exiv2-fujifilm-finepix-s2pro.jpg
34
+ - lib/exif.cpp
35
+ - lib/exiv2.cpp
36
+ - lib/exiv2.hpp
37
+ - lib/extconf.rb
38
+ - lib/image.cpp
39
+ - README
40
+ test_files: []
41
+
42
+ rdoc_options:
43
+ - --main=README
44
+ - --line-numbers
45
+ - --webcvs=svn+ssh://max_lapshin@rubyforge.org/var/svn/ruby-exiv2
46
+ - --charset=utf-8
47
+ - --promiscuous
48
+ extra_rdoc_files:
49
+ - README
50
+ executables: []
51
+
52
+ extensions:
53
+ - lib/extconf.rb
54
+ requirements: []
55
+
56
+ dependencies: []
57
+