ruby-exiv2 1.3 → 1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }