curver 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.
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: []