ruby-exiv2 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -0,0 +1,12 @@
1
+ Library for handling exif image tags.
2
+
3
+ Basic usage:
4
+
5
+ > gem install ruby-exiv2
6
+
7
+
8
+ require 'exiv2'
9
+ @img = Exiv2::Image.new("a.jpg")
10
+ @exif = @img.exif
11
+ puts @img.exif["Exif.Photo.PixelXDimension"]
12
+ => 3024
data/lib/Makefile CHANGED
@@ -40,7 +40,7 @@ CFLAGS = -fno-common -O -pipe -I/opt/local/include -fno-common -pipe -fno-co
40
40
  CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) -DHAVE_EXIF_HPP -O -pipe -I/opt/local/include -Wall -I/usr/local/include/exiv2 -I/usr/include/exiv2
41
41
  CXXFLAGS = $(CFLAGS)
42
42
  DLDFLAGS = -L/opt/local/lib -lstdc++
43
- LDSHARED = g++ -g -dynamic -bundle -undefined suppress -flat_namespace
43
+ LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
44
44
  AR = ar
45
45
  EXEEXT =
46
46
 
data/lib/exif.cpp CHANGED
@@ -9,7 +9,7 @@ static VALUE unmarshall_value(const Exiv2::Value& value) {
9
9
 
10
10
  Exiv2::TypeId type_id = value.typeId();
11
11
  switch(type_id) {
12
- case Exiv2::invalidTypeId:
12
+ case Exiv2::invalidTypeId:
13
13
  {
14
14
  rb_warn("Trying to demarshall invalid type id");
15
15
  return Qnil;
@@ -31,16 +31,17 @@ static VALUE unmarshall_value(const Exiv2::Value& value) {
31
31
  VALUE str = rb_str_buf_new(value.size() - 1);
32
32
  value.copy((Exiv2::byte *)STR(str), Exiv2::littleEndian);
33
33
  LEN(str) = value.size() - 1;
34
+ STR(str)[LEN(str)] = '\0';
35
+ LEN(str) = strlen(STR(str));
34
36
  return str;
35
37
  }
36
38
 
37
39
  case Exiv2::unsignedRational:
38
40
  case Exiv2::signedRational:
39
41
  {
40
- return rb_str_new2(value.toString().c_str());
41
42
  Exiv2::Rational r = value.toRational();
42
43
  ID rational_id = rb_intern("Rational");
43
- if(0 && rb_const_defined(rb_cObject, rational_id)) {
44
+ if(rb_const_defined(rb_cObject, rational_id)) {
44
45
  VALUE rational = rb_const_get(rb_cObject, rational_id);
45
46
  return rb_funcall(rational, rb_intern("new!"), 2, INT2NUM(r.first), INT2NUM(r.second));
46
47
  }
@@ -95,6 +96,67 @@ static VALUE exiv2_exif_get(VALUE self, VALUE key) {
95
96
  __NIL_END
96
97
  }
97
98
 
99
+ /*
100
+ * First, I have to get out type by key. If such key is forbidden, I will refuse to marshall it.
101
+ * Then, I will cast ruby VALUE to C++ value, according to type_id
102
+ * then I will just set apropreciated hash entry to this casted value
103
+ */
104
+ static bool marshall_value(Exiv2::ExifData &exifData, const char* key, VALUE value) {
105
+ Exiv2::ExifKey exif_key(key);
106
+ Exiv2::TypeId type_id = Exiv2::ExifTags::tagType(exif_key.tag(), exif_key.ifdId());
107
+ switch(type_id) {
108
+ case Exiv2::invalidTypeId:
109
+ {
110
+ rb_warn("Trying to marshall invalid type id");
111
+ return Qnil;
112
+ }
113
+
114
+ case Exiv2::unsignedByte:
115
+ case Exiv2::unsignedShort:
116
+ case Exiv2::unsignedLong:
117
+ case Exiv2::signedShort:
118
+ case Exiv2::signedLong:
119
+ {
120
+ exifData[key] = NUM2INT(value);
121
+ return true;
122
+ }
123
+
124
+ case Exiv2::asciiString:
125
+ case Exiv2::string:
126
+ case Exiv2::undefined:
127
+ {
128
+ exifData[key] = std::string(STR(value));
129
+ return true;
130
+ }
131
+
132
+ case Exiv2::unsignedRational:
133
+ case Exiv2::signedRational:
134
+ {
135
+ if(rb_respond_to(value, rb_intern("numerator"))) {
136
+ int numerator = NUM2INT(rb_funcall(value, rb_intern("numerator"), 0));
137
+ int denominator = NUM2INT(rb_funcall(value, rb_intern("denominator"), 0));
138
+ exifData[key] = Exiv2::Rational(numerator, denominator);
139
+ return true;
140
+ }
141
+ exifData[key] = Exiv2::Rational(NUM2INT(value), 1);
142
+ return true;
143
+ }
144
+
145
+ case Exiv2::invalid6:
146
+ case Exiv2::date:
147
+ case Exiv2::time:
148
+ case Exiv2::comment:
149
+ case Exiv2::directory:
150
+ case Exiv2::lastTypeId:
151
+ {
152
+ exifData[key] = std::string(STR(value));
153
+ return true;
154
+ }
155
+ }
156
+ return false;
157
+ }
158
+
159
+
98
160
  /*
99
161
  * @exif["Exif.Photo.PixelXDimension"] = 3024
100
162
  * [] — is a universal accessor
@@ -105,12 +167,19 @@ static VALUE exiv2_exif_set(VALUE self, VALUE key, VALUE value) {
105
167
  Data_Get_Struct(self, rbImage, image);
106
168
 
107
169
  VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
108
- VALUE strvalue = rb_funcall(value, rb_intern("to_s"), 0);
109
- Exiv2::ExifData &exifData = image->image->exifData();
170
+ bool marshalled = false;
171
+ {
172
+ Exiv2::ExifData &exifData = image->image->exifData();
173
+
174
+ marshalled = marshall_value(exifData, STR(strkey), value);
175
+ }
176
+
177
+ if(!marshalled) {
178
+ THROW("Couldn't write %s", STR(strkey));
179
+ }
110
180
 
111
- exifData[STR(strkey)] = STR(strvalue);
112
181
  image->dirty = true;
113
- return strvalue;
182
+ return value;
114
183
  __NIL_END
115
184
  }
116
185
 
data/lib/exiv2.cpp CHANGED
@@ -31,11 +31,26 @@
31
31
 
32
32
  VALUE mExiv2, cImage, cExif, cIptc, cThumbnail, eError;
33
33
 
34
+ void rb_exiv2_throw(const char *file, long unsigned int line, const char *fmt, ...) {
35
+ char* message;
36
+ va_list ap;
37
+ va_start(ap, fmt);
38
+ vasprintf(&message, fmt, ap);
39
+ va_end(ap);
40
+
41
+ char error_message[strlen(message) + 80];
42
+ snprintf(error_message, sizeof(error_message), "%s. File: %s, line: %lu", message, file, line);
43
+ free(message);
44
+ rb_raise(eError, error_message);
45
+ }
46
+
47
+
34
48
  #ifdef __cplusplus
35
49
  extern "C"
36
50
  #endif
37
51
 
38
52
 
53
+
39
54
  void Init_exiv2() {
40
55
  mExiv2 = rb_define_module("Exiv2");
41
56
 
data/lib/exiv2.hpp CHANGED
@@ -81,6 +81,9 @@
81
81
  #define __NIL_END } catch(Exiv2::AnyError& e) { return Qnil; }
82
82
  #define __VOID_END } catch(Exiv2::AnyError& e) {}
83
83
 
84
+ #define THROW(message, ...) rb_exiv2_throw(__FILE__, __LINE__, message, ##__VA_ARGS__)
85
+ void rb_exiv2_throw(const char* file, long unsigned int line, const char *fmt, ...);
86
+
84
87
  #if defined(__cplusplus)
85
88
  extern "C" {
86
89
  #endif
data/lib/extconf.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "mkmf"
4
- CONFIG["CPP"] = "g++ -g -undefined suppress -flat_namespace "
5
- CONFIG['LDSHARED'] = "g++ -g -dynamic -bundle -undefined suppress -flat_namespace"
4
+ #CONFIG["CXX"] = "g++ -g " + CONFIG['LDSHARED']
5
+ CONFIG["CPP"] = "g++ -E "
6
+ #CONFIG['LDSHARED'] = "g++ -g -dynamic -bundle -undefined suppress -flat_namespace"
6
7
 
7
8
 
8
9
 
data/test/image.rb CHANGED
@@ -14,71 +14,99 @@ class ImageTest < Test::Unit::TestCase
14
14
  end
15
15
  begin
16
16
  yield test_file_name
17
- rescue
17
+ rescue StandardError => e
18
+ File.unlink(test_file_name)
19
+ raise e
18
20
  end
19
21
  File.unlink(test_file_name)
20
22
  end
21
23
 
22
24
  def test_open
23
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
24
- assert @img = Exiv2::Image.new(f), "Image should be opened from IO::File"
25
- assert_equal "FinePixS2Pro", @img.exif["Exif.Image.Model"]
26
- assert_equal nil, @img.exif["zeze"]
27
- assert_equal "3024", @img.exif["Exif.Photo.PixelXDimension"]
25
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
26
+ open(filename) do |image_file|
27
+ assert @img = Exiv2::Image.new(image_file), "Image should be opened from IO::File"
28
+ assert_equal "FinePixS2Pro", @img.exif["Exif.Image.Model"]
29
+ assert_equal nil, @img.exif["zeze"]
30
+ assert_equal 3024, @img.exif["Exif.Photo.PixelXDimension"]
31
+ end
28
32
  end
29
33
 
30
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
31
- assert @img = Exiv2::Image.new(f.path), "Image should be opened from filename"
34
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
35
+ assert @img = Exiv2::Image.new(filename), "Image should be opened from filename"
32
36
  assert_equal "FinePixS2Pro", @img.exif["Exif.Image.Model"]
33
37
  assert_equal nil, @img.exif["zeze"]
34
- assert_equal "3024", @img.exif["Exif.Photo.PixelXDimension"]
38
+ assert_equal 3024, @img.exif["Exif.Photo.PixelXDimension"]
35
39
  end
36
40
  end
37
41
 
38
- def test_write
39
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
40
- assert @img = Exiv2::Image.new(f)
42
+ def test_write_string
43
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
44
+ assert @img = Exiv2::Image.new(filename)
41
45
  assert_equal "FinePixS2Pro", @img.exif["Exif.Image.Model"]
42
46
  assert_equal "*istDs", @img.exif["Exif.Image.Model"] = "*istDs"
43
47
  assert @img.save
44
48
 
45
- assert @img = Exiv2::Image.new(f)
49
+ assert @img = Exiv2::Image.new(filename)
46
50
  assert_equal "*istDs", @img.exif["Exif.Image.Model"]
47
51
  end
48
52
  end
49
53
 
54
+ def test_write_int
55
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
56
+ assert @img = Exiv2::Image.new(filename)
57
+ assert_equal 3024, @img.exif["Exif.Photo.PixelXDimension"]
58
+ assert_equal 25, @img.exif["Exif.Photo.PixelXDimension"] = 25
59
+ assert @img.save
60
+
61
+ assert @img = Exiv2::Image.new(filename)
62
+ assert_equal 25, @img.exif["Exif.Photo.PixelXDimension"]
63
+ end
64
+ end
65
+
66
+ def test_write_rational
67
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
68
+ assert @img = Exiv2::Image.new(filename)
69
+ assert_equal Rational.new!(72, 1), @img.exif["Exif.Image.XResolution"]
70
+ assert_equal Rational.new!(27, 11), @img.exif["Exif.Image.XResolution"] = Rational.new!(27, 11)
71
+ assert @img.save
72
+
73
+ assert @img = Exiv2::Image.new(filename)
74
+ assert_equal Rational.new!(27, 11), @img.exif["Exif.Image.XResolution"]
75
+ end
76
+ end
77
+
78
+
79
+
50
80
  def test_comment
51
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
52
- assert @img = Exiv2::Image.new(f)
81
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
82
+ assert @img = Exiv2::Image.new(filename)
53
83
  assert_equal "My funny comment", @img.comment = "My funny comment"
54
84
  assert @img.save
55
85
 
56
- assert @img = Exiv2::Image.new(f)
86
+ assert @img = Exiv2::Image.new(filename)
57
87
  assert_equal "My funny comment", @img.comment
58
88
  end
59
89
  end
60
90
 
61
91
  def test_typehinting
62
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
63
- assert @img = Exiv2::Image.new(f)
92
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
93
+ assert @img = Exiv2::Image.new(filename)
64
94
  assert @exif = @img.exif
65
95
  assert_equal 1, @exif["Exif.Image.Orientation"]
66
96
  assert_equal "Digital Camera FinePixS2Pro Ver1.00", @exif["Exif.Image.Software"]
97
+ assert_kind_of Numeric, @exif["Exif.Image.XResolution"]
67
98
  assert_equal 72, @exif["Exif.Image.XResolution"]
68
- assert_equal String, @exif["Exif.Image.XResolution"].class
69
- puts @exif["Exif.Image.XResolution"].class
70
99
 
71
100
  require 'rational'
72
101
 
73
- assert_equal 72, @exif["Exif.Image.XResolution"]
74
- assert_equal Numeric, @exif["Exif.Image.XResolution"].class
75
- puts @exif["Exif.Image.XResolution"].class
102
+ assert_kind_of Rational, @exif["Exif.Image.XResolution"]
103
+ assert_equal Rational.new!(72, 1), @exif["Exif.Image.XResolution"]
76
104
  end
77
105
  end
78
106
 
79
107
  def test_each
80
- open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |f|
81
- assert @img = Exiv2::Image.new(f)
108
+ open_test_file "exiv2-fujifilm-finepix-s2pro.jpg" do |filename|
109
+ assert @img = Exiv2::Image.new(filename)
82
110
  i = 0
83
111
  @img.exif.each do |key, value|
84
112
  i = i + 1
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: ruby-exiv2
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.2"
7
- date: 2006-10-30 00:00:00 +03:00
6
+ version: "0.3"
7
+ date: 2006-11-07 00:00:00 +03:00
8
8
  summary: Exiv2 (exif image tags handling) library driver
9
9
  require_paths:
10
10
  - lib