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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c683878731b0e51f247aff3462f53272a04c13e4c31fbbf1daa14e9ec606f235
4
- data.tar.gz: 606bc6208d106f867700b051bb73c917fc55d9985e8df0071e882a90e644f4db
3
+ metadata.gz: b3c5ec517d5379d54dcac83356f816f4e460ea651956600c4a406766483fff9e
4
+ data.tar.gz: a26273761002413d8f2944fce7c6d9da591a3b3124be8a640f9c375a029df739
5
5
  SHA512:
6
- metadata.gz: 88a3935892903034fdef3c0d1e1065d3886a5b6d636b6f46d693cb53fc2a7409cb151bda74ae15b83c39f7dd850a126d83c737da55204262a1592000f9294d55
7
- data.tar.gz: 43cbfb2c910938575dbc1a83835e454d0ff1f61000a8f1a8d93247a10fb0b6fa6e2f9288f86a49e4f338a59264e498f513d316957aa693f8b6e543f673cf69db
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
  [![Gem Version](https://badge.fury.io/rb/image_filter_dsl.svg)](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
- ### Sample
15
+ ## DSL
14
16
 
15
- Define filter
17
+ ### Filter Block
18
+
19
+ Using `ImageFilterDsl::Dsl::Filter`
16
20
 
17
21
  ```ruby
18
- swizzle = Filter.define [:r,:g,:b], [:r,:g,:b] do
19
- copy [:g], :t # copy green to temp
20
- copy [:r], :g # copy red to green
21
- copy [:b], :r # copy blue to red
22
- copy [:t], :b # copy temp (original green) to blue
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.ifdkk", 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
 
@@ -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
- printf "Usage: image_filter_dsl <kernel_file> <image_in> <image_out>\n"
8
- else
9
- ImageFilterDsl.cli_process_image(ARGV)
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
@@ -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
@@ -22,7 +22,7 @@ module ImageFilterDsl
22
22
  # Constants used in header
23
23
  HEADER_VALUES = {
24
24
  header: "ifdKernel",
25
- version: 0.01
25
+ version: 0.02
26
26
  }
27
27
 
28
28
  ##
@@ -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 [condition (0/1/0.0/1.0), trueval, falseval]
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.0.3
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-02-02 00:00:00.000000000 Z
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
- rubyforge_project:
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