ruby-exiv2 0.2 → 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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