extexif 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +2 -0
- data/Manifest.txt +15 -0
- data/README.txt +52 -0
- data/Rakefile +21 -0
- data/ext/COPYING +504 -0
- data/ext/ChangeLog +18 -0
- data/ext/Makefile +149 -0
- data/ext/README +30 -0
- data/ext/exif.c +653 -0
- data/ext/exif.rd.en +146 -0
- data/ext/exif.rd.ja +154 -0
- data/ext/extconf.rb +15 -0
- data/lib/extexif.rb +135 -0
- data/test/test_extexif.rb +10 -0
- metadata +71 -0
data/ext/ChangeLog
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Thu May 22 21:30:00 2007 Rakuto Furutani <rakuto@gmail.com>
|
2
|
+
* exif.c : support to fetch Exif GPS data.
|
3
|
+
|
4
|
+
Wed Dec 11 20:21:22 2002 Ryuichi Tamura <r-tam@fsinet.or.jp>
|
5
|
+
|
6
|
+
* exif.c (rb_exif_get_tag) : now need not pass hexadecimal number
|
7
|
+
as string object. pass it as it is.
|
8
|
+
|
9
|
+
* exif.c (rb_exif_get_tag) : search only for tags available in
|
10
|
+
libexif to improve search performance.
|
11
|
+
|
12
|
+
* Version 0.1.2
|
13
|
+
|
14
|
+
Mon Nov 11 22:48:17 2002 Ryuichi Tamura <r-tam@fsinet.or.jp>
|
15
|
+
|
16
|
+
* exif.c (rb_exif_get_tag) : return nil if return value is empty.
|
17
|
+
|
18
|
+
* Version 0.1.1.
|
data/ext/Makefile
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /usr/lib/ruby/1.8/i486-linux
|
8
|
+
hdrdir = $(topdir)
|
9
|
+
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
+
prefix = $(DESTDIR)/usr
|
11
|
+
exec_prefix = $(DESTDIR)/usr
|
12
|
+
sitedir = $(DESTDIR)/usr/local/lib/site_ruby
|
13
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
14
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
15
|
+
dvidir = $(docdir)
|
16
|
+
datarootdir = $(prefix)/share
|
17
|
+
archdir = $(rubylibdir)/$(arch)
|
18
|
+
sbindir = $(exec_prefix)/sbin
|
19
|
+
psdir = $(docdir)
|
20
|
+
localedir = $(datarootdir)/locale
|
21
|
+
htmldir = $(docdir)
|
22
|
+
datadir = $(prefix)/share
|
23
|
+
includedir = $(prefix)/include
|
24
|
+
infodir = $(datarootdir)/info
|
25
|
+
sysconfdir = $(DESTDIR)/etc
|
26
|
+
mandir = $(datadir)/man
|
27
|
+
libdir = $(DESTDIR)/usr/lib
|
28
|
+
sharedstatedir = $(prefix)/com
|
29
|
+
oldincludedir = $(DESTDIR)/usr/include
|
30
|
+
pdfdir = $(docdir)
|
31
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
32
|
+
bindir = $(exec_prefix)/bin
|
33
|
+
localstatedir = $(DESTDIR)/var
|
34
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
35
|
+
libexecdir = $(exec_prefix)/libexec
|
36
|
+
|
37
|
+
CC = gcc
|
38
|
+
LIBRUBY = $(LIBRUBY_SO)
|
39
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
40
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
41
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
42
|
+
|
43
|
+
RUBY_EXTCONF_H =
|
44
|
+
CFLAGS = -fPIC -Wall -g -fno-strict-aliasing -O2 -fPIC
|
45
|
+
INCFLAGS = -I. -I. -I/usr/lib/ruby/1.8/i486-linux -I.
|
46
|
+
CPPFLAGS = -DHAVE_LIBEXIF_EXIF_IFD_H -DHAVE_LIBEXIF_EXIF_DATA_H -DHAVE_LIBEXIF_EXIF_UTILS_H -DHAVE_LIBEXIF_EXIF_TAG_H -I/usr/local/include
|
47
|
+
CXXFLAGS = $(CFLAGS)
|
48
|
+
DLDFLAGS = -rdynamic -Wl,-export-dynamic
|
49
|
+
LDSHARED = $(CC) -shared
|
50
|
+
AR = ar
|
51
|
+
EXEEXT =
|
52
|
+
|
53
|
+
RUBY_INSTALL_NAME = ruby1.8
|
54
|
+
RUBY_SO_NAME = ruby1.8
|
55
|
+
arch = i486-linux
|
56
|
+
sitearch = i486-linux
|
57
|
+
ruby_version = 1.8
|
58
|
+
ruby = /usr/bin/ruby1.8
|
59
|
+
RUBY = $(ruby)
|
60
|
+
RM = rm -f
|
61
|
+
MAKEDIRS = mkdir -p
|
62
|
+
INSTALL = /usr/bin/install -c
|
63
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
64
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
65
|
+
COPY = cp
|
66
|
+
|
67
|
+
#### End of system configuration section. ####
|
68
|
+
|
69
|
+
preload =
|
70
|
+
|
71
|
+
libpath = /usr/local/lib $(libdir)
|
72
|
+
LIBPATH = -L"/usr/local/lib" -L"$(libdir)"
|
73
|
+
DEFFILE =
|
74
|
+
|
75
|
+
CLEANFILES =
|
76
|
+
DISTCLEANFILES =
|
77
|
+
|
78
|
+
extout =
|
79
|
+
extout_prefix =
|
80
|
+
target_prefix =
|
81
|
+
LOCAL_LIBS =
|
82
|
+
LIBS = $(LIBRUBYARG_SHARED) -lexif -lpthread -ldl -lcrypt -lm -lc
|
83
|
+
SRCS = exif.c
|
84
|
+
OBJS = exif.o
|
85
|
+
TARGET = exif
|
86
|
+
DLLIB = $(TARGET).so
|
87
|
+
EXTSTATIC =
|
88
|
+
STATIC_LIB =
|
89
|
+
|
90
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
91
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
92
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
93
|
+
|
94
|
+
TARGET_SO = $(DLLIB)
|
95
|
+
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
|
96
|
+
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
|
97
|
+
|
98
|
+
all: $(DLLIB)
|
99
|
+
static: $(STATIC_LIB)
|
100
|
+
|
101
|
+
clean:
|
102
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
103
|
+
|
104
|
+
distclean: clean
|
105
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
106
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
107
|
+
|
108
|
+
realclean: distclean
|
109
|
+
install: install-so install-rb
|
110
|
+
|
111
|
+
install-so: $(RUBYARCHDIR)
|
112
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
113
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
114
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
115
|
+
install-rb: pre-install-rb install-rb-default
|
116
|
+
install-rb-default: pre-install-rb-default
|
117
|
+
pre-install-rb: Makefile
|
118
|
+
pre-install-rb-default: Makefile
|
119
|
+
$(RUBYARCHDIR):
|
120
|
+
$(MAKEDIRS) $@
|
121
|
+
|
122
|
+
site-install: site-install-so site-install-rb
|
123
|
+
site-install-so: install-so
|
124
|
+
site-install-rb: install-rb
|
125
|
+
|
126
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
127
|
+
|
128
|
+
.cc.o:
|
129
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
130
|
+
|
131
|
+
.cxx.o:
|
132
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
133
|
+
|
134
|
+
.cpp.o:
|
135
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
136
|
+
|
137
|
+
.C.o:
|
138
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
139
|
+
|
140
|
+
.c.o:
|
141
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
142
|
+
|
143
|
+
$(DLLIB): $(OBJS)
|
144
|
+
@-$(RM) $@
|
145
|
+
$(LDSHARED) $(DLDFLAGS) $(LIBPATH) -o $@ $(OBJS) $(LOCAL_LIBS) $(LIBS)
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
$(OBJS): ruby.h defines.h
|
data/ext/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= ruby-libexif - an interface to libexif library
|
2
|
+
|
3
|
+
libexif is a library for parsing, editing, and saving EXIF data.
|
4
|
+
You can retrieve useful information from EXIF tags contained in
|
5
|
+
images created by recording equipments(for example, digital camera).
|
6
|
+
For more information, please refer ((<URL:http://libexif.sourceforge.net/>))
|
7
|
+
|
8
|
+
== Requirements
|
9
|
+
|
10
|
+
* ruby-1.6 or heigher
|
11
|
+
* libexif-0.5.6 (or heigher)
|
12
|
+
|
13
|
+
== Install
|
14
|
+
|
15
|
+
$ ruby extconf.rb
|
16
|
+
$ su
|
17
|
+
# make site-install
|
18
|
+
|
19
|
+
== Author
|
20
|
+
|
21
|
+
Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
22
|
+
See 'COPYING' file for license information.
|
23
|
+
|
24
|
+
== Homepage
|
25
|
+
|
26
|
+
((<URL:http://tam.0xfa.com/ruby-libexif/>))
|
27
|
+
|
28
|
+
== Bugs
|
29
|
+
|
30
|
+
methods to edit the value of EXIF tag is not yet implemented.
|
data/ext/exif.c
ADDED
@@ -0,0 +1,653 @@
|
|
1
|
+
/******************************************************************************
|
2
|
+
vim:sts=4:ts=4:sw=4
|
3
|
+
|
4
|
+
exif.c - ruby interface to libexif library
|
5
|
+
|
6
|
+
Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
7
|
+
|
8
|
+
Deried & Copyrth (C) 2007 Rakuto Furutani <rfurutani@uievolution.com>
|
9
|
+
|
10
|
+
|
11
|
+
*******************************************************************************/
|
12
|
+
#include <ruby.h>
|
13
|
+
#include <libexif/exif-tag.h>
|
14
|
+
#include <libexif/exif-data.h>
|
15
|
+
#include <libexif/exif-utils.h>
|
16
|
+
|
17
|
+
#define Get_Exif(obj, exif) { \
|
18
|
+
Data_Get_Struct((obj), Exif, (exif)); \
|
19
|
+
if (!(exif)->ed) \
|
20
|
+
rb_raise(eExifError, "should set data first"); \
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
typedef struct _Exif Exif;
|
25
|
+
|
26
|
+
struct _Exif {
|
27
|
+
ExifData *ed;
|
28
|
+
int ifd;
|
29
|
+
};
|
30
|
+
|
31
|
+
#define IFD_RB_DEFAULT (EXIF_IFD_0 - 1)
|
32
|
+
|
33
|
+
static VALUE cExif, mExifByteOrder, mExifIfd;
|
34
|
+
static VALUE eExifError, eExifInvalidFormat;
|
35
|
+
static VALUE eExifInvalidIFD, eExifTagNotFound, eExifThumbnailNotFound;
|
36
|
+
|
37
|
+
static void
|
38
|
+
rb_exif_free(Exif *exif)
|
39
|
+
{
|
40
|
+
if (exif){
|
41
|
+
exif_data_free(exif->ed);
|
42
|
+
exif->ed = NULL;
|
43
|
+
free(exif);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
static VALUE
|
48
|
+
rb_exif_s_new(int argc, VALUE *argv, VALUE klass)
|
49
|
+
{
|
50
|
+
VALUE obj;
|
51
|
+
Exif *exif;
|
52
|
+
exif = ALLOC(Exif);
|
53
|
+
exif->ed = NULL;
|
54
|
+
exif->ifd = IFD_RB_DEFAULT;
|
55
|
+
obj = Data_Wrap_Struct(klass, 0, rb_exif_free, exif);
|
56
|
+
rb_obj_call_init(obj, argc, argv);
|
57
|
+
return obj;
|
58
|
+
}
|
59
|
+
|
60
|
+
static ExifData *
|
61
|
+
rb_exif_data_new_from_file(VALUE fpath)
|
62
|
+
{
|
63
|
+
ExifData *data;
|
64
|
+
Check_Type(fpath, T_STRING);
|
65
|
+
data = exif_data_new_from_file(RSTRING(fpath)->ptr);
|
66
|
+
if (!data){
|
67
|
+
FILE *f;
|
68
|
+
f = fopen(RSTRING(fpath)->ptr,"rb");
|
69
|
+
if (!f)
|
70
|
+
rb_raise(rb_eArgError, "unable to open file - '%s'",
|
71
|
+
RSTRING(fpath)->ptr);
|
72
|
+
fclose(f);
|
73
|
+
rb_raise(eExifInvalidFormat,
|
74
|
+
"'%s' does not contain EXIF data", RSTRING(fpath)->ptr);
|
75
|
+
}
|
76
|
+
return data;
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
static VALUE
|
81
|
+
rb_exif_initialize(int argc, VALUE *argv, VALUE obj)
|
82
|
+
{
|
83
|
+
VALUE fpath;
|
84
|
+
Exif *exif;
|
85
|
+
Data_Get_Struct(obj, Exif, exif);
|
86
|
+
if (rb_scan_args(argc, argv, "01", &fpath) == 1) {
|
87
|
+
exif->ed = rb_exif_data_new_from_file(fpath);
|
88
|
+
}
|
89
|
+
else {
|
90
|
+
exif->ed = exif_data_new();
|
91
|
+
}
|
92
|
+
return Qnil;
|
93
|
+
}
|
94
|
+
|
95
|
+
static void
|
96
|
+
rb_exif_data_new_from_data(ExifData *ed, VALUE str)
|
97
|
+
{
|
98
|
+
Check_Type(str, T_STRING);
|
99
|
+
if (ed){
|
100
|
+
exif_data_free(ed);
|
101
|
+
ed = NULL;
|
102
|
+
}
|
103
|
+
ed = exif_data_new_from_data((unsigned char *)RSTRING(str)->ptr, RSTRING(str)->len);
|
104
|
+
}
|
105
|
+
|
106
|
+
static VALUE
|
107
|
+
rb_exif_set_data(VALUE obj, VALUE str)
|
108
|
+
{
|
109
|
+
Exif *exif;
|
110
|
+
Data_Get_Struct(obj, Exif, exif);
|
111
|
+
rb_exif_data_new_from_data(exif->ed, str);
|
112
|
+
return obj;
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE
|
116
|
+
rb_exif_get_byte_order(VALUE obj)
|
117
|
+
{
|
118
|
+
Exif *exif;
|
119
|
+
Get_Exif(obj, exif);
|
120
|
+
return FIX2INT(exif_data_get_byte_order(exif->ed));
|
121
|
+
}
|
122
|
+
|
123
|
+
static VALUE
|
124
|
+
rb_exif_set_byte_order(VALUE obj, VALUE byteorder)
|
125
|
+
{
|
126
|
+
Exif *exif;
|
127
|
+
Get_Exif(obj, exif);
|
128
|
+
exif_data_set_byte_order(exif->ed, FIX2INT(byteorder));
|
129
|
+
return obj;
|
130
|
+
}
|
131
|
+
|
132
|
+
static void
|
133
|
+
rb_exif_yield_tag_value(ExifEntry *entry, void *data)
|
134
|
+
{
|
135
|
+
VALUE k, v;
|
136
|
+
char buf[7];
|
137
|
+
char value[1024];
|
138
|
+
unsigned char *ids = data;
|
139
|
+
memset(buf, 0, sizeof(buf));
|
140
|
+
sprintf(buf, "0x%04x", entry->tag);
|
141
|
+
k = *ids ? rb_str_new2(buf) : rb_str_new2(exif_tag_get_title(entry->tag));
|
142
|
+
v = rb_str_new2(exif_entry_get_value(entry, value, sizeof(value)));
|
143
|
+
rb_yield(rb_assoc_new(k, v));
|
144
|
+
}
|
145
|
+
|
146
|
+
|
147
|
+
static void
|
148
|
+
rb_exif_data_foreach_content_func(ExifContent *content, void *data)
|
149
|
+
{
|
150
|
+
exif_content_foreach_entry(content, rb_exif_yield_tag_value, data);
|
151
|
+
}
|
152
|
+
|
153
|
+
static VALUE
|
154
|
+
rb_exif_each(int argc, VALUE *argv, VALUE obj)
|
155
|
+
{
|
156
|
+
Exif *exif;
|
157
|
+
VALUE use_tag_id;
|
158
|
+
unsigned char ids = 0;
|
159
|
+
if (rb_scan_args(argc, argv, "01", &use_tag_id) == 1){
|
160
|
+
ids = FIX2UINT(use_tag_id);
|
161
|
+
}
|
162
|
+
Get_Exif(obj, exif);
|
163
|
+
exif_data_foreach_content(exif->ed, rb_exif_data_foreach_content_func, &ids);
|
164
|
+
return obj;
|
165
|
+
}
|
166
|
+
|
167
|
+
static ExifIfd exif_ifd_from_string (const char *);
|
168
|
+
|
169
|
+
static VALUE
|
170
|
+
rb_exif_set_ifd(VALUE obj, VALUE ifd)
|
171
|
+
{
|
172
|
+
Exif *exif;
|
173
|
+
int i;
|
174
|
+
Get_Exif(obj, exif);
|
175
|
+
switch(TYPE(ifd)){
|
176
|
+
case T_FIXNUM:
|
177
|
+
i = FIX2INT(ifd);
|
178
|
+
if (i < IFD_RB_DEFAULT || i > EXIF_IFD_INTEROPERABILITY){
|
179
|
+
rb_raise(rb_eRuntimeError, "wrong constant");
|
180
|
+
}
|
181
|
+
break;
|
182
|
+
case T_STRING:
|
183
|
+
i = exif_ifd_from_string(RSTRING(ifd)->ptr);
|
184
|
+
if (i == -1){
|
185
|
+
rb_raise(rb_eRuntimeError, "unknown IFD: '%s'", RSTRING(ifd)->ptr);
|
186
|
+
}
|
187
|
+
break;
|
188
|
+
default:
|
189
|
+
rb_raise(rb_eTypeError, "wrong type of an argument");
|
190
|
+
break;
|
191
|
+
}
|
192
|
+
exif->ifd = i;
|
193
|
+
return obj;
|
194
|
+
}
|
195
|
+
|
196
|
+
static VALUE
|
197
|
+
rb_exif_get_ifd(VALUE obj)
|
198
|
+
{
|
199
|
+
Exif *exif;
|
200
|
+
const char *name;
|
201
|
+
Get_Exif(obj, exif);
|
202
|
+
name = exif_ifd_get_name(exif->ifd);
|
203
|
+
if (!name)
|
204
|
+
return Qnil;
|
205
|
+
return rb_str_new2(name);
|
206
|
+
}
|
207
|
+
|
208
|
+
static ExifTag exif_tag_from_string (const char *);
|
209
|
+
static ExifTag exif_tag_from_tagid (ExifTag);
|
210
|
+
|
211
|
+
static VALUE
|
212
|
+
rb_exif_get_tag(VALUE obj, VALUE tagid)
|
213
|
+
{
|
214
|
+
Exif *exif;
|
215
|
+
ExifTag tag;
|
216
|
+
ExifEntry *e;
|
217
|
+
const char *found;
|
218
|
+
int i;
|
219
|
+
char value[1024];
|
220
|
+
|
221
|
+
Get_Exif(obj, exif);
|
222
|
+
switch (TYPE(tagid)) {
|
223
|
+
case T_STRING:
|
224
|
+
tag = exif_tag_from_string(RSTRING(tagid)->ptr);
|
225
|
+
if (!tag){
|
226
|
+
rb_raise(eExifError, "invalid tag: '%s'", RSTRING(tagid)->ptr);
|
227
|
+
}
|
228
|
+
break;
|
229
|
+
case T_FIXNUM:
|
230
|
+
tag = exif_tag_from_tagid(FIX2INT(tagid));
|
231
|
+
if (!tag){
|
232
|
+
rb_raise(eExifError, "invalid tag: 0x%04x", tagid);
|
233
|
+
}
|
234
|
+
break;
|
235
|
+
default:
|
236
|
+
rb_raise(rb_eTypeError, "wrong type of arguments");
|
237
|
+
break;
|
238
|
+
}
|
239
|
+
if (exif->ifd >= 0){
|
240
|
+
e = exif_content_get_entry(exif->ed->ifd[exif->ifd], tag);
|
241
|
+
if (!e){
|
242
|
+
rb_raise(eExifTagNotFound,
|
243
|
+
"IFD '%s' does not contain tag '%s'(0x%04x)",
|
244
|
+
exif_ifd_get_name(exif->ifd), exif_tag_get_title(tag), tag);
|
245
|
+
}
|
246
|
+
return rb_str_new2(exif_entry_get_value(e, value, sizeof(value)));
|
247
|
+
}
|
248
|
+
for (i = 0; i < EXIF_IFD_COUNT; i++){
|
249
|
+
e = exif_content_get_entry(exif->ed->ifd[i], tag);
|
250
|
+
if (e)
|
251
|
+
break;
|
252
|
+
}
|
253
|
+
found = exif_entry_get_value(e, value, sizeof(value));
|
254
|
+
return found ? rb_str_new2(found) : Qnil;
|
255
|
+
}
|
256
|
+
|
257
|
+
static void
|
258
|
+
rb_exif_set_tag_0(ExifData *ed, ExifEntry *e, VALUE val)
|
259
|
+
{
|
260
|
+
ExifByteOrder o;
|
261
|
+
o = exif_data_get_byte_order(ed);
|
262
|
+
/* exif_entry_dump(e, 1); */
|
263
|
+
|
264
|
+
}
|
265
|
+
|
266
|
+
static VALUE
|
267
|
+
rb_exif_set_tag(VALUE obj, VALUE tagid, VALUE val)
|
268
|
+
{
|
269
|
+
Exif *exif;
|
270
|
+
ExifTag tag;
|
271
|
+
ExifEntry *e;
|
272
|
+
|
273
|
+
rb_raise(rb_eNotImpError, "soryy, not yet implemented");
|
274
|
+
Check_Type(tagid, T_STRING);
|
275
|
+
Check_Type(val, T_STRING);
|
276
|
+
Get_Exif(obj, exif);
|
277
|
+
tag = exif_tag_from_string(RSTRING(tagid)->ptr);
|
278
|
+
if (!tag || !exif_tag_get_name(tag)){
|
279
|
+
rb_raise(eExifError, "invalid tag: '%s'", RSTRING(tagid)->ptr);
|
280
|
+
}
|
281
|
+
e = exif_content_get_entry(exif->ed->ifd[exif->ifd], tag);
|
282
|
+
if (!e){
|
283
|
+
e = exif_entry_new();
|
284
|
+
exif_content_add_entry(exif->ed->ifd[exif->ifd], e);
|
285
|
+
exif_entry_initialize(e, tag);
|
286
|
+
}
|
287
|
+
rb_exif_set_tag_0(exif->ed, e, val);
|
288
|
+
return obj;
|
289
|
+
}
|
290
|
+
static VALUE
|
291
|
+
rb_exif_list_tags_at_ifd(VALUE obj, VALUE ifd)
|
292
|
+
{
|
293
|
+
Exif *exif;
|
294
|
+
unsigned int tag;
|
295
|
+
int i;
|
296
|
+
const char *name;
|
297
|
+
char buf[7];
|
298
|
+
VALUE ret = rb_ary_new();
|
299
|
+
i = FIX2INT(ifd);
|
300
|
+
if (i < EXIF_IFD_0 || i > EXIF_IFD_INTEROPERABILITY){
|
301
|
+
rb_raise(rb_eRuntimeError, "wrong constant");
|
302
|
+
}
|
303
|
+
Get_Exif(obj, exif);
|
304
|
+
for (tag = 0; tag < 0xffff; tag++) {
|
305
|
+
name = exif_tag_get_title(tag);
|
306
|
+
if (!name)
|
307
|
+
continue;
|
308
|
+
if (exif_content_get_entry(exif->ed->ifd[i], tag)){
|
309
|
+
memset(buf, 0, sizeof(buf));
|
310
|
+
sprintf(buf, "0x%04x", tag);
|
311
|
+
rb_ary_push(ret, rb_assoc_new(rb_str_new2(name), rb_str_new2(buf)));
|
312
|
+
}
|
313
|
+
}
|
314
|
+
return ret;
|
315
|
+
}
|
316
|
+
|
317
|
+
static VALUE
|
318
|
+
rb_exif_s_get_tag_description(VALUE klass, VALUE tagid)
|
319
|
+
{
|
320
|
+
ExifTag tag;
|
321
|
+
VALUE cdr;
|
322
|
+
char buf[7];
|
323
|
+
switch (TYPE(tagid)){
|
324
|
+
case T_FIXNUM:
|
325
|
+
tag = FIX2INT(tagid);
|
326
|
+
if (!exif_tag_get_name(tag))
|
327
|
+
rb_raise(eExifError, "invalid tag id: 0x%04x(%d)",
|
328
|
+
FIX2INT(tagid), FIX2INT(tagid));
|
329
|
+
break;
|
330
|
+
case T_STRING:
|
331
|
+
tag = exif_tag_from_string(RSTRING(tagid)->ptr);
|
332
|
+
if (!tag || !exif_tag_get_name(tag)) {
|
333
|
+
rb_raise(eExifError, "invalid tag: '%s'", RSTRING(tagid)->ptr);
|
334
|
+
}
|
335
|
+
break;
|
336
|
+
default:
|
337
|
+
rb_raise(rb_eTypeError, "wrong type of an argument");
|
338
|
+
break;
|
339
|
+
}
|
340
|
+
memset(buf, 0, sizeof(buf));
|
341
|
+
sprintf(buf, "0x%04x", tag);
|
342
|
+
cdr = rb_ary_new();
|
343
|
+
rb_ary_push(cdr, rb_str_new2(exif_tag_get_name(tag)));
|
344
|
+
rb_ary_push(cdr, rb_str_new2(exif_tag_get_description(tag)));
|
345
|
+
rb_ary_push(cdr, rb_str_new2(buf));
|
346
|
+
return rb_assoc_new(rb_str_new2(exif_tag_get_title(tag)), cdr);
|
347
|
+
}
|
348
|
+
|
349
|
+
static VALUE
|
350
|
+
rb_exif_extract_thumbnail(VALUE obj, VALUE dest)
|
351
|
+
{
|
352
|
+
Exif *exif;
|
353
|
+
Get_Exif(obj, exif);
|
354
|
+
if (!exif->ed->data)
|
355
|
+
rb_raise(eExifThumbnailNotFound, "thumbnail not found");
|
356
|
+
rb_funcall(dest, rb_intern("<<"), 1, rb_str_new((char *)exif->ed->data, exif->ed->size));
|
357
|
+
return obj;
|
358
|
+
}
|
359
|
+
|
360
|
+
static VALUE
|
361
|
+
rb_exif_set_thumbnail(VALUE obj, VALUE src)
|
362
|
+
{
|
363
|
+
Exif *exif;
|
364
|
+
Get_Exif(obj, exif);
|
365
|
+
if (exif->ed->data){
|
366
|
+
free(exif->ed->data);
|
367
|
+
exif->ed->data = NULL;
|
368
|
+
exif->ed->size = 0;
|
369
|
+
}
|
370
|
+
Check_Type(src, T_STRING);
|
371
|
+
exif->ed->size = RSTRING(src)->len;
|
372
|
+
exif->ed->data = xmalloc(sizeof(char)*exif->ed->size);
|
373
|
+
MEMMOVE(exif->ed->data, RSTRING(src)->ptr, char, exif->ed->size);
|
374
|
+
return obj;
|
375
|
+
}
|
376
|
+
|
377
|
+
|
378
|
+
#define N_(val) val
|
379
|
+
#define GPS_SUPPORT
|
380
|
+
|
381
|
+
static struct {
|
382
|
+
ExifTag tag;
|
383
|
+
const char *name;
|
384
|
+
const char *title;
|
385
|
+
} ExifTagTable[] = {
|
386
|
+
{EXIF_TAG_INTEROPERABILITY_INDEX, "InteroperabilityIndex",
|
387
|
+
"InteroperabilityIndex"},
|
388
|
+
{EXIF_TAG_INTEROPERABILITY_VERSION, "InteroperabilityVersion",
|
389
|
+
"InteroperabilityVersion"},
|
390
|
+
{EXIF_TAG_IMAGE_WIDTH, "ImageWidth", N_("Image Width")},
|
391
|
+
{EXIF_TAG_IMAGE_LENGTH, "ImageLength", N_("Image Length")},
|
392
|
+
{EXIF_TAG_BITS_PER_SAMPLE, "BitsPerSample", N_("Bits per Sample")},
|
393
|
+
{EXIF_TAG_COMPRESSION, "Compression", N_("Compression")},
|
394
|
+
{EXIF_TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation",
|
395
|
+
N_("Photometric Interpretation")},
|
396
|
+
{EXIF_TAG_FILL_ORDER, "FillOrder", N_("Fill Order")},
|
397
|
+
{EXIF_TAG_DOCUMENT_NAME, "DocumentName", N_("Document Name")},
|
398
|
+
{EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription", N_("Image Description")},
|
399
|
+
{EXIF_TAG_MAKE, "Make", N_("Manufacturer")},
|
400
|
+
{EXIF_TAG_MODEL, "Model", N_("Model")},
|
401
|
+
{EXIF_TAG_STRIP_OFFSETS, "StripOffsets", N_("Strip Offsets")},
|
402
|
+
{EXIF_TAG_ORIENTATION, "Orientation", N_("Orientation")},
|
403
|
+
{EXIF_TAG_SAMPLES_PER_PIXEL, "SamplesPerPixel",
|
404
|
+
N_("Samples per Pixel")},
|
405
|
+
{EXIF_TAG_ROWS_PER_STRIP, "RowsPerStrip", N_("Rows per Strip")},
|
406
|
+
{EXIF_TAG_STRIP_BYTE_COUNTS, "StripByteCounts", N_("Strip Byte Count")},
|
407
|
+
{EXIF_TAG_X_RESOLUTION, "XResolution", N_("x-Resolution")},
|
408
|
+
{EXIF_TAG_Y_RESOLUTION, "YResolution", N_("y-Resolution")},
|
409
|
+
{EXIF_TAG_PLANAR_CONFIGURATION, "PlanarConfiguration",
|
410
|
+
N_("Planar Configuration")},
|
411
|
+
{EXIF_TAG_RESOLUTION_UNIT, "ResolutionUnit", N_("Resolution Unit")},
|
412
|
+
{EXIF_TAG_TRANSFER_FUNCTION, "TransferFunction",
|
413
|
+
N_("Transfer Function")},
|
414
|
+
{EXIF_TAG_SOFTWARE, "Software", N_("Software")},
|
415
|
+
{EXIF_TAG_DATE_TIME, "DateTime", N_("Date and Time")},
|
416
|
+
{EXIF_TAG_ARTIST, "Artist", N_("Artist")},
|
417
|
+
{EXIF_TAG_WHITE_POINT, "WhitePoint", N_("White Point")},
|
418
|
+
{EXIF_TAG_PRIMARY_CHROMATICITIES, "PrimaryChromaticities",
|
419
|
+
N_("Primary Chromaticities")},
|
420
|
+
{EXIF_TAG_TRANSFER_RANGE, "TransferRange", N_("Transfer Range")},
|
421
|
+
{EXIF_TAG_JPEG_PROC, "JPEGProc", "JPEGProc"},
|
422
|
+
{EXIF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEGInterchangeFormat",
|
423
|
+
N_("JPEG Interchange Format")},
|
424
|
+
{EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
|
425
|
+
"JPEGInterchangeFormatLength", N_("JPEG Interchange Format Length")},
|
426
|
+
{EXIF_TAG_YCBCR_COEFFICIENTS, "YCbCrCoefficients",
|
427
|
+
N_("YCbCr Coefficients")},
|
428
|
+
{EXIF_TAG_YCBCR_SUB_SAMPLING, "YCbCrSubSampling",
|
429
|
+
N_("YCbCr Sub-Sampling")},
|
430
|
+
{EXIF_TAG_YCBCR_POSITIONING, "YCbCrPositioning",
|
431
|
+
N_("YCbCr Positioning")},
|
432
|
+
{EXIF_TAG_REFERENCE_BLACK_WHITE, "ReferenceBlackWhite",
|
433
|
+
N_("Reference Black/White")},
|
434
|
+
{EXIF_TAG_RELATED_IMAGE_FILE_FORMAT, "RelatedImageFileFormat",
|
435
|
+
"RelatedImageFileFormat"},
|
436
|
+
{EXIF_TAG_RELATED_IMAGE_WIDTH, "RelatedImageWidth",
|
437
|
+
"RelatedImageWidth"},
|
438
|
+
{EXIF_TAG_RELATED_IMAGE_LENGTH, "RelatedImageLength",
|
439
|
+
"RelatedImageLength"},
|
440
|
+
{EXIF_TAG_CFA_REPEAT_PATTERN_DIM, "CFARepeatPatternDim",
|
441
|
+
"CFARepeatPatternDim"},
|
442
|
+
{EXIF_TAG_CFA_PATTERN, "CFAPattern",
|
443
|
+
N_("CFA Pattern")},
|
444
|
+
{EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", N_("Battery Level")},
|
445
|
+
{EXIF_TAG_COPYRIGHT, "Copyright", N_("Copyright")},
|
446
|
+
{EXIF_TAG_EXPOSURE_TIME, "ExposureTime", N_("Exposure Time")},
|
447
|
+
{EXIF_TAG_FNUMBER, "FNumber", "FNumber"},
|
448
|
+
{EXIF_TAG_IPTC_NAA, "IPTC/NAA", "IPTC/NAA"},
|
449
|
+
{EXIF_TAG_EXIF_IFD_POINTER, "ExifIFDPointer", "ExifIFDPointer"},
|
450
|
+
{EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile",
|
451
|
+
"InterColorProfile"},
|
452
|
+
{EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", "ExposureProgram"},
|
453
|
+
{EXIF_TAG_SPECTRAL_SENSITIVITY, "SpectralSensitivity",
|
454
|
+
N_("Spectral Sensitivity")},
|
455
|
+
{EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer",
|
456
|
+
"GPSInfoIFDPointer"},
|
457
|
+
#ifdef GPS_SUPPORT
|
458
|
+
{EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", N_("GPS tag version")},
|
459
|
+
{EXIF_TAG_GPS_LATITUDE_REF, "GPSLatutideRef", N_("North or South latitude")},
|
460
|
+
{EXIF_TAG_GPS_LATITUDE, "GPSLatitude", N_("Latitude")},
|
461
|
+
{EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", N_("East or West longitude")},
|
462
|
+
{EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", N_("Longitude")},
|
463
|
+
{EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", N_("Altitude reference")},
|
464
|
+
{EXIF_TAG_GPS_ALTITUDE , "GPSAltitude", N_("Altitude")},
|
465
|
+
{EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", N_("GPS time (atomic clock)")},
|
466
|
+
{EXIF_TAG_GPS_SATELLITES, "GPSSatellites", N_("GPS satellites used for measurement")},
|
467
|
+
{EXIF_TAG_GPS_STATUS, "GPSStatus", N_(" GPS receiver status")},
|
468
|
+
{EXIF_TAG_GPS_MEASURE_MODE, "GPSMessureMode", N_("GPS measurement mode")},
|
469
|
+
{EXIF_TAG_GPS_DOP, "GPSDOP", N_("Measurement precision")},
|
470
|
+
{EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", N_("Speed unit")},
|
471
|
+
{EXIF_TAG_GPS_SPEED, "GPSSpeed", N_("Speed of GPS receiver")},
|
472
|
+
{EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", N_("Reference for direction of movement")},
|
473
|
+
{EXIF_TAG_GPS_TRACK, "GPSTrack", N_("Direction of movement")},
|
474
|
+
{EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", N_("Reference for direction of image")},
|
475
|
+
{EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", N_("Direction of image")},
|
476
|
+
{EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", N_("Geodetic survey data used")},
|
477
|
+
{EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", N_("Reference for latitude of destination")},
|
478
|
+
{EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", N_("Latitude of destination")},
|
479
|
+
{EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", N_("Reference for longitude of destination")},
|
480
|
+
{EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", N_("Longitude of destination")},
|
481
|
+
{EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", N_("Reference for bearing of destination")},
|
482
|
+
{EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", N_("Bearing of destination")},
|
483
|
+
{EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", N_("Reference for distance to destination")},
|
484
|
+
{EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", N_("Distance to destination")},
|
485
|
+
{EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", N_("Name of GPS processing method")},
|
486
|
+
{EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", N_("Name of GPS area")},
|
487
|
+
{EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", N_("GPS date")},
|
488
|
+
{EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", N_("GPS differential correction")},
|
489
|
+
#endif
|
490
|
+
|
491
|
+
{EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings",
|
492
|
+
N_("ISO Speed Ratings")},
|
493
|
+
{EXIF_TAG_OECF, "OECF", "OECF"},
|
494
|
+
{EXIF_TAG_EXIF_VERSION, "ExifVersion", N_("Exif Version")},
|
495
|
+
{EXIF_TAG_DATE_TIME_ORIGINAL, "DateTimeOriginal",
|
496
|
+
N_("Date and Time (original)")},
|
497
|
+
{EXIF_TAG_DATE_TIME_DIGITIZED, "DateTimeDigitized",
|
498
|
+
N_("Date and Time (digitized)")},
|
499
|
+
{EXIF_TAG_COMPONENTS_CONFIGURATION, "ComponentsConfiguration",
|
500
|
+
"ComponentsConfiguration"},
|
501
|
+
{EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, "CompressedBitsPerPixel",
|
502
|
+
N_("Compressed Bits per Pixel")},
|
503
|
+
{EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue",
|
504
|
+
N_("Shutter speed")},
|
505
|
+
{EXIF_TAG_APERTURE_VALUE, "ApertureValue", N_("Aperture")},
|
506
|
+
{EXIF_TAG_BRIGHTNESS_VALUE, "BrightnessValue", N_("Brightness")},
|
507
|
+
{EXIF_TAG_EXPOSURE_BIAS_VALUE, "ExposureBiasValue",
|
508
|
+
N_("Exposure Bias")},
|
509
|
+
{EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", "MaxApertureValue"},
|
510
|
+
{EXIF_TAG_SUBJECT_DISTANCE, "SubjectDistance",
|
511
|
+
N_("Subject Distance")},
|
512
|
+
{EXIF_TAG_METERING_MODE, "MeteringMode", N_("Metering Mode")},
|
513
|
+
{EXIF_TAG_LIGHT_SOURCE, "LightSource", N_("Light Source")},
|
514
|
+
{EXIF_TAG_FLASH, "Flash", N_("Flash")},
|
515
|
+
{EXIF_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length")},
|
516
|
+
{EXIF_TAG_MAKER_NOTE, "MakerNote", N_("Maker Note")},
|
517
|
+
{EXIF_TAG_USER_COMMENT, "UserComment", N_("User Comment")},
|
518
|
+
{EXIF_TAG_SUBSEC_TIME, "SubsecTime", "SubsecTime"},
|
519
|
+
{EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "SubSecTimeOriginal",
|
520
|
+
"SubSecTimeOriginal"},
|
521
|
+
{EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "SubSecTimeDigitized",
|
522
|
+
"SubSecTimeDigitized"},
|
523
|
+
{EXIF_TAG_FLASH_PIX_VERSION, "FlashPixVersion", "FlashPixVersion"},
|
524
|
+
{EXIF_TAG_COLOR_SPACE, "ColorSpace", N_("Color Space")},
|
525
|
+
{EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", "PixelXDimension"},
|
526
|
+
{EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", "PixelYDimension"},
|
527
|
+
{EXIF_TAG_RELATED_SOUND_FILE, "RelatedSoundFile",
|
528
|
+
"RelatedSoundFile"},
|
529
|
+
{EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer",
|
530
|
+
"InteroperabilityIFDPointer"},
|
531
|
+
{EXIF_TAG_FLASH_ENERGY, "FlashEnergy", N_("Flash Energy")},
|
532
|
+
{EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE, "SpatialFrequencyResponse",
|
533
|
+
N_("Spatial Frequency Response")},
|
534
|
+
{EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, "FocalPlaneXResolution",
|
535
|
+
N_("Focal Plane x-Resolution")},
|
536
|
+
{EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, "FocalPlaneYResolution",
|
537
|
+
N_("Focal Plane y-Resolution")},
|
538
|
+
{EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, "FocalPlaneResolutionUnit",
|
539
|
+
N_("Focal Plane Resolution Unit")},
|
540
|
+
{EXIF_TAG_SUBJECT_LOCATION, "SubjectLocation",
|
541
|
+
N_("Subject Location")},
|
542
|
+
{EXIF_TAG_EXPOSURE_INDEX, "ExposureIndex", N_("Exposure index")},
|
543
|
+
{EXIF_TAG_SENSING_METHOD, "SensingMethod", N_("Sensing Method")},
|
544
|
+
{EXIF_TAG_FILE_SOURCE, "FileSource", N_("File Source")},
|
545
|
+
{EXIF_TAG_SCENE_TYPE, "SceneType", N_("Scene Type")},
|
546
|
+
{EXIF_TAG_NEW_CFA_PATTERN, "CFAPattern",
|
547
|
+
N_("CFA Pattern")},
|
548
|
+
{EXIF_TAG_SUBJECT_AREA, "SubjectArea", N_("Subject Area")},
|
549
|
+
{EXIF_TAG_CUSTOM_RENDERED, "CustomRendered", N_("Custom Rendered")},
|
550
|
+
{EXIF_TAG_EXPOSURE_MODE, "ExposureMode", N_("Exposure Mode")},
|
551
|
+
{EXIF_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance")},
|
552
|
+
{EXIF_TAG_DIGITAL_ZOOM_RATIO, "DigitalZoomRatio",
|
553
|
+
N_("Digital Zoom Ratio")},
|
554
|
+
{EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm",
|
555
|
+
N_("Focal Length In 35mm Film")},
|
556
|
+
{EXIF_TAG_SCENE_CAPTURE_TYPE, "SceneCaptureType",
|
557
|
+
N_("Scene Capture Type")},
|
558
|
+
{EXIF_TAG_GAIN_CONTROL, "GainControl", N_("Gain Control")},
|
559
|
+
{EXIF_TAG_CONTRAST, "Contrast", N_("Contrast")},
|
560
|
+
{EXIF_TAG_SATURATION, "Saturation", N_("Saturation")},
|
561
|
+
{EXIF_TAG_SHARPNESS, "Sharpness", N_("Sharpness")},
|
562
|
+
{EXIF_TAG_DEVICE_SETTING_DESCRIPTION, "DeviceSettingDescription",
|
563
|
+
N_("Device Setting Description")},
|
564
|
+
{EXIF_TAG_SUBJECT_DISTANCE_RANGE, "SubjectDistanceRange",
|
565
|
+
N_("Subject Distance Range")},
|
566
|
+
{EXIF_TAG_IMAGE_UNIQUE_ID, "ImageUniqueID", N_("Image Unique ID")},
|
567
|
+
{-1, NULL, NULL}
|
568
|
+
};
|
569
|
+
|
570
|
+
|
571
|
+
static ExifTag
|
572
|
+
exif_tag_from_string (const char *str)
|
573
|
+
{
|
574
|
+
int i;
|
575
|
+
|
576
|
+
if (!str)
|
577
|
+
return 0;
|
578
|
+
/* Is the string a tag's name or title? */
|
579
|
+
for (i = 0; ExifTagTable[i].name != NULL; i++) {
|
580
|
+
if (!strcmp (str, ExifTagTable[i].name))
|
581
|
+
return (ExifTagTable[i].tag);
|
582
|
+
if (!strcmp (str, ExifTagTable[i].title))
|
583
|
+
return (ExifTagTable[i].tag);
|
584
|
+
}
|
585
|
+
return 0;
|
586
|
+
}
|
587
|
+
|
588
|
+
static ExifTag
|
589
|
+
exif_tag_from_tagid(ExifTag tag)
|
590
|
+
{
|
591
|
+
int i;
|
592
|
+
for (i = 0; ExifTagTable[i].tag != -1; i++) {
|
593
|
+
if (ExifTagTable[i].tag == tag)
|
594
|
+
return tag;
|
595
|
+
}
|
596
|
+
return 0;
|
597
|
+
}
|
598
|
+
|
599
|
+
|
600
|
+
static ExifIfd
|
601
|
+
exif_ifd_from_string (const char *string)
|
602
|
+
{
|
603
|
+
unsigned int i;
|
604
|
+
|
605
|
+
if (!string)
|
606
|
+
return (-1);
|
607
|
+
|
608
|
+
for (i = 0; i < EXIF_IFD_COUNT; i++) {
|
609
|
+
if (!strcmp (string, exif_ifd_get_name (i)))
|
610
|
+
return (i);
|
611
|
+
}
|
612
|
+
|
613
|
+
return (-1);
|
614
|
+
}
|
615
|
+
|
616
|
+
void
|
617
|
+
Init_exif(void)
|
618
|
+
{
|
619
|
+
cExif = rb_define_class("Exif", rb_cObject);
|
620
|
+
eExifError = rb_define_class_under(cExif, "Error", rb_eRuntimeError);
|
621
|
+
eExifInvalidFormat = rb_define_class_under(cExif, "NotExifFormat", eExifError);
|
622
|
+
eExifInvalidIFD = rb_define_class_under(eExifError, "InvalidIFD", eExifError);
|
623
|
+
eExifTagNotFound = rb_define_class_under(eExifError, "TagNotFound", eExifError);
|
624
|
+
eExifThumbnailNotFound = rb_define_class_under(eExifError, "ThumbnailNotFound", eExifError);
|
625
|
+
|
626
|
+
rb_define_singleton_method(cExif, "new", rb_exif_s_new, -1);
|
627
|
+
rb_define_private_method(cExif, "initialize", rb_exif_initialize, -1);
|
628
|
+
rb_define_method(cExif, "data=", rb_exif_set_data, 1);
|
629
|
+
rb_define_alias(cExif, "<<", "data=");
|
630
|
+
rb_define_method(cExif, "each_entry", rb_exif_each, -1);
|
631
|
+
rb_define_method(cExif, "byte_order", rb_exif_get_byte_order, 0);
|
632
|
+
rb_define_method(cExif, "byte_order=", rb_exif_set_byte_order, 1);
|
633
|
+
rb_define_method(cExif, "ifd=", rb_exif_set_ifd, 1);
|
634
|
+
rb_define_method(cExif, "ifd", rb_exif_get_ifd, 0);
|
635
|
+
rb_define_method(cExif, "[]", rb_exif_get_tag, 1);
|
636
|
+
rb_define_method(cExif, "[]=", rb_exif_set_tag, 2);
|
637
|
+
rb_define_singleton_method(cExif, "[]", rb_exif_s_get_tag_description, 1);
|
638
|
+
rb_define_method(cExif, "list_tags", rb_exif_list_tags_at_ifd, 1);
|
639
|
+
rb_define_method(cExif, "extract_thumbnail", rb_exif_extract_thumbnail, 1);
|
640
|
+
rb_define_alias(cExif, "thumbnail", "extract_thumbnail");
|
641
|
+
rb_define_method(cExif, "thumbnail=", rb_exif_set_thumbnail, 1);
|
642
|
+
|
643
|
+
mExifByteOrder = rb_define_module_under(cExif, "ByteOrder");
|
644
|
+
rb_define_const(mExifByteOrder, "MOTOROLA", INT2FIX(EXIF_BYTE_ORDER_MOTOROLA));
|
645
|
+
rb_define_const(mExifByteOrder, "INTEL", INT2FIX(EXIF_BYTE_ORDER_INTEL));
|
646
|
+
mExifIfd = rb_define_module_under(cExif, "IFD");
|
647
|
+
rb_define_const(mExifIfd, "Zero", INT2FIX(EXIF_IFD_0));
|
648
|
+
rb_define_const(mExifIfd, "One", INT2FIX(EXIF_IFD_1));
|
649
|
+
rb_define_const(mExifIfd, "EXIF", INT2FIX(EXIF_IFD_EXIF));
|
650
|
+
rb_define_const(mExifIfd, "GPS", INT2FIX(EXIF_IFD_GPS));
|
651
|
+
rb_define_const(mExifIfd, "Interoperability", INT2FIX(EXIF_IFD_INTEROPERABILITY));
|
652
|
+
rb_define_const(mExifIfd, "Any", INT2FIX(IFD_RB_DEFAULT));
|
653
|
+
}
|