curver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/curver.rb +117 -0
  3. metadata +72 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0d2f16eded28fa62e404d2778e35e03d7df8221
4
+ data.tar.gz: 870b378f36bffb0f860d47d91354ed1bcf450715
5
+ SHA512:
6
+ metadata.gz: 23a59224793b557fd55981ebc3cb8231ab8b41106e494467f36c0a8212d0170b8ff79fe3da230324d51a2a60457027b350a6c0f57c5569f2479ae7af7b87e47c
7
+ data.tar.gz: c392c98a634bcbf028e78416c7550c46a5f96e5eec83d19217c2895ab8dc1289be29019bf306b33ee8932dd6bed47c19e7d036f3225ef660d9f504c7333fdeef
data/lib/curver.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'spliner'
2
+ require 'matrix'
3
+ require 'fileutils'
4
+
5
+ class Curver
6
+
7
+ attr_reader :acv_file_path
8
+
9
+ CHANNELS = [:rgb, :r, :g, :b]
10
+
11
+ IndexReader = Struct.new(:position)
12
+ MultiChannelCurve = Struct.new(*CHANNELS)
13
+
14
+ ChannelCurve = Struct.new(:points) do
15
+
16
+ def range
17
+ @range ||= Curver.range(self.points)
18
+ end
19
+
20
+ def polynom
21
+ @polynom ||= Curver.compute_polynom(points, range)
22
+ end
23
+
24
+ end
25
+
26
+ def initialize(acv_file_path)
27
+ raise "No file at this path" unless File.exist?(acv_file_path)
28
+ self.class.set_default_values
29
+ @acv_file_path = acv_file_path
30
+ end
31
+
32
+ def curves
33
+ @curves ||= self.class.read_curves(acv_file_path)
34
+ end
35
+
36
+ def polynoms
37
+ CHANNELS.reduce({}) do |h, channel|
38
+ h[channel] = curves[channel].polynom
39
+ h
40
+ end
41
+ end
42
+
43
+ def export_image(original_path, export_base_name)
44
+ self.class.export_image(curves, original_path, export_base_name)
45
+ end
46
+
47
+ def puts_polynoms
48
+ puts "Polynoms (x^0 -> x^n) ---"
49
+ puts polynoms
50
+ puts "---"
51
+ end
52
+
53
+ class << self
54
+
55
+ attr_accessor :polynom_degree, :max_value, :range_size, :polynom_precision
56
+
57
+ def set_default_values
58
+ self.polynom_degree ||= 6
59
+ self.max_value ||= 255
60
+ self.range_size ||= 255
61
+ self.polynom_precision ||= 3
62
+ end
63
+
64
+ def read_curves file_path
65
+ ary = File.read(file_path, encode: 'binary').unpack('S>*')
66
+ multi_channel_curve(ary)
67
+ end
68
+
69
+ def multi_channel_curve ary
70
+ ir = IndexReader.new(2)
71
+ channels_points = CHANNELS.map { |k| sanitize_points read_array!(ary, ir) }
72
+ channels_curves = channels_points.map{ |points| ChannelCurve.new(points) }
73
+ MultiChannelCurve.new(*channels_curves)
74
+ end
75
+
76
+ def compute_polynom points, range
77
+ values = spline_values(points, range)
78
+ polynom(range, values)
79
+ end
80
+
81
+ def sanitize_points array
82
+ ary = (array.length / 2).times.map{|i| [array[2*i+1], array[2*i]]}
83
+ ary.map{ |dot| dot.map{ |v| v / max_value.to_f } }
84
+ end
85
+
86
+ def read_array! array, index_reader
87
+ ary = array.drop(index_reader.position)
88
+ raise 'Wrong index reader position' if ary.empty?
89
+ points_count = (ary.first * 2)
90
+ index_reader.position += points_count + 1
91
+ ary[1..points_count]
92
+ end
93
+
94
+ def polynom x, y
95
+ x_data = x.map { |xi| (0..polynom_degree).map { |pow| (xi**pow).to_f } }
96
+ mx = Matrix[*x_data]
97
+ my = Matrix.column_vector(y)
98
+ ((mx.t * mx).inv * mx.t * my).transpose.to_a[0].map{|e| truncate(e, polynom_precision) }
99
+ end
100
+
101
+ def truncate i, length
102
+ (i * (10 ** length)).to_i.to_f / (10 ** length)
103
+ end
104
+
105
+ def spline_values(coords, range)
106
+ spline = Spliner::Spliner.new coords.map(&:first), coords.map(&:last)
107
+ spline[range]
108
+ end
109
+
110
+ def range coords
111
+ min_value, max_value = coords.first.first, coords.last.first
112
+ (min_value..max_value).step((max_value - min_value)/range_size).to_a
113
+ end
114
+
115
+ end
116
+
117
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: curver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Théo CARRIVE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: spliner
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.5'
41
+ description: Convert your Adobe curves files to polynom functions
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/curver.rb
48
+ homepage:
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.5.1
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Curver
72
+ test_files: []