image_filter_dsl 0.0.3 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +167 -19
- data/bin/image_filter_dsl +8 -6
- data/lib/image_filter_dsl.rb +2 -1
- data/lib/image_filter_dsl/binary/struct.rb +1 -1
- data/lib/image_filter_dsl/dsl/filter_instructions.rb +101 -4
- data/lib/image_filter_dsl/engine/cli.rb +83 -0
- data/lib/image_filter_dsl/engine/image_processor.rb +2 -1
- data/lib/image_filter_dsl/serialize.rb +69 -0
- data/lib/image_filter_dsl/serializers/common.rb +57 -0
- data/lib/image_filter_dsl/serializers/intermediate.rb +65 -0
- data/lib/image_filter_dsl/serializers/json.rb +43 -0
- data/lib/image_filter_dsl/serializers/msg_pack.rb +51 -0
- data/lib/image_filter_dsl/serializers/yaml.rb +42 -0
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3c5ec517d5379d54dcac83356f816f4e460ea651956600c4a406766483fff9e
|
4
|
+
data.tar.gz: a26273761002413d8f2944fce7c6d9da591a3b3124be8a640f9c375a029df739
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 573236b32a4096fe6d8e57106cf9e4e79e9c4571583d0b9d1ceb710e8cb2dd227cadc51597bd5d8751fd55efd86ee4038207598833a38f3f41da8d8e3c9b5e47
|
7
|
+
data.tar.gz: f3703bc27fce75391023a2e8ab056f721471f3e522326f4201fa98600f62f70b75e3fb9b7a5850208c395883746e5d8ee5d4bd0b0e847f4b1e25b101bdeb2a21
|
data/README.md
CHANGED
@@ -4,54 +4,202 @@ _An Image Filter DSL (duh)_
|
|
4
4
|
|
5
5
|
[](https://badge.fury.io/rb/image_filter_dsl)
|
6
6
|
|
7
|
+
{file:CHANGELOG.md Change Log}
|
8
|
+
|
7
9
|
## Features
|
8
10
|
|
9
11
|
- DSL with customizable input and output variables, and a set of basic instructions
|
10
12
|
- IO with serialization so Kernels can be written to binary files and loaded from binary files
|
11
13
|
- Image Processor that generates image file by applying Filter Kernel to every pixel of input image (supports multi-threading)
|
12
14
|
|
13
|
-
|
15
|
+
## DSL
|
14
16
|
|
15
|
-
|
17
|
+
### Filter Block
|
18
|
+
|
19
|
+
Using `ImageFilterDsl::Dsl::Filter`
|
16
20
|
|
17
21
|
```ruby
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
# - First array contains input variables
|
23
|
+
# x, y, r, g, b, a, :width and :hght are automatically
|
24
|
+
# populated by image filter process
|
25
|
+
# - Second array contains output vars; r,g,b,a and optionally
|
26
|
+
# x,y for images
|
27
|
+
filter = Filter.define [:x,:y,:r,:g,:b], [:r,:g,:b] do
|
28
|
+
# Instructions go here
|
29
|
+
# instruction [input(s)], output
|
30
|
+
add [:x,:r], :g
|
31
|
+
|
32
|
+
# output can be an existing symbol in out, or a custom one up to 5 letters
|
33
|
+
# long (longer will be trimmed if serialized to a binary file)
|
34
|
+
|
35
|
+
# input can be any declared input or custom variable
|
23
36
|
end
|
24
37
|
```
|
25
38
|
|
39
|
+
### Instructions
|
40
|
+
|
41
|
+
Basic Use:
|
42
|
+
|
43
|
+
``instruction [argument1,argument2,...], :output_variable``
|
44
|
+
|
45
|
+
__Math__
|
46
|
+
|
47
|
+
- `add` add 2 or more input values, storing in output (<code>a+b</code>)
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
add [:r,5], :r # replace r with r + 5
|
51
|
+
```
|
52
|
+
|
53
|
+
- `mult` add 2 or more inputs, storing in out (<code>a*b</code>)
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
mult [:r,2], :r # Replace r with r * 2
|
57
|
+
```
|
58
|
+
|
59
|
+
- `div` divide 2 inputs
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
div [:r, 2], :g # Write r/2 to g
|
63
|
+
```
|
64
|
+
|
65
|
+
- `mod` store modulo of two inputs in output
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
mod [2,4], :t # Write 2$4 (2) to t
|
69
|
+
```
|
70
|
+
|
71
|
+
- `abs` store absolute value of input in output
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
abs [-5], :r # Writes abs(5) to r
|
75
|
+
```
|
76
|
+
|
77
|
+
__Collection__
|
78
|
+
|
79
|
+
- `min` store smallest of inputs in output (accepts 2 or more values)
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
min [:r,255,:g], :s # Writes smallest of r, 255 and g to s
|
83
|
+
```
|
84
|
+
|
85
|
+
- `max` store largest of inputs in output (accepts 2 or more values)
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
max [:r,0,:g], :s # Writes largest of r, 0 and g to s
|
89
|
+
```
|
90
|
+
|
91
|
+
- `avg` store average of inputs in output (accepts 2 or more values)
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
avg [:r,:g,:b], :ca # Writes (r+g+b)/3 to ca
|
95
|
+
```
|
96
|
+
|
97
|
+
|
98
|
+
__Logic/Conversion/Memory__
|
99
|
+
|
100
|
+
- `above` choose one of two values based on greater than comparison (2 or 4 values) `[n1,n1,true_val,false_val]` (If not specified, `true_val` is 1 and `false_val` is 0)
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
# if r > g, store 0 in g, else store g in g (keep g the same)
|
104
|
+
above [:r,:g,0,:g], :g
|
105
|
+
```
|
106
|
+
|
107
|
+
- `below` choose one of two values based on less than comparison (2 or 4 values) `[n1,n1,true_val,false_val]` (If not specified, `true_val` is 1 and `false_val` is 0)
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# if r < g, store 0 in r, else store r in r (keep r the same)
|
111
|
+
below [:r,:g,0,:r], :r
|
112
|
+
```
|
113
|
+
|
114
|
+
- `between` choose one of two values based on whether value is between two others (3 or 5 values) `[min,max,value,true_val,false_val]` (If not specified, `true_val` is 1 and `false_val` is 0)
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
# Returns value since val > 1 && val < 3
|
118
|
+
below [1,3,2], :r
|
119
|
+
# Returns 1 since -1 < 1
|
120
|
+
below [1,-1,5], :r
|
121
|
+
```
|
122
|
+
|
123
|
+
- `switch` choose one of two values based on condition value (1/1.0 = true, 0/0.0 = false) `[cond,true_val,false_val]`
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# If c is true, store r in a, else store g in a
|
127
|
+
switch [:c,:r,:g], :a
|
128
|
+
```
|
129
|
+
|
130
|
+
- `eq` if two input values are equal, store 1, else 0 (_2 values_) (`[val1,val2]`)
|
131
|
+
- `bnot` if input is 1 or 1.0, store 0, else 1 (_1 value_) (`[bool]`)
|
132
|
+
- `band` if _all_ input values are 1 or 1.0, store 1, else 0 (_1+ values_) (`[val1,val2,...]`)
|
133
|
+
- `bor` if _any_ input values are 1 or 1.0, store 1, else 0 (_1+ values_) (`[val1,val2,...]`)
|
134
|
+
- `copy` copy input directly to output (`[src]`)
|
135
|
+
- `ceil` nearest whole integer of input, rounded up (_1 value_) (`[val]`)
|
136
|
+
- `floor` nearest whole integer of input, rounded down (_1 value_) (`[val]`)
|
137
|
+
- `clamp` input clamped to be no less than min, no greater than max (`[min,max,val]`)
|
138
|
+
- `float` cast input to float (_1 value_) (`[val]`)
|
139
|
+
- `round` round first input value to second value decimals (`[value,decimal_count]`)
|
140
|
+
- `mix` Mix two values together with a ratio (0*a + (1-r)*b) (`[ratio,a,b]`)
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# store (0.3*r) + (0.7*g) in b
|
144
|
+
mix [0.3,:r,:g], :b
|
145
|
+
```
|
146
|
+
|
147
|
+
__Generators__
|
148
|
+
|
149
|
+
- `rand` random float between min and max (`[min,max]`)
|
150
|
+
- `sin` sine function on single value
|
151
|
+
- `cos` cosine function on single value
|
152
|
+
- `tan` tangent function on single value
|
153
|
+
|
154
|
+
### Sample
|
155
|
+
|
156
|
+
Define filter
|
157
|
+
|
158
|
+
```
|
159
|
+
swizzle = Filter.define [:r,:g,:b], [:r,:g,:b] do
|
160
|
+
copy [:g], :t # copy green to temp
|
161
|
+
copy [:r], :g # copy red to green
|
162
|
+
copy [:b], :r # copy blue to red
|
163
|
+
copy [:t], :b # copy temp (original green) to blue
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
26
167
|
Optionally write filter kernal to binary file on disk
|
27
168
|
|
28
169
|
```ruby
|
29
|
-
ImageFilterDsl::Engine::IO.write("./swizzle.
|
170
|
+
ImageFilterDsl::Engine::IO.write("./swizzle.ifdk", swizzle)
|
30
171
|
```
|
31
172
|
|
32
173
|
Use filter kernal to process image
|
33
174
|
|
34
175
|
```ruby
|
35
|
-
# From binary kernal file
|
36
|
-
processor = ImageFilterDsl::Engine::ImageProcessor.new('./swizzle.ifdk')
|
37
|
-
# OR from filter object
|
38
|
-
processor = ImageFilterDsl::Engine::ImageProcessor.new(swizzle)
|
39
|
-
# or use aliases in main module
|
40
|
-
processor = ImageFilterDsl.image_processor(swizzle)
|
41
|
-
|
42
|
-
# Process image and store output
|
43
|
-
processor.process_image('./my_source.png', './my_output.png')
|
176
|
+
# From binary kernal file
|
177
|
+
processor = ImageFilterDsl::Engine::ImageProcessor.new('./swizzle.ifdk')
|
178
|
+
# OR from filter object
|
179
|
+
processor = ImageFilterDsl::Engine::ImageProcessor.new(swizzle)
|
180
|
+
# or use aliases in main module
|
181
|
+
processor = ImageFilterDsl.image_processor(swizzle)
|
182
|
+
|
183
|
+
# Process image and store output
|
184
|
+
processor.process_image('./my_source.png', './my_output.png')
|
44
185
|
```
|
45
186
|
|
46
|
-
- See `./sample_filters/samples.rb`
|
47
|
-
- See Also: [image_filter_dsl_samples](https://bitbucket.org/WadeH/image_filter_dsl_samples/src/master/) for samples
|
187
|
+
- See `./sample_filters/samples.rb` for sample filters
|
188
|
+
- See Also: [image_filter_dsl_samples](https://bitbucket.org/WadeH/image_filter_dsl_samples/src/master/) for more samples
|
48
189
|
|
49
190
|
## Gem
|
50
191
|
|
51
192
|
Either
|
193
|
+
|
52
194
|
- Build into a gem using included `gemspec` file; includes CLI functionality
|
53
195
|
- Install using gem with `gem install image_filter_dsl`
|
54
196
|
|
197
|
+
## CLI
|
198
|
+
|
199
|
+
Image Filter DSL can be made to process an image from a binary kernal using
|
200
|
+
its CLI tool, `image_filter_dsl`
|
201
|
+
|
202
|
+
- Usage: `image_filter_dsl <kernel_file> <image_in> <image_out>`
|
55
203
|
|
56
204
|
## License
|
57
205
|
|
data/bin/image_filter_dsl
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'image_filter_dsl'
|
4
4
|
|
5
|
-
printf "Image Filter DSL > Process Image\n"
|
6
|
-
if ARGV.length == 0
|
7
|
-
|
8
|
-
else
|
9
|
-
|
10
|
-
end
|
5
|
+
# printf "Image Filter DSL > Process Image\n"
|
6
|
+
# if ARGV.length == 0
|
7
|
+
# printf "Usage: image_filter_dsl <kernel_file> <image_in> <image_out>\n"
|
8
|
+
# else
|
9
|
+
# ImageFilterDsl.cli_process_image(ARGV)
|
10
|
+
# end
|
11
|
+
|
12
|
+
ImageFilterDsl::Engine::CLI.run
|
data/lib/image_filter_dsl.rb
CHANGED
@@ -5,7 +5,8 @@ require_relative './image_filter_dsl/binary/struct.rb'
|
|
5
5
|
require_relative './image_filter_dsl/binary/serialize.rb'
|
6
6
|
require_relative './image_filter_dsl/engine/io.rb'
|
7
7
|
require_relative './image_filter_dsl/engine/image_processor.rb'
|
8
|
-
|
8
|
+
require_relative './image_filter_dsl/serialize.rb'
|
9
|
+
require_relative './image_filter_dsl/engine/cli.rb'
|
9
10
|
##
|
10
11
|
# Image Filter DSL Library
|
11
12
|
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
@@ -3,6 +3,8 @@
|
|
3
3
|
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
4
4
|
# @author Wade H. <vdtdev.prod@gmail.com>
|
5
5
|
module ImageFilterDsl
|
6
|
+
##
|
7
|
+
# Module defining DSL
|
6
8
|
module Dsl
|
7
9
|
##
|
8
10
|
# Module defining filter kernel instruction logic
|
@@ -31,7 +33,17 @@ module ImageFilterDsl
|
|
31
33
|
round: 0xd6,
|
32
34
|
switch: 0xd7,
|
33
35
|
eq: 0xd8,
|
34
|
-
bnot: 0xd9
|
36
|
+
bnot: 0xd9,
|
37
|
+
mix: 0xda,
|
38
|
+
between: 0xdb,
|
39
|
+
clamp: 0xdc,
|
40
|
+
band: 0xdd,
|
41
|
+
bor: 0xde,
|
42
|
+
# generation
|
43
|
+
rand: 0xf0,
|
44
|
+
sin: 0xf1,
|
45
|
+
cos: 0xf2,
|
46
|
+
tan: 0xf3
|
35
47
|
}
|
36
48
|
|
37
49
|
##
|
@@ -113,9 +125,11 @@ module ImageFilterDsl
|
|
113
125
|
|
114
126
|
##
|
115
127
|
# Above instruction
|
116
|
-
# @param [Array] i input values (a,b,trueVal,falseVal)
|
128
|
+
# @param [Array] i input values `(a,b,trueVal,falseVal)`
|
129
|
+
# `trueVal` defaults to `1`, `falseVal` defaults to `0`
|
117
130
|
# @return [Integer|Float] output value
|
118
131
|
def self.above(i)
|
132
|
+
i = [i,1,0].flatten if i.length == 2
|
119
133
|
if(i[0]>i[1])
|
120
134
|
if i.length < 3
|
121
135
|
1
|
@@ -133,9 +147,11 @@ module ImageFilterDsl
|
|
133
147
|
|
134
148
|
##
|
135
149
|
# Below instruction
|
136
|
-
# @param [Array] i input values (a,b,trueVal,falseVal)
|
150
|
+
# @param [Array] i input values `(a,b,trueVal,falseVal)`
|
151
|
+
# `trueVal` defaults to `1`, `falseVal` defaults to `0`
|
137
152
|
# @return [Integer|Float] output value
|
138
153
|
def self.below(i)
|
154
|
+
i = [i,1,0].flatten if i.length == 2
|
139
155
|
if(i[0]<i[1])
|
140
156
|
if i.length < 3
|
141
157
|
1
|
@@ -151,6 +167,28 @@ module ImageFilterDsl
|
|
151
167
|
end
|
152
168
|
end
|
153
169
|
|
170
|
+
##
|
171
|
+
# Between instruction (check if value is between two others)
|
172
|
+
# @param [Array] i input values `[min, max, value, trueVal, falseVal]`
|
173
|
+
# `trueVal` defaults to `1`, `falseVal` defaults to `0`
|
174
|
+
# @return [Integer] 1 if true, 0 if false
|
175
|
+
def self.between(i)
|
176
|
+
i = [i,1,0].flatten if i.length == 3
|
177
|
+
a,b,v,t,f = i
|
178
|
+
r = (v>=a) && (v<=b)
|
179
|
+
(r)? t : f
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# Clamp value between a min and a max
|
184
|
+
# @param [Array] i input values `[min,max,val]`
|
185
|
+
# @return [Integer|Float] Value forced to be no greater than `max`
|
186
|
+
# and no less than `min`
|
187
|
+
def self.clamp(i)
|
188
|
+
a,b,v = i
|
189
|
+
[b,[a,v].max].min
|
190
|
+
end
|
191
|
+
|
154
192
|
##
|
155
193
|
# Floor instruction
|
156
194
|
# @param [Array] i input value (v)
|
@@ -186,7 +224,7 @@ module ImageFilterDsl
|
|
186
224
|
##
|
187
225
|
# 'Switch' instruction (basically if)
|
188
226
|
#
|
189
|
-
# switch
|
227
|
+
# switch condition (0/1/0.0/1.0), trueval, falseval]
|
190
228
|
# @param [Array] i input value (condition, true val, false val)
|
191
229
|
# @return [Integer|Float] output value
|
192
230
|
def self.switch(i)
|
@@ -220,6 +258,65 @@ module ImageFilterDsl
|
|
220
258
|
1
|
221
259
|
end
|
222
260
|
end
|
261
|
+
|
262
|
+
##
|
263
|
+
# Logical AND instruction
|
264
|
+
# @param [Array] i input values (ints or floats)
|
265
|
+
# @return [Integer] 1 if all values are `1` or `1.0`, else 0
|
266
|
+
def self.band(i)
|
267
|
+
(i.reduce(:+).to_i == i.length)? 1 : 0
|
268
|
+
end
|
269
|
+
|
270
|
+
##
|
271
|
+
# Logical OR instruction
|
272
|
+
# @param [Array] i input values (ints or floats)
|
273
|
+
# @return [Integer] 1 if any values are `1` or `1.0`, else 0
|
274
|
+
def self.bor(i)
|
275
|
+
(i.reduce(:+).to_i > 0)? 1 : 0
|
276
|
+
end
|
277
|
+
|
278
|
+
##
|
279
|
+
# Mix two values with a ratio
|
280
|
+
# @param [Array] i input values (ratio (0-1.0), a, b)
|
281
|
+
# @return [Float] output value of ((ratio*a) + ((1.0-ratio)*b))
|
282
|
+
def self.mix(i)
|
283
|
+
ratio, a, b = i
|
284
|
+
(ratio*a)+((1.0-ratio)*b)
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Random number instruction
|
289
|
+
# @param [Array] i input values (min, max)
|
290
|
+
# @return [Float] Random number between min and max
|
291
|
+
def self.rand(i)
|
292
|
+
r=Random.new
|
293
|
+
min,max = i
|
294
|
+
(-min) + (r.rand * (max + min))
|
295
|
+
end
|
296
|
+
|
297
|
+
##
|
298
|
+
# Sine function
|
299
|
+
# @param [Array] i input value to use sin on
|
300
|
+
# @return [Float] Sine of input value
|
301
|
+
def self.sin(i)
|
302
|
+
Math.sin(i[0])
|
303
|
+
end
|
304
|
+
|
305
|
+
##
|
306
|
+
# Cosine function
|
307
|
+
# @param [Array] i input value to use cos on
|
308
|
+
# @return [Float] Cosine of input value
|
309
|
+
def self.cos(i)
|
310
|
+
Math.cos(i[0])
|
311
|
+
end
|
312
|
+
|
313
|
+
##
|
314
|
+
# Tangent function
|
315
|
+
# @param [Array] i input value to use tan on
|
316
|
+
# @return [Float] Tangent of input value
|
317
|
+
def self.tan(i)
|
318
|
+
Math.tan(i[0])
|
319
|
+
end
|
223
320
|
end
|
224
321
|
end
|
225
322
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
##
|
2
|
+
# Image Filter DSL Library
|
3
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
4
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
5
|
+
module ImageFilterDsl
|
6
|
+
module Engine
|
7
|
+
##
|
8
|
+
# CLI Argument parser and handler module
|
9
|
+
module CLI
|
10
|
+
extend self
|
11
|
+
|
12
|
+
Options = Struct.new(:action, :filter, :input, :output)
|
13
|
+
RequiredArgs = {
|
14
|
+
process: [:filter, :input, :output],
|
15
|
+
compile: [:input, :output]
|
16
|
+
}
|
17
|
+
|
18
|
+
def parse(args)
|
19
|
+
opts = Options.new
|
20
|
+
args=args.map{|s|s.strip}
|
21
|
+
|
22
|
+
p = args[0]
|
23
|
+
|
24
|
+
if !p.nil? && p.downcase == '--process'
|
25
|
+
opts.action = :process
|
26
|
+
elsif !p.nil? && p.downcase == '--compile'
|
27
|
+
opts.action = :compile
|
28
|
+
end
|
29
|
+
|
30
|
+
unless opts.action.nil?
|
31
|
+
case opts.action
|
32
|
+
when :process
|
33
|
+
f,i,o = args[1..-1]
|
34
|
+
opts.filter = f
|
35
|
+
opts.input = i
|
36
|
+
opts.output = o
|
37
|
+
when :compile
|
38
|
+
s,k = args[1..-1]
|
39
|
+
opts.input = s
|
40
|
+
opts.output = k
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
return opts
|
45
|
+
end
|
46
|
+
|
47
|
+
def run()
|
48
|
+
options = parse(ARGV)
|
49
|
+
if options.action.nil?
|
50
|
+
show_usage
|
51
|
+
else
|
52
|
+
p options
|
53
|
+
if RequiredArgs[options.action].select{|o| options[o].nil?}.length == 0
|
54
|
+
do_action(options)
|
55
|
+
else
|
56
|
+
show_usage(options.action)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def show_usage(action=nil)
|
62
|
+
if !action.nil?
|
63
|
+
print "Invalid arguments for #{action.to_s}\n"
|
64
|
+
end
|
65
|
+
print [
|
66
|
+
"Usage: image_filter_dsl <action<",
|
67
|
+
"\t--process <kernel_file> <image in> <image out>\t\tProcess image with binary kernel",
|
68
|
+
"\t--compile <source_file> <output_kernel>\t\tCompile given ruby source to binary kernel"
|
69
|
+
].join("\n")
|
70
|
+
print "\n"
|
71
|
+
end
|
72
|
+
|
73
|
+
def do_action(opts)
|
74
|
+
if opts.action == :process
|
75
|
+
ip = ImageFilterDsl.image_processor(opts.filter)
|
76
|
+
ip.process_image(opts.input, opts.output)
|
77
|
+
elsif opts.action == :compile
|
78
|
+
print "(Not yet implemented :)\n"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -13,6 +13,8 @@ module ImageFilterDsl
|
|
13
13
|
|
14
14
|
attr_accessor :kernel, :config
|
15
15
|
|
16
|
+
|
17
|
+
|
16
18
|
##
|
17
19
|
# Constructor
|
18
20
|
# @param [Dsl::Kernel::FilterKernel|String] filter_kernel FilterKernel object or path to binary kernel file
|
@@ -121,7 +123,6 @@ module ImageFilterDsl
|
|
121
123
|
b = clr.b(pixel)
|
122
124
|
a = clr.a(pixel)
|
123
125
|
|
124
|
-
|
125
126
|
inputs = Hash[*@kernel.inputs.map{|k|[k,0]}.flatten]
|
126
127
|
inputs[:x] = x if inputs.keys.include?(:x)
|
127
128
|
inputs[:y] = y if inputs.keys.include?(:y)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative './serializers/common.rb'
|
2
|
+
require_relative './serializers/msg_pack.rb'
|
3
|
+
require_relative './serializers/json.rb'
|
4
|
+
require_relative './serializers/yaml.rb'
|
5
|
+
require_relative './serializers/intermediate.rb'
|
6
|
+
##
|
7
|
+
# Image Filter DSL Library
|
8
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
9
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
10
|
+
module ImageFilterDsl
|
11
|
+
##
|
12
|
+
# Module providing access to kernel serialization and
|
13
|
+
# deserialization functionality. Actual serialization/deserialization
|
14
|
+
# logic defined in modules within `Serializers`
|
15
|
+
module Serialize
|
16
|
+
extend self
|
17
|
+
# include Serialize::Json
|
18
|
+
# include Serializers::Json
|
19
|
+
|
20
|
+
##
|
21
|
+
# Intermediate serializer module
|
22
|
+
INTERMEDIATE = Serializers::Intermediate
|
23
|
+
|
24
|
+
##
|
25
|
+
# Available serializers, mapping format symbol to
|
26
|
+
# module
|
27
|
+
SERIALIZERS = {
|
28
|
+
json: Serializers::Json,
|
29
|
+
msgpack: Serializers::MsgPack,
|
30
|
+
yaml: Serializers::Yaml
|
31
|
+
}
|
32
|
+
##
|
33
|
+
# Available serializer symbols
|
34
|
+
FORMATS = SERIALIZERS.keys
|
35
|
+
|
36
|
+
##
|
37
|
+
# Serialize kernel, optionally using intermediate step
|
38
|
+
# @param [ImageFilterDsl::Dsl::Kernel] kernel Kernel
|
39
|
+
# @param [Symbol] format Format to serialize to from FORMATS, or
|
40
|
+
# `nil` to convert to intermediate
|
41
|
+
# @return [Hash|String] serialized kernel
|
42
|
+
def from_kernel(kernel, format=nil)
|
43
|
+
i = INTERMEDIATE.from_kernel(kernel)
|
44
|
+
if format.nil?
|
45
|
+
return i
|
46
|
+
else
|
47
|
+
m = SERIALIZERS[format]
|
48
|
+
return m.send(:serialize, i)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Deserialize to kernel, optionally using intermediate step
|
54
|
+
# @param [Hash|String] data Serialized data
|
55
|
+
# @param [Symbol] format Format to convert from from FORMATS, or
|
56
|
+
# `nil` to convert from intermediate
|
57
|
+
# @return [Kernel] Kernal from deserialization
|
58
|
+
def to_kernel(data,format=nil)
|
59
|
+
if format.nil?
|
60
|
+
return INTERMEDIATE.to_kernel(data)
|
61
|
+
else
|
62
|
+
i = SERIALIZERS[format].send(:deserialize, data)
|
63
|
+
return INTERMEDIATE.to_kernel(i)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# Image Filter DSL Library
|
3
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
4
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
5
|
+
module ImageFilterDsl
|
6
|
+
module Serializers
|
7
|
+
##
|
8
|
+
# Common helper methods for serializers; Include in serializer modules
|
9
|
+
# with `include Common`
|
10
|
+
module Common
|
11
|
+
extend self
|
12
|
+
##
|
13
|
+
# Normalize symbol/value, stripping out
|
14
|
+
# any colons and converting to symbol; Non strings
|
15
|
+
# are returned unaltered; if array, logic is applied to all items
|
16
|
+
# @param [String|Number|Symbol|Array] val
|
17
|
+
# @return [Symbol|Number|Array] Normalized value
|
18
|
+
def normalize_sym(val)
|
19
|
+
if val.is_a?(String)
|
20
|
+
val.gsub(':','').to_sym
|
21
|
+
elsif val.is_a?(Array)
|
22
|
+
val.map{|v|normalize_sym(v)}
|
23
|
+
else
|
24
|
+
val
|
25
|
+
end
|
26
|
+
end
|
27
|
+
##
|
28
|
+
# 'Fix' hash, converting keys to symbols (if keys provided)
|
29
|
+
# and converting values/arrays of values so any strings are
|
30
|
+
# normalized and cast to symbols using {normalize_sym}
|
31
|
+
# @param [Hash] hash Hash to fix
|
32
|
+
# @param [Array] keys Optional array of key symbols to check for and
|
33
|
+
# convert string equivalents over to symbols if found
|
34
|
+
# @return [Hash] Fixed copy of input hash
|
35
|
+
def fix_hash(hash,keys=[])
|
36
|
+
h2=hash.dup
|
37
|
+
unless keys.length == 0
|
38
|
+
keys.each do |k|
|
39
|
+
if !h2.has_key?(k) && h2.has_key?(k.to_s)
|
40
|
+
h2[k] = h2[k.to_s]
|
41
|
+
h2.delete k.to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
h2.keys.each do |k|
|
46
|
+
if h2[k].is_a?(Array)
|
47
|
+
h2[k] = h2[k].map{|v|normalize_sym(v)}
|
48
|
+
else
|
49
|
+
h2[k] = normalize_sym(h2[k])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return h2
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
##
|
2
|
+
# Image Filter DSL Library
|
3
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
4
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
5
|
+
module ImageFilterDsl
|
6
|
+
##
|
7
|
+
# Kernel data serializers
|
8
|
+
module Serializers
|
9
|
+
##
|
10
|
+
# Provides serialization/deserialization for Kernels
|
11
|
+
# to an intermediate format representing kernel as hash.
|
12
|
+
# Used by other serializers as intermediate between serializing
|
13
|
+
# from and deserializing to kernels
|
14
|
+
module Intermediate
|
15
|
+
include Common
|
16
|
+
extend self
|
17
|
+
##
|
18
|
+
# Convert kernel to intermediate hash struct
|
19
|
+
# @param [ImageFilterDsl::Dsl::Kernel] kernel Source kernel
|
20
|
+
# @return [Hash] Intermediate hash version of kernel
|
21
|
+
def from_kernel(kernel)
|
22
|
+
data = {
|
23
|
+
inputs: kernel.inputs,
|
24
|
+
outputs: kernel.outputs
|
25
|
+
}
|
26
|
+
data[:instructions] = kernel.instructions.map do |i|
|
27
|
+
{op: i.op, in: i.inputs, out: i.out}
|
28
|
+
end
|
29
|
+
data
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Convert intermediate kernel hash to kernel object
|
34
|
+
# @param [Hash] data Intermediate kernel data
|
35
|
+
# @return [ImageFilterDsl::Dsl::Kernel] Constructed kernel
|
36
|
+
def to_kernel(data)
|
37
|
+
ins = data[:instructions].map{|i| fix_instruction_symbols(i) }
|
38
|
+
filt = ImageFilterDsl::Dsl::Filter.define(data[:inputs],data[:outputs]) do
|
39
|
+
ins.each do |i|
|
40
|
+
send(i[:op], i[:in], i[:out])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
return filt
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def fix_instruction_symbols(ins_hash)
|
49
|
+
fix_hash(ins_hash,[:op,:in,:out])
|
50
|
+
# r_k=Proc.new {|k| (ins_hash.has_key?(k))? k : k.to_s}
|
51
|
+
# op_h = r_k.call(:op)
|
52
|
+
# in_h = r_k.call(:in)
|
53
|
+
# out_h = r_k.call(:out)
|
54
|
+
# norm_sym = Proc.new {|s| (s.is_a?(String))? s.gsub(':','').to_sym : s}
|
55
|
+
# {
|
56
|
+
# op: norm_sym.call(ins_hash[op_h]),
|
57
|
+
# in: ins_hash[in_h].map { |i|
|
58
|
+
# norm_sym.call(i)
|
59
|
+
# },
|
60
|
+
# out: norm_sym.call(ins_hash[out_h])
|
61
|
+
# }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json'
|
2
|
+
##
|
3
|
+
# Image Filter DSL Library
|
4
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
5
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
6
|
+
module ImageFilterDsl
|
7
|
+
module Serializers
|
8
|
+
##
|
9
|
+
# Provides serialization/deserialization to/from JSON using
|
10
|
+
# intermediate serializer
|
11
|
+
module Json
|
12
|
+
include Common
|
13
|
+
extend self
|
14
|
+
##
|
15
|
+
# Serialize kernel to JSON string
|
16
|
+
# @param [Hash] kernel Kernel in intermediate format
|
17
|
+
# @return [String] JSON serialized version of kernel
|
18
|
+
def serialize(kernel)
|
19
|
+
{
|
20
|
+
header: ImageFilterDsl::Binary::Struct::HEADER_VALUES,
|
21
|
+
inputs: kernel[:inputs],
|
22
|
+
outputs: kernel[:outputs],
|
23
|
+
instructions: kernel[:instructions]
|
24
|
+
}.to_json
|
25
|
+
end
|
26
|
+
##
|
27
|
+
# Deserialize JSON kernel to intermediate format
|
28
|
+
# @param [String] data JSON kernel data
|
29
|
+
# @return [Hash] Intermediate format of kernel data
|
30
|
+
def deserialize(data)
|
31
|
+
data = JSON.load(data)
|
32
|
+
data = fix_hash(data,[:inputs,:outputs,:instructions])
|
33
|
+
data[:instructions] = data[:instructions].map {|i| fix_hash(i,[:op,:in,:out])}
|
34
|
+
|
35
|
+
{
|
36
|
+
inputs: data[:inputs],
|
37
|
+
outputs: data[:outputs],
|
38
|
+
instructions: data[:instructions]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'msgpack'
|
2
|
+
##
|
3
|
+
# Image Filter DSL Library
|
4
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
5
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
6
|
+
module ImageFilterDsl
|
7
|
+
module Serializers
|
8
|
+
##
|
9
|
+
# Provides serialization/deserialization to/from MessagePack strings
|
10
|
+
# using intermediate serializer
|
11
|
+
module MsgPack
|
12
|
+
include Common
|
13
|
+
extend self
|
14
|
+
##
|
15
|
+
# 'Header' added to start of array packed with MsgPack
|
16
|
+
HEADER = ['mp',ImageFilterDsl::Binary::Struct::HEADER_VALUES.values].flatten
|
17
|
+
##
|
18
|
+
# Serialize kernel to MessagePack string
|
19
|
+
# @param [Hash] kernel Kernel in intermediate format
|
20
|
+
# @return [String] MessagePack serialized version of kernel
|
21
|
+
def serialize(kernel)
|
22
|
+
[
|
23
|
+
HEADER,
|
24
|
+
kernel[:inputs],
|
25
|
+
kernel[:outputs],
|
26
|
+
kernel[:instructions].map do |i|
|
27
|
+
[i[:op],i[:in],i[:out]]
|
28
|
+
end
|
29
|
+
].to_msgpack
|
30
|
+
end
|
31
|
+
##
|
32
|
+
# Deserialize MessagePack kernel to intermediate format
|
33
|
+
# @param [String] data MessagePack kernel data
|
34
|
+
# @return [Hash] Intermediate format of kernel data
|
35
|
+
def deserialize(data)
|
36
|
+
data = MessagePack.unpack(data)
|
37
|
+
head,inps,outs,ins=data
|
38
|
+
d = {
|
39
|
+
inputs: normalize_sym(inps),
|
40
|
+
outputs: normalize_sym(outs),
|
41
|
+
instructions: ins.map do |i|
|
42
|
+
op,iin,iout=i
|
43
|
+
fix_hash({op: op, in: iin, out: iout})
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
return d
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
##
|
3
|
+
# Image Filter DSL Library
|
4
|
+
# (c) 2018-2020 VDTDEV/Wade H. ~ MIT License
|
5
|
+
# @author Wade H. <vdtdev.prod@gmail.com>
|
6
|
+
module ImageFilterDsl
|
7
|
+
module Serializers
|
8
|
+
##
|
9
|
+
# Provides serialization/deserialization to/from YAML using
|
10
|
+
# intermediate serializer
|
11
|
+
module Yaml
|
12
|
+
include Common
|
13
|
+
extend self
|
14
|
+
##
|
15
|
+
# Serialize kernel to YAML string
|
16
|
+
# @param [Hash] kernel Kernel in intermediate format
|
17
|
+
# @return [String] YAML serialized version of kernel
|
18
|
+
def serialize(kernel)
|
19
|
+
{
|
20
|
+
header: ImageFilterDsl::Binary::Struct::HEADER_VALUES,
|
21
|
+
inputs: kernel[:inputs],
|
22
|
+
outputs: kernel[:outputs],
|
23
|
+
instructions: kernel[:instructions]
|
24
|
+
}.to_yaml
|
25
|
+
end
|
26
|
+
##
|
27
|
+
# Deserialize YAML kernel to intermediate format
|
28
|
+
# @param [String] data YAML kernel data
|
29
|
+
# @return [Hash] Intermediate format of kernel data
|
30
|
+
def deserialize(data)
|
31
|
+
data = YAML.load(data)
|
32
|
+
data = fix_hash(data,[:inputs,:outputs,:instructions])
|
33
|
+
data[:instructions] = data[:instructions].map {|i| fix_hash(i,[:op,:in,:out])}
|
34
|
+
{
|
35
|
+
inputs: data[:inputs],
|
36
|
+
outputs: data[:outputs],
|
37
|
+
instructions: data[:instructions]
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_filter_dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wade H.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chunky_png
|
@@ -89,13 +89,21 @@ files:
|
|
89
89
|
- lib/image_filter_dsl/dsl/filter.rb
|
90
90
|
- lib/image_filter_dsl/dsl/filter_instructions.rb
|
91
91
|
- lib/image_filter_dsl/dsl/kernel.rb
|
92
|
+
- lib/image_filter_dsl/engine/cli.rb
|
92
93
|
- lib/image_filter_dsl/engine/image_processor.rb
|
93
94
|
- lib/image_filter_dsl/engine/io.rb
|
95
|
+
- lib/image_filter_dsl/serialize.rb
|
96
|
+
- lib/image_filter_dsl/serializers/common.rb
|
97
|
+
- lib/image_filter_dsl/serializers/intermediate.rb
|
98
|
+
- lib/image_filter_dsl/serializers/json.rb
|
99
|
+
- lib/image_filter_dsl/serializers/msg_pack.rb
|
100
|
+
- lib/image_filter_dsl/serializers/yaml.rb
|
94
101
|
homepage: https://bitbucket.org/WadeH/image_filter_dsl
|
95
102
|
licenses:
|
96
103
|
- MIT
|
97
104
|
metadata:
|
98
105
|
source_code_uri: https://bitbucket.org/WadeH/image_filter_dsl
|
106
|
+
documentation_uri: https://rubydoc.info/gems/image_filter_dsl/0.1.1
|
99
107
|
post_install_message:
|
100
108
|
rdoc_options: []
|
101
109
|
require_paths:
|
@@ -111,8 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
119
|
- !ruby/object:Gem::Version
|
112
120
|
version: '0'
|
113
121
|
requirements: []
|
114
|
-
|
115
|
-
rubygems_version: 2.7.8
|
122
|
+
rubygems_version: 3.0.0
|
116
123
|
signing_key:
|
117
124
|
specification_version: 4
|
118
125
|
summary: Image Filter DSL
|