iptc 0.0.3 → 0.0.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.
- data/lib/iptc/jpeg/markers.rb +158 -167
- data/lib/iptc/version.rb +2 -2
- metadata +4 -4
data/lib/iptc/jpeg/markers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# :vi:ts=2:sts=2:et:
|
1
2
|
require 'stringio'
|
2
3
|
|
3
4
|
require 'iptc/marker'
|
@@ -5,186 +6,176 @@ require 'iptc/marker_nomenclature'
|
|
5
6
|
require 'iptc/jpeg/marker'
|
6
7
|
|
7
8
|
module IPTC
|
8
|
-
|
9
9
|
module JPEG
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
10
|
+
# == Markers
|
11
|
+
# All the known JPEG markers
|
12
|
+
module Markers
|
13
|
+
# == SOIMarker
|
14
|
+
# The Start Of Image Marker
|
15
|
+
class SOIMarker < Marker
|
16
|
+
def valid?
|
17
|
+
return read(5)=="JFIF\0"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
# == COMMarker
|
21
|
+
# The COM Marker, contains comments
|
22
|
+
class COMMarker < Marker
|
23
|
+
attr_reader :content
|
24
|
+
def parse
|
25
|
+
l "COM Marker Parsed"
|
26
|
+
@content = read(@size)
|
27
|
+
@dirty = false
|
28
|
+
|
29
|
+
@values['COM/COM']=@content
|
30
|
+
end
|
31
|
+
# def []=(key,value)
|
32
|
+
# if @content != value
|
33
|
+
# @content = value
|
34
|
+
# @dirty = true
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
def [](item)
|
38
|
+
return @content
|
39
|
+
end
|
40
|
+
end
|
41
|
+
# == The APP13Marker
|
42
|
+
# The APP13 marker, know as the IPTC Marker
|
43
|
+
# See also the IPTC::MarkerNomenclature.
|
44
|
+
class APP13Marker < Marker
|
45
|
+
def initialize(type, data)
|
46
|
+
@header = "Photoshop 3.0\0008BIM"
|
47
|
+
|
48
|
+
super(type, data)
|
49
|
+
@prefix = "iptc"
|
50
|
+
|
51
|
+
end
|
52
|
+
def valid?
|
53
|
+
return read(@header.length)==@header
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse
|
57
|
+
l "APP13 marker parsed"
|
58
|
+
@markers = Array.new
|
59
|
+
|
60
|
+
|
61
|
+
@bim_type = read(2)
|
62
|
+
@bim_dummy = read(4)
|
63
|
+
size = read(2)
|
64
|
+
|
65
|
+
content = StringIO.new(read(size.unpack('n')[0]))
|
66
|
+
|
67
|
+
while !content.eof?
|
68
|
+
|
69
|
+
header = content.read(2)
|
70
|
+
|
71
|
+
# http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
|
72
|
+
case header
|
73
|
+
when "\x1c\x01"
|
74
|
+
# skip the envelope
|
75
|
+
while !content.eof?
|
76
|
+
if content.read(1) == "\x1c"
|
77
|
+
content.pos = content.pos - 1
|
78
|
+
break
|
79
|
+
end
|
48
80
|
end
|
49
|
-
|
50
|
-
# == The APP13Marker
|
51
|
-
# The APP13 marker, know as the IPTC Marker
|
52
|
-
# See also the IPTC::MarkerNomenclature.
|
53
|
-
class APP13Marker < Marker
|
54
|
-
def initialize(type, data)
|
55
|
-
@header = "Photoshop 3.0\0008BIM"
|
81
|
+
when "\x1c\x02"
|
56
82
|
|
57
|
-
|
58
|
-
|
83
|
+
type = content.read(1).unpack('c')[0]
|
84
|
+
size = content.read(2)
|
85
|
+
value = content.read(size.unpack('n')[0])
|
59
86
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@bim_type = read(2)
|
71
|
-
@bim_dummy = read(4)
|
72
|
-
size = read(2)
|
73
|
-
|
74
|
-
content = StringIO.new(read(size.unpack('n')[0]))
|
75
|
-
|
76
|
-
while !content.eof?
|
77
|
-
|
78
|
-
header = content.read(2)
|
79
|
-
|
80
|
-
# http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
|
81
|
-
case header
|
82
|
-
when "\x1c\x01"
|
83
|
-
# skip the envelope
|
84
|
-
while !content.eof?
|
85
|
-
if content.read(1) == "\x1c"
|
86
|
-
content.pos = content.pos - 1
|
87
|
-
break
|
88
|
-
end
|
89
|
-
end
|
90
|
-
when "\x1c\x02"
|
91
|
-
|
92
|
-
type = content.read(1).unpack('c')[0]
|
93
|
-
size = content.read(2)
|
94
|
-
value = content.read(size.unpack('n')[0])
|
95
|
-
|
96
|
-
l "Found marker #{type}"
|
97
|
-
marker = IPTC::Marker.new(type, value)
|
98
|
-
@values[@prefix+"/"+IPTC::MarkerNomenclature.markers(type.to_i).name] ||= []
|
99
|
-
@values[@prefix+"/"+IPTC::MarkerNomenclature.markers(type.to_i).name] << value
|
100
|
-
@markers << marker
|
101
|
-
|
102
|
-
else
|
103
|
-
# raise InvalidBlockException.new("Invalid BIM segment #{header.inspect} in marker\n#{@original_content.inspect}")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
return @values
|
107
|
-
end
|
108
|
-
|
109
|
-
def [](item)
|
110
|
-
return @values[item]
|
111
|
-
end
|
112
|
-
def to_binary
|
113
|
-
marker = ""
|
114
|
-
@markers.each do |value|
|
115
|
-
marker += value.to_binary
|
116
|
-
end
|
117
|
-
|
118
|
-
marker = @header+@bim_type+@bim_dummy+[marker.length].pack('n')+marker
|
119
|
-
|
120
|
-
# build the complete marker
|
121
|
-
marker = super(marker)
|
122
|
-
|
123
|
-
return marker
|
124
|
-
end
|
125
|
-
def properties
|
126
|
-
return IPTC::TAGS.values.sort
|
127
|
-
end
|
128
|
-
def set(property, value)
|
129
|
-
numerical_tag = IPTC::TAGS.index(property)
|
130
|
-
if numerical_tag!=nil
|
131
|
-
else
|
132
|
-
throw InvalidPropertyException.new("Invalid property #{property} for IPTC marker")
|
133
|
-
end
|
134
|
-
marker = IPTC::Marker.new(numerical_tag, value)
|
135
|
-
@markers << marker
|
136
|
-
end
|
87
|
+
l "Found marker #{type}"
|
88
|
+
marker = IPTC::Marker.new(type, value)
|
89
|
+
@values[@prefix+"/"+IPTC::MarkerNomenclature.markers(type.to_i).name] ||= []
|
90
|
+
@values[@prefix+"/"+IPTC::MarkerNomenclature.markers(type.to_i).name] << value
|
91
|
+
@markers << marker
|
92
|
+
|
93
|
+
else
|
94
|
+
# raise InvalidBlockException.new("Invalid BIM segment #{header.inspect} in marker\n#{@original_content.inspect}")
|
95
|
+
end
|
137
96
|
end
|
138
|
-
|
97
|
+
return @values
|
98
|
+
end
|
99
|
+
|
100
|
+
def [](item)
|
101
|
+
return @values[item]
|
102
|
+
end
|
103
|
+
def to_binary
|
104
|
+
marker = ""
|
105
|
+
@markers.each do |value|
|
106
|
+
marker += value.to_binary
|
139
107
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
108
|
+
|
109
|
+
marker = @header+@bim_type+@bim_dummy+[marker.length].pack('n')+marker
|
110
|
+
|
111
|
+
# build the complete marker
|
112
|
+
marker = super(marker)
|
113
|
+
|
114
|
+
return marker
|
115
|
+
end
|
116
|
+
def properties
|
117
|
+
return IPTC::TAGS.values.sort
|
118
|
+
end
|
119
|
+
def set(property, value)
|
120
|
+
numerical_tag = IPTC::TAGS.index(property)
|
121
|
+
if numerical_tag!=nil
|
122
|
+
else
|
123
|
+
throw InvalidPropertyException.new("Invalid property #{property} for IPTC marker")
|
124
|
+
end
|
125
|
+
marker = IPTC::Marker.new(numerical_tag, value)
|
126
|
+
@markers << marker
|
127
|
+
end
|
128
|
+
end
|
129
|
+
class InvalidPropertyException < Exception
|
130
|
+
end
|
131
|
+
# == The APP0Marker
|
132
|
+
# Contains some useful JFIF informations about the current
|
133
|
+
# image.
|
134
|
+
class APP0Marker < Marker
|
135
|
+
def initialize type, data
|
136
|
+
super type, data
|
137
|
+
end
|
138
|
+
def valid?
|
139
|
+
if read(5)!="JFIF\0"
|
140
|
+
return false
|
167
141
|
end
|
168
|
-
|
142
|
+
return true
|
143
|
+
end
|
144
|
+
def parse
|
145
|
+
|
146
|
+
@values = {
|
147
|
+
'APP0/revision'=>read(2).unpack('n')[0],
|
148
|
+
'APP0/unit' => read(1),
|
149
|
+
'APP0/xdensity' => read(2).unpack('n')[0],
|
150
|
+
'APP0/ydensity' => read(2).unpack('n')[0],
|
151
|
+
'APP0/xthumbnail' => read(1).unpack('c')[0],
|
152
|
+
'APP0/ythumbnail' => read(1).unpack('c')[0]
|
153
|
+
}
|
154
|
+
end
|
155
|
+
def [](item)
|
156
|
+
return @values[item]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
169
160
|
end
|
170
161
|
end
|
171
162
|
|
172
163
|
if $0 == __FILE__
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
require 'iptc/jpeg/image'
|
179
|
-
|
164
|
+
if ARGV[0]==nil
|
165
|
+
puts "No file given. Aborting."
|
166
|
+
exit
|
167
|
+
end
|
180
168
|
|
181
|
-
|
182
|
-
im = IPTC::JPEG::Image.new(ARGV[0])
|
169
|
+
require 'iptc/jpeg/image'
|
183
170
|
|
184
|
-
puts "Done reading #{ARGV[0]}"
|
185
171
|
|
186
|
-
|
187
|
-
|
188
|
-
|
172
|
+
# read the image
|
173
|
+
im = IPTC::JPEG::Image.new(ARGV[0])
|
174
|
+
|
175
|
+
puts "Done reading #{ARGV[0]}"
|
176
|
+
|
177
|
+
im.values.each do |item|
|
178
|
+
puts "#{item.key}\t#{item.value}"
|
179
|
+
end
|
189
180
|
|
190
181
|
end
|
data/lib/iptc/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module IPTC
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
2
|
+
VERSION = "0.0.5"
|
3
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iptc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pierre Baillet
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date:
|
19
|
+
date: 2012-01-09 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|