ruby-exiv2 1.3 → 1.5

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.
@@ -1,230 +0,0 @@
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
- /*
17
- * Document-class: Exiv2::Image
18
- * Image is used to access to all exif data of image
19
- *
20
- * @image = Exiv2::Image.new("my.jpg")
21
- * puts @image["Iptc.Application2.DateCreated"]
22
- * puts @image["Exif.Image.Software"]
23
- */
24
- static VALUE exiv2_image_s_allocate(VALUE klass) {
25
- __BEGIN
26
- rbImage* image = new rbImage();
27
- image->dirty = false;
28
- return Data_Wrap_Struct(klass, 0, image_delete, image);
29
- __END
30
- }
31
-
32
- /*
33
- * img = Exiv2::Image.new("IMGP3025.jpg")
34
- */
35
- static VALUE exiv2_image_initialize(VALUE self, VALUE file) {
36
- __BEGIN
37
- rbImage* image;
38
- Data_Get_Struct(self, rbImage, image);
39
-
40
-
41
- try {
42
- if(rb_respond_to(file, rb_intern("read"))) {
43
- VALUE file_content = rb_funcall(file, rb_intern("read"), 0);
44
- rb_iv_set(self, "@file_content", file_content);
45
- image->image = Exiv2::ImageFactory::open(CBSTR(file_content), LEN(file_content));
46
- } else if(TYPE(file) == T_STRING) {
47
- image->image = Exiv2::ImageFactory::open(CSTR(file));
48
- }
49
- image->image->readMetadata();
50
- }
51
- catch(const Exiv2::AnyError&) {
52
- rb_raise(rb_eStandardError, "Cannot open file %s", STR(file));
53
- }
54
- return self;
55
- __END
56
- }
57
-
58
- /*
59
- *
60
- * Load Exiv2::Image from memory string
61
- *
62
- * content = File.open("a.jpg").read
63
- * img = Exiv2::Image.load_string(content)
64
- */
65
- static VALUE exiv2_image_load_string(VALUE self, VALUE string) {
66
- __BEGIN
67
- Check_Type(string, T_STRING);
68
- rbImage* image = new rbImage();
69
- image->dirty = false;
70
- VALUE img = Data_Wrap_Struct(self, 0, image_delete, image);
71
-
72
- image->image = Exiv2::ImageFactory::open(CBSTR(string), LEN(string));
73
- return img;
74
- __END
75
- }
76
-
77
-
78
- static void image_real_save(rbImage* image) {
79
- if(image->dirty) {
80
- image->image->writeMetadata();
81
- image->dirty = false;
82
- }
83
- }
84
-
85
- /*
86
- * Save image with changed data
87
- */
88
- static VALUE exiv2_image_save(VALUE self) {
89
- __BEGIN
90
- rbImage* image;
91
- Data_Get_Struct(self, rbImage, image);
92
- image_real_save(image);
93
- return self;
94
- __END
95
- }
96
-
97
- /*
98
- * Clear all metadata in image. Not only exif
99
- */
100
- static VALUE exiv2_image_clear(VALUE self) {
101
- __BEGIN
102
- rbImage* image;
103
- Data_Get_Struct(self, rbImage, image);
104
- image->image->clearMetadata();
105
- image->dirty = true;
106
- return self;
107
- __END
108
- }
109
-
110
- /*
111
- * Get comment of image
112
- */
113
- static VALUE exiv2_image_get_comment(VALUE self) {
114
- __BEGIN
115
- rbImage* image;
116
- Data_Get_Struct(self, rbImage, image);
117
- std::string comment = image->image->comment();
118
- return rb_str_new(comment.c_str(), comment.length());
119
- __END
120
- }
121
-
122
- /*
123
- * Set comment in image
124
- */
125
- static VALUE exiv2_image_set_comment(VALUE self, VALUE comment) {
126
- __BEGIN
127
- rbImage* image;
128
- Data_Get_Struct(self, rbImage, image);
129
- switch(TYPE(comment)) {
130
- case T_STRING: {
131
- image->image->setComment(CSTR(comment));
132
- image->dirty = true;
133
- break;
134
- }
135
- case T_NIL: {
136
- image->image->clearComment();
137
- image->dirty = true;
138
- break;
139
- }
140
- default: {
141
- rb_raise(rb_eStandardError, "Can only set comment to string, or clear it with nil value");
142
- }
143
- }
144
- return comment;
145
- __END
146
- }
147
-
148
- /*
149
- * Access to exif data of image
150
- */
151
- static VALUE exiv2_image_exif(VALUE self) {
152
- __BEGIN
153
- rbImage* image;
154
- Data_Get_Struct(self, rbImage, image);
155
- VALUE exif = Data_Wrap_Struct(cExif, 0, image_leave, image);
156
- rb_iv_set(exif, "@image", self);
157
- return exif;
158
- __END
159
- }
160
-
161
- /*
162
- * Access to iptc data of image
163
- */
164
- static VALUE exiv2_image_iptc(VALUE self) {
165
- __BEGIN
166
- rbImage* image;
167
- Data_Get_Struct(self, rbImage, image);
168
- VALUE iptc = Data_Wrap_Struct(cIptc, 0, image_leave, image);
169
- rb_iv_set(iptc, "@image", self);
170
- return iptc;
171
- __END
172
- }
173
-
174
-
175
- /*
176
- * Dump thumbnail to file.
177
- * @img.thumbnail("my_image")
178
- */
179
- static VALUE exiv2_image_thumbnail(VALUE self, VALUE file_name) {
180
- __BEGIN
181
- Check_Type(file_name, T_STRING);
182
-
183
- rbImage* image;
184
- Data_Get_Struct(self, rbImage, image);
185
-
186
- Exiv2::ExifData &exifData = image->image->exifData();
187
- exifData.writeThumbnail(STR(file_name));
188
- if(rb_block_given_p()) {
189
- rb_yield(file_name);
190
- }
191
- return self;
192
- __END
193
- }
194
-
195
- /*
196
- * Set image thumbnail to contents of passed file
197
- * @img.thumbnail = "my_image.jpg"
198
- */
199
- static VALUE exiv2_image_thumbnail_set(VALUE self, VALUE file_name) {
200
- __BEGIN
201
- Check_Type(file_name, T_STRING);
202
-
203
- rbImage* image;
204
- Data_Get_Struct(self, rbImage, image);
205
-
206
- Exiv2::ExifData &exifData = image->image->exifData();
207
- exifData.setJpegThumbnail(STR(file_name));
208
- return self;
209
- __END
210
- }
211
-
212
-
213
- void Init_image() {
214
- cImage = rb_define_class_under(mExiv2, "Image", rb_cObject);
215
- rb_define_alloc_func(cImage, exiv2_image_s_allocate);
216
- rb_define_method(cImage, "initialize", VALUEFUNC(exiv2_image_initialize), 1);
217
- rb_define_singleton_method(cImage, "load_string", VALUEFUNC(exiv2_image_load_string), 1);
218
-
219
- rb_define_method(cImage, "exif", VALUEFUNC(exiv2_image_exif), 0);
220
- rb_define_method(cImage, "Exif", VALUEFUNC(exiv2_image_exif), 0);
221
- rb_define_method(cImage, "iptc", VALUEFUNC(exiv2_image_iptc), 0);
222
-
223
- rb_define_method(cImage, "thumbnail", VALUEFUNC(exiv2_image_thumbnail), 1);
224
- rb_define_method(cImage, "thumbnail=", VALUEFUNC(exiv2_image_thumbnail_set), 1);
225
-
226
- rb_define_method(cImage, "save", VALUEFUNC(exiv2_image_save), 0);
227
- rb_define_method(cImage, "clear", VALUEFUNC(exiv2_image_clear), 0);
228
- rb_define_method(cImage, "comment", VALUEFUNC(exiv2_image_get_comment), 0);
229
- rb_define_method(cImage, "comment=", VALUEFUNC(exiv2_image_set_comment), 1);
230
- }
@@ -1,253 +0,0 @@
1
- #include "exiv2.hpp"
2
-
3
- /*
4
- * First, I have to get out type by key. If such key is forbidden, I will refuse to marshall it.
5
- * Then, I will cast ruby VALUE to C++ value, according to type_id
6
- * then I will just set apropreciated hash entry to this casted value
7
- */
8
- static bool marshall_value(Exiv2::IptcData &data, const char* key, VALUE value) {
9
- Exiv2::TypeId type_id;
10
- try {
11
- Exiv2::IptcKey iptcKey(key);
12
- type_id = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
13
- }
14
- catch(Exiv2::Error& e) {
15
- rb_raise(eError, "Cannot set tag %s because it doesn't exists. Look at http://www.exiv2.org/tags.html for list of supported tags", key);
16
- }
17
- switch(type_id) {
18
- case Exiv2::invalidTypeId:
19
- {
20
- rb_warn("Trying to marshall invalid type id");
21
- return Qnil;
22
- }
23
-
24
- case Exiv2::unsignedByte:
25
- case Exiv2::unsignedShort:
26
- case Exiv2::unsignedLong:
27
- case Exiv2::signedShort:
28
- case Exiv2::signedLong:
29
- {
30
- data[key] = NUM2INT(value);
31
- return true;
32
- }
33
-
34
- case Exiv2::asciiString:
35
- case Exiv2::string:
36
- case Exiv2::undefined:
37
- {
38
- data[key] = std::string(STR(value));
39
- return true;
40
- }
41
-
42
- case Exiv2::unsignedRational:
43
- case Exiv2::signedRational:
44
- {
45
- if(rb_respond_to(value, rb_intern("numerator"))) {
46
- int numerator = NUM2INT(rb_funcall(value, rb_intern("numerator"), 0));
47
- int denominator = NUM2INT(rb_funcall(value, rb_intern("denominator"), 0));
48
- data[key] = numerator / denominator;
49
- return true;
50
- }
51
- data[key] = int(NUM2INT(value));
52
- return true;
53
- }
54
-
55
- case Exiv2::date:
56
- {
57
- int year = NUM2INT(rb_funcall(value, rb_intern("year"), 0));
58
- int month = NUM2INT(rb_funcall(value, rb_intern("month"), 0));
59
- int day = NUM2INT(rb_funcall(value, rb_intern("day"), 0));
60
- data[key] = Exiv2::DateValue(year, month, day);
61
- return true;
62
- }
63
- case Exiv2::time: {
64
- int hour = NUM2INT(rb_funcall(value, rb_intern("hour"), 0));
65
- int minute = NUM2INT(rb_funcall(value, rb_intern("min"), 0));
66
- int second = NUM2INT(rb_funcall(value, rb_intern("sec"), 0));
67
- data[key] = Exiv2::TimeValue(hour, minute, second);
68
- return true;
69
- }
70
-
71
- case Exiv2::invalid6:
72
- case Exiv2::comment:
73
- case Exiv2::directory:
74
- case Exiv2::lastTypeId:
75
- {
76
- data[key] = std::string(STR(value));
77
- return true;
78
- }
79
- }
80
- return false;
81
- }
82
-
83
-
84
- /*
85
- * Access iptc tag by name
86
- *
87
- * <code>Exiv2::Image.new("test/data/smiley.jpg").iptc["Iptc.Application2.ObjectName"] => "GreeenDude"</code>
88
- */
89
- static VALUE exiv2_iptc_get(VALUE self, VALUE key) {
90
- __BEGIN
91
- rbImage* image;
92
- Data_Get_Struct(self, rbImage, image);
93
-
94
- VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
95
- Exiv2::IptcData &iptcData = image->image->iptcData();
96
-
97
- if(iptcData.empty()) {
98
- return Qnil;
99
- }
100
-
101
- Exiv2::IptcKey iptcKey(STR(strkey));
102
- Exiv2::IptcData::const_iterator pos = iptcData.findKey(iptcKey);
103
- if (pos == iptcData.end()) {
104
- return Qnil;
105
- }
106
-
107
- return unmarshall_value(pos->value());
108
- __NIL_END
109
- }
110
-
111
- #if 1
112
- /*
113
- * @iptc["Iptc.Application2.ObjectName"] = "GreeenDude"
114
- * [] — is a universal accessor
115
- */
116
- static VALUE exiv2_iptc_set(VALUE self, VALUE key, VALUE value) {
117
- __BEGIN
118
- rbImage* image;
119
- Data_Get_Struct(self, rbImage, image);
120
-
121
- VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
122
-
123
- if(!marshall_value(image->image->iptcData(), STR(strkey), value)) {
124
- THROW("Couldn't write %s", STR(strkey));
125
- }
126
-
127
- image->dirty = true;
128
- return value;
129
- __NIL_END
130
-
131
- }
132
- #endif
133
-
134
- /*
135
- * Iterates through all iptc tags in image
136
- */
137
- static VALUE exiv2_iptc_each(int argc, VALUE *argv, VALUE self) {
138
- __BEGIN
139
- rbImage* image;
140
- Data_Get_Struct(self, rbImage, image);
141
-
142
- VALUE prefix;
143
- rb_scan_args(argc, argv, "01", &prefix);
144
-
145
- Exiv2::IptcData &iptcData = image->image->iptcData();
146
- if(iptcData.empty()) {
147
- return Qnil;
148
- }
149
-
150
- Exiv2::IptcData::const_iterator end = iptcData.end();
151
- for(Exiv2::IptcData::const_iterator i = iptcData.begin(); i != end; ++i) {
152
- VALUE key = rb_str_new(i->key().c_str(), i->key().length());
153
- VALUE val = unmarshall_value(i->value());
154
- if(prefix != Qnil && INT2FIX(0) != rb_funcall(key, rb_intern("index"), 1, prefix)) {
155
- continue;
156
- }
157
- rb_yield(rb_ary_new3(2, key, val));
158
- }
159
- return self;
160
- __END
161
- }
162
-
163
- #if 1
164
- /*
165
- * Delete iptc value by it's name
166
- */
167
- static VALUE exiv2_iptc_delete(VALUE self, VALUE key) {
168
- __BEGIN
169
- rbImage* image;
170
- Data_Get_Struct(self, rbImage, image);
171
-
172
- VALUE strkey = rb_funcall(key, rb_intern("to_s"), 0);
173
- Exiv2::IptcData &iptcData = image->image->iptcData();
174
-
175
- if(iptcData.empty()) {
176
- return Qnil;
177
- }
178
-
179
- Exiv2::IptcKey iptcKey(STR(strkey));
180
- Exiv2::IptcData::iterator pos = iptcData.findKey(iptcKey);
181
- if (pos == iptcData.end()) {
182
- return Qnil;
183
- }
184
-
185
- std::string v = pos->toString();
186
- iptcData.erase(pos);
187
- return rb_str_new(v.c_str(), v.length());
188
- __NIL_END
189
- }
190
- #endif
191
-
192
- /*
193
- * Clear all iptc data in image
194
- */
195
- static VALUE exiv2_iptc_clear(VALUE self) {
196
- __BEGIN
197
- rbImage* image;
198
- Data_Get_Struct(self, rbImage, image);
199
-
200
- Exiv2::IptcData &iptcData = image->image->iptcData();
201
-
202
- if(iptcData.empty()) {
203
- return Qnil;
204
- }
205
- iptcData.clear();
206
- return self;
207
- __END
208
- }
209
-
210
- /*
211
- * Count of iptc tags in image
212
- */
213
- static VALUE exiv2_iptc_count(VALUE self) {
214
- __BEGIN
215
- rbImage* image;
216
- Data_Get_Struct(self, rbImage, image);
217
-
218
- Exiv2::IptcData &iptcData = image->image->iptcData();
219
-
220
- return INT2FIX(iptcData.count());
221
- __END
222
- }
223
-
224
- /*
225
- * Predicate method. Is iptc empty?
226
- */
227
- static VALUE exiv2_iptc_empty(VALUE self) {
228
- __BEGIN
229
- rbImage* image;
230
- Data_Get_Struct(self, rbImage, image);
231
-
232
- Exiv2::IptcData &iptcData = image->image->iptcData();
233
-
234
- return iptcData.empty() ? Qtrue : Qfalse;
235
- __NIL_END
236
- }
237
-
238
-
239
-
240
-
241
-
242
- void Init_iptc() {
243
- cIptc = rb_define_class_under(mExiv2, "Iptc", rb_cObject);
244
- rb_define_method(cIptc, "each", VALUEFUNC(exiv2_iptc_each), -1);
245
- rb_define_method(cIptc, "[]", VALUEFUNC(exiv2_iptc_get), 1);
246
- #if 1
247
- rb_define_method(cIptc, "[]=", VALUEFUNC(exiv2_iptc_set), 2);
248
- rb_define_method(cIptc, "delete", VALUEFUNC(exiv2_iptc_delete), 1);
249
- #endif
250
- rb_define_method(cIptc, "clear", VALUEFUNC(exiv2_iptc_clear), 0);
251
- rb_define_method(cIptc, "count", VALUEFUNC(exiv2_iptc_count), 0);
252
- rb_define_method(cIptc, "empty?", VALUEFUNC(exiv2_iptc_empty), 0);
253
- }