ase-palette 0.9.0 → 0.9.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: fefbb045aba878667c779f8cf8a72f21c9c91f919efad22a436bc27594a22a0d
4
- data.tar.gz: 7bbc45674d4344377fbdda0057fbb0b174c2f9eca06d7c495b50a59889e172cb
3
+ metadata.gz: 6361e025b4781e0cacb4f6f8b8f52b0d4b11d489468f06496b0f92c9dc11c9bb
4
+ data.tar.gz: 99807b55893ef200819ceb4b2cac53b1321cf99bcdab52d4c0e0680c9a825439
5
5
  SHA512:
6
- metadata.gz: e25b1c71ae0192350717faf8fe00cd438ba999cf27f8b70b9ca11547d9d3f103452c426b3fd02c132ef2cd5a9efd5e0db5e33061fef3a287b5a4d43d8a218a3c
7
- data.tar.gz: 3a3de6e42b122ceb0f9c5db2f7c0c35e285e67af4e96e85645b56b56c57395c4e26f6b4ea9c5c181677de4a493186921acebb1ace0a81698d1f95393c0ce0471
6
+ metadata.gz: 6409fcfa09189d3a50274ef25d4d179fa624b768329b2ef91da7977d9cd006255536b82ff4a2225bd8de18205328a3031666fb82d7a586c8e469d5c9f8245080
7
+ data.tar.gz: 76a1cf7733d883941f868a26eeb2b7bbb198b838ab1dc5e35c976533a9460a867f259dd438b1c5701be0379edc3c191fb09c4d35557cfdb3fc0faab17522e9c9
@@ -1,4 +1,7 @@
1
1
  # Changelog
2
2
 
3
+ `0.9.1`
4
+ - Add ability to read ASE files
5
+
3
6
  `0.9.0`
4
7
  - Initial beta version of gem
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ase-palette (0.9.0)
4
+ ase-palette (0.9.1)
5
5
  bindata (~> 2.4.4)
6
6
  hex_string (~> 1.0.1)
7
7
 
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # ASEPalette
2
2
 
3
+ [<img src="https://img.shields.io/gem/v/ase-palette.svg?color=g" />](https://rubygems.org/gems/ase-palette)
4
+ [<img src="https://img.shields.io/gem/dt/ase-palette.svg?color=g" />](https://rubygems.org/gems/ase-palette)
5
+
6
+ Create and manage Adobe ASE color palettes in Ruby.
7
+
3
8
  ## Installation
4
9
 
5
10
  Add this line to your application's Gemfile:
@@ -8,14 +13,6 @@ Add this line to your application's Gemfile:
8
13
  gem 'ase-palette'
9
14
  ```
10
15
 
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install ase-palette
18
-
19
16
  ## Usage
20
17
 
21
18
  ### Load
@@ -86,17 +83,13 @@ respond_to do |format|
86
83
  end
87
84
  ```
88
85
 
89
- ### Import [UNDER DEVELOPMENT]
86
+ ### Import
90
87
 
91
88
  ```ruby
92
89
  # Open palette from file
93
- palette = ASEPalette.open('path/to/palette.ase')
94
-
95
- # Access color
96
- puts palette.color_with_name "Red"
97
- # Red, RGB: 255/0/0, :global
90
+ palette = ASEPalette.open 'path/to/palette.ase'
98
91
 
99
- # Access palette
92
+ # Access palette colors
100
93
  puts palette
101
94
  # ASEPalette 2.0
102
95
  # --------------
@@ -13,4 +13,8 @@ module ASEPalette
13
13
  def self.new
14
14
  Palette.new
15
15
  end
16
+
17
+ def self.open(path)
18
+ Palette.new(path)
19
+ end
16
20
  end
@@ -1,15 +1,17 @@
1
1
  module ASEPalette
2
2
  class Palette
3
3
  # TODO: Consider removing 'with_name' from method signatures
4
- # TODO: Make sure to encode strings back to UTF-8 when importing ASE files
5
- # TODO: Check case-sensitivity of the ASE spec for color and group names
6
4
 
7
5
  # Initialize palette
8
- def initialize
6
+ def initialize(path = nil)
9
7
  @version_major = 1
10
8
  @version_minor = 0
11
9
  @colors = []
12
10
  @groups = []
11
+ if path
12
+ palette_hash = PaletteBinary.build_binary_hash_from_file(path)
13
+ initialize_values_from_palette_hash(palette_hash)
14
+ end
13
15
  end
14
16
 
15
17
  # Get palette version
@@ -35,7 +37,7 @@ module ASEPalette
35
37
 
36
38
  # Get color by name
37
39
  def color_with_name(name)
38
- found_colors = all_colors.select { |c| c.name == name }
40
+ found_colors = all_colors.select { |color| color.name == name }
39
41
  found_colors.length >= 1 ? found_colors[0] : nil
40
42
  end
41
43
 
@@ -46,7 +48,7 @@ module ASEPalette
46
48
 
47
49
  # Get read-only group by name
48
50
  def group_with_name(name)
49
- found_groups = @groups.select { |g| g.name == name }
51
+ found_groups = @groups.select { |group| group.name == name }
50
52
  found_groups.length >= 1 ? found_groups[0].clone : nil
51
53
  end
52
54
 
@@ -56,7 +58,7 @@ module ASEPalette
56
58
  # Returns true if color is added
57
59
  def add_color(color, group_name: nil)
58
60
  if color.is_a? Color
59
- if color_does_not_exist_in_palette(color.name)
61
+ if color_does_not_exist(color.name)
60
62
  if group_name
61
63
  group = find_or_create_group(group_name)
62
64
  group.colors << color
@@ -76,7 +78,7 @@ module ASEPalette
76
78
  # Create empty group in palette
77
79
  # Returns true if group is created
78
80
  def create_group(name)
79
- if @groups.select { |group| group.name == name }.length == 0
81
+ if group_does_not_exist(name)
80
82
  @groups << ASEPalette::Group.new(name)
81
83
  true
82
84
  else
@@ -116,20 +118,22 @@ module ASEPalette
116
118
  s += "This palette is empty\n"
117
119
  end
118
120
  s += divider
119
- s += "#{all_colors.length} color#{if all_colors.length != 1 then "s" end}, " \
120
- "#{@groups.length} group#{if @groups.length != 1 then "s" end}"
121
+ s += "#{all_colors.length} " \
122
+ "color#{if all_colors.length != 1 then "s" end}, " \
123
+ "#{@groups.length} " \
124
+ "group#{if @groups.length != 1 then "s" end}"
121
125
  s
122
126
  end
123
127
 
124
128
  # Create binary representation of palette
125
129
  def to_binary
126
- palette = PaletteBinary.build_binary_palette(
130
+ binary_palette = PaletteBinary.build_binary_palette(
127
131
  @colors.map(&:to_h),
128
132
  @groups.map(&:to_h),
129
133
  @version_major,
130
134
  @version_minor,
131
135
  )
132
- palette.to_binary_s
136
+ binary_palette.to_binary_s
133
137
  end
134
138
 
135
139
  # Create human-readable hex representation of palette
@@ -139,6 +143,46 @@ module ASEPalette
139
143
 
140
144
  private
141
145
 
146
+ # Set palette values from binary-derived hash
147
+ # Used to populate a Palette from an ASE file
148
+ def initialize_values_from_palette_hash(palette_hash)
149
+ @version_major = palette_hash[:version_major]
150
+ @version_minor = palette_hash[:version_minor]
151
+ palette_hash[:colors].each do |color|
152
+ add_color(color_from_hash(color))
153
+ end
154
+ palette_hash[:groups].each do |group|
155
+ group[:colors].each do |color|
156
+ add_color(color_from_hash(color), group_name: group[:name])
157
+ end
158
+ end
159
+ end
160
+
161
+ # Create Color object from binary-derived hash
162
+ # Used to populate a Palette from an ASE file
163
+ def color_from_hash(color)
164
+ case color[:model]
165
+ when :rgb
166
+ Color::RGB.new(
167
+ color[:name],
168
+ *color[:data].values,
169
+ color[:type],
170
+ )
171
+ when :cmyk
172
+ Color::CMYK.new(
173
+ color[:name],
174
+ *color[:data].values,
175
+ color[:type],
176
+ )
177
+ when :lab
178
+ Color::LAB.new(
179
+ color[:name],
180
+ *color[:data].values,
181
+ color[:type],
182
+ )
183
+ end
184
+ end
185
+
142
186
  # Returns an array of all colors in the palette,
143
187
  # including those in groups
144
188
  def all_colors
@@ -147,10 +191,15 @@ module ASEPalette
147
191
 
148
192
  # Determines whether or not a color exists in the palette,
149
193
  # including those in groups
150
- def color_does_not_exist_in_palette(name)
194
+ def color_does_not_exist(name)
151
195
  all_colors.select { |color| color.name == name }.length == 0
152
196
  end
153
197
 
198
+ # Determines whether or not a group exists in the palette
199
+ def group_does_not_exist(name)
200
+ @groups.select { |group| group.name == name }.length == 0
201
+ end
202
+
154
203
  # Returns a found or created group
155
204
  def find_or_create_group(name)
156
205
  found_groups = @groups.select { |group| group.name == name }
@@ -21,12 +21,12 @@ module ASEPalette
21
21
  class ASEBinData < BinData::Record
22
22
  endian :big
23
23
 
24
- string :signature, value: "ASEF"
24
+ string :signature, value: "ASEF", read_length: 4
25
25
  uint16 :version_major, initial_value: DEFAULT_VERSION_MAJOR
26
26
  uint16 :version_minor, initial_value: DEFAULT_VERSION_MINOR
27
27
  uint32 :block_count, value: -> { blocks.length }
28
28
 
29
- array :blocks do
29
+ array :blocks, initial_length: -> { block_count } do
30
30
  uint16 :block_type
31
31
  uint32 :block_length, value: -> {
32
32
  block_length = 0
@@ -53,7 +53,7 @@ module ASEPalette
53
53
  class BlockGroupStart < BinData::Record
54
54
  endian :big
55
55
  uint16 :name_length, value: -> { name.length / 2 + 1 }
56
- string :name, read_length: :name_length
56
+ string :name, read_length: -> { (name_length - 1) * 2 }
57
57
  uint16 :null_padding, value: 0
58
58
  end
59
59
  class BlockGroupEnd < BinData::Record
@@ -61,9 +61,9 @@ module ASEPalette
61
61
  class BlockColor < BinData::Record
62
62
  endian :big
63
63
  uint16 :name_length, value: -> { name.length / 2 + 1 }
64
- string :name, read_length: :name_length
64
+ string :name, read_length: -> { (name_length - 1) * 2 }
65
65
  uint16 :null_padding, value: 0
66
- string :color_model, initial_value: COLOR_MODEL_DEFAULT
66
+ string :color_model, read_length: 4
67
67
  choice :color_data, selection: -> { color_model } do
68
68
  class ColorDataRGB < BinData::Record
69
69
  endian :big
@@ -134,6 +134,12 @@ module ASEPalette
134
134
  palette
135
135
  end
136
136
 
137
+ def self.build_binary_hash_from_file(path)
138
+ file = File.open(path)
139
+ binary = ASEBinData.read(file)
140
+ binary_to_hash(binary)
141
+ end
142
+
137
143
  private
138
144
 
139
145
  def self.binary_add_color(palette, name, model, type, data)
@@ -206,5 +212,78 @@ module ASEPalette
206
212
  block_type: BLOCK_TYPE_GROUP_END,
207
213
  })
208
214
  end
215
+
216
+ def self.binary_to_hash(binary)
217
+ palette = {
218
+ version_major: binary.version_major,
219
+ version_minor: binary.version_minor,
220
+ colors: [],
221
+ groups: [],
222
+ }
223
+
224
+ current_group = nil
225
+ binary.blocks.each do |block|
226
+ block_type = block[:block_type]
227
+ block_data = block[:block_data]
228
+ if block_type == BLOCK_TYPE_COLOR || block_type == BLOCK_TYPE_GROUP_START
229
+ block_name = block_data[:name].force_encoding(Encoding::UTF_16BE).encode(Encoding::UTF_8)
230
+ end
231
+ if block_type == BLOCK_TYPE_COLOR
232
+ color = { name: block_name }
233
+
234
+ color_data = block_data[:color_data]
235
+
236
+ case block_data[:color_model]
237
+ when COLOR_MODEL_RGB
238
+ color[:model] = :rgb
239
+ color[:data] = {
240
+ r: (color_data[:red] * 255.0).round,
241
+ g: (color_data[:green] * 255.0).round,
242
+ b: (color_data[:blue] * 255.0).round,
243
+ }
244
+ when COLOR_MODEL_CMYK, COLOR_MODEL_GRAY
245
+ color[:model] = :cmyk
246
+ color[:data] = {
247
+ c: (color_data[:cyan] * 100.0).round,
248
+ m: (color_data[:magenta] * 100.0).round,
249
+ y: (color_data[:yellow] * 100.0).round,
250
+ k: (color_data[:black] * 100.0).round,
251
+ }
252
+ when COLOR_MODEL_LAB
253
+ color[:model] = :lab
254
+ color[:data] = {
255
+ l: (color_data[:lightness] * 100.0).round,
256
+ a: (color_data[:a]).round,
257
+ b: (color_data[:b]).round,
258
+ }
259
+ end
260
+
261
+ case block_data[:color_type]
262
+ when COLOR_TYPE_GLOBAL
263
+ color[:type] = :global
264
+ when COLOR_TYPE_SPOT
265
+ color[:type] = :spot
266
+ when COLOR_TYPE_NORMAL
267
+ color[:type] = :normal
268
+ end
269
+
270
+ if current_group
271
+ current_group[:colors] << color
272
+ else
273
+ palette[:colors] << color
274
+ end
275
+ elsif block_type == BLOCK_TYPE_GROUP_START
276
+ current_group = {
277
+ name: block_name,
278
+ colors: []
279
+ }
280
+ palette[:groups] << current_group
281
+ elsif block_type == BLOCK_TYPE_GROUP_END
282
+ current_group = nil
283
+ end
284
+ end
285
+
286
+ palette
287
+ end
209
288
  end
210
289
  end
@@ -1,3 +1,3 @@
1
1
  module ASEPalette
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ase-palette
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Becker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-14 00:00:00.000000000 Z
11
+ date: 2019-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata