extexif 1.0.0
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/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
|
+
}
|