tiny-quick-box 0.0.1

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.
@@ -0,0 +1,151 @@
1
+ require "json"
2
+
3
+ module MiniMagick
4
+ class Image
5
+ # @private
6
+ class Info
7
+ ASCII_ENCODED_EXIF_KEYS = %w[ExifVersion FlashPixVersion]
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ @info = {}
12
+ end
13
+
14
+ def [](value, *args)
15
+ case value
16
+ when "format", "width", "height", "dimensions", "size", "human_size"
17
+ cheap_info(value)
18
+ when "colorspace"
19
+ colorspace
20
+ when "resolution"
21
+ resolution(*args)
22
+ when "signature"
23
+ signature
24
+ when /^EXIF\:/i
25
+ raw_exif(value)
26
+ when "exif"
27
+ exif
28
+ when "data"
29
+ data
30
+ else
31
+ raw(value)
32
+ end
33
+ end
34
+
35
+ def clear
36
+ @info.clear
37
+ end
38
+
39
+ def cheap_info(value)
40
+ @info.fetch(value) do
41
+ format, width, height, size = parse_warnings(self["%m %w %h %b"]).split(" ")
42
+
43
+ path = @path
44
+ path = path.match(/\[\d+\]$/).pre_match if path =~ /\[\d+\]$/
45
+
46
+ @info.update(
47
+ "format" => format,
48
+ "width" => Integer(width),
49
+ "height" => Integer(height),
50
+ "dimensions" => [Integer(width), Integer(height)],
51
+ "size" => File.size(path),
52
+ "human_size" => size,
53
+ )
54
+
55
+ @info.fetch(value)
56
+ end
57
+ rescue ArgumentError, TypeError
58
+ raise MiniMagick::Invalid, "image data can't be read"
59
+ end
60
+
61
+ def parse_warnings(raw_info)
62
+ return raw_info unless raw_info.split("\n").size > 1
63
+
64
+ raw_info.split("\n").each do |line|
65
+ # must match "%m %w %h %b"
66
+ return line if line.match?(/^[A-Z]+ \d+ \d+ \d+(|\.\d+)([KMGTPEZY]{0,1})B$/)
67
+ end
68
+ raise TypeError
69
+ end
70
+
71
+ def colorspace
72
+ @info["colorspace"] ||= self["%r"]
73
+ end
74
+
75
+ def resolution(unit = nil)
76
+ output = identify do |b|
77
+ b.units unit if unit
78
+ b.format "%x %y"
79
+ end
80
+ output.split(" ").map(&:to_i)
81
+ end
82
+
83
+ def raw_exif(value)
84
+ self["%[#{value}]"]
85
+ end
86
+
87
+ def exif
88
+ @info["exif"] ||= (
89
+ hash = {}
90
+ output = self["%[EXIF:*]"]
91
+
92
+ output.each_line do |line|
93
+ line = line.chomp("\n")
94
+
95
+ if match = line.match(/^exif:/)
96
+ key, value = match.post_match.split("=", 2)
97
+ value = decode_comma_separated_ascii_characters(value) if ASCII_ENCODED_EXIF_KEYS.include?(key)
98
+ hash[key] = value
99
+ else
100
+ hash[hash.keys.last] << "\n#{line}"
101
+ end
102
+ end
103
+
104
+ hash
105
+ )
106
+ end
107
+
108
+ def raw(value)
109
+ @info["raw:#{value}"] ||= identify { |b| b.format(value) }
110
+ end
111
+
112
+ def signature
113
+ @info["signature"] ||= self["%#"]
114
+ end
115
+
116
+ def data
117
+ @info["data"] ||= (
118
+ json = MiniMagick.convert do |convert|
119
+ convert << path
120
+ convert << "json:"
121
+ end
122
+
123
+ data = JSON.parse(json)
124
+ data = data.fetch(0) if data.is_a?(Array)
125
+ data.fetch("image")
126
+ )
127
+ end
128
+
129
+ def identify
130
+ MiniMagick.identify do |builder|
131
+ yield builder if block_given?
132
+ builder << path
133
+ end
134
+ end
135
+
136
+ private
137
+
138
+ def decode_comma_separated_ascii_characters(encoded_value)
139
+ return encoded_value unless encoded_value.include?(',')
140
+ encoded_value.scan(/\d+/).map(&:to_i).map(&:chr).join
141
+ end
142
+
143
+ def path
144
+ value = @path
145
+ value += "[0]" unless value =~ /\[\d+\]$/
146
+ value
147
+ end
148
+
149
+ end
150
+ end
151
+ end