psd 2.1.2 → 3.9.0
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 +5 -5
- data/.travis.yml +2 -0
- data/README.md +60 -20
- data/lib/psd/blend_mode.rb +46 -38
- data/lib/psd/channel_image.rb +11 -5
- data/lib/psd/color.rb +14 -5
- data/lib/psd/descriptor.rb +39 -16
- data/lib/psd/file.rb +9 -6
- data/lib/psd/header.rb +38 -33
- data/lib/psd/helpers.rb +2 -2
- data/lib/psd/image.rb +21 -16
- data/lib/psd/image_formats/layer_rle.rb +2 -2
- data/lib/psd/image_formats/rle.rb +4 -10
- data/lib/psd/image_modes/cmyk.rb +18 -5
- data/lib/psd/image_modes/greyscale.rb +6 -1
- data/lib/psd/image_modes/rgb.rb +17 -5
- data/lib/psd/layer/blend_modes.rb +15 -13
- data/lib/psd/layer/helpers.rb +8 -10
- data/lib/psd/layer/info/black_white.rb +33 -0
- data/lib/psd/{layer_info → layer/info}/blend_clipping_elements.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/blend_interior_elements.rb +4 -2
- data/lib/psd/layer/info/brightness_contrast.rb +21 -0
- data/lib/psd/layer/info/channel_blending_restrictions.rb +27 -0
- data/lib/psd/layer/info/channel_mixer.rb +27 -0
- data/lib/psd/layer/info/color_balance.rb +23 -0
- data/lib/psd/layer/info/color_lookup.rb +14 -0
- data/lib/psd/layer/info/content_generator.rb +42 -0
- data/lib/psd/layer/info/curves.rb +78 -0
- data/lib/psd/layer/info/effects_layer.rb +174 -0
- data/lib/psd/layer/info/exposure.rb +20 -0
- data/lib/psd/{layer_info → layer/info}/fill_opacity.rb +4 -2
- data/lib/psd/layer/info/gradient_fill.rb +14 -0
- data/lib/psd/layer/info/gradient_map.rb +69 -0
- data/lib/psd/layer/info/hue_saturation.rb +41 -0
- data/lib/psd/layer/info/invert.rb +17 -0
- data/lib/psd/layer/info/knockout.rb +22 -0
- data/lib/psd/layer/info/layer_effects.rb +16 -0
- data/lib/psd/{layer_info → layer/info}/layer_group.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/layer_id.rb +4 -2
- data/lib/psd/layer/info/layer_mask_as_global_mask.rb +16 -0
- data/lib/psd/{layer_info → layer/info}/layer_name_source.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/layer_section_divider.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/legacy_typetool.rb +6 -4
- data/lib/psd/layer/info/levels.rb +48 -0
- data/lib/psd/{layer_info → layer/info}/locked.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/metadata_setting.rb +5 -3
- data/lib/psd/{layer_info → layer/info}/object_effects.rb +5 -5
- data/lib/psd/layer/info/pattern.rb +14 -0
- data/lib/psd/layer/info/pattern_fill.rb +15 -0
- data/lib/psd/layer/info/photo_filter.rb +44 -0
- data/lib/psd/{layer_info → layer/info}/placed_layer.rb +4 -2
- data/lib/psd/layer/info/posterize.rb +16 -0
- data/lib/psd/{layer_info → layer/info}/reference_point.rb +4 -2
- data/lib/psd/layer/info/selective_color.rb +32 -0
- data/lib/psd/layer/info/sheet_color.rb +36 -0
- data/lib/psd/layer/info/solid_color.rb +36 -0
- data/lib/psd/layer/info/threshold.rb +16 -0
- data/lib/psd/layer/info/transparency_shapes_layer.rb +16 -0
- data/lib/psd/{layer_info → layer/info}/typetool.rb +27 -13
- data/lib/psd/{layer_info → layer/info}/unicode_name.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/vector_mask.rb +7 -5
- data/lib/psd/layer/info/vector_mask_as_global_mask.rb +16 -0
- data/lib/psd/layer/info/vector_origination.rb +14 -0
- data/lib/psd/{layer_info → layer/info}/vector_stroke.rb +4 -2
- data/lib/psd/{layer_info → layer/info}/vector_stroke_content.rb +4 -2
- data/lib/psd/layer/info/vibrance.rb +22 -0
- data/lib/psd/layer/info.rb +106 -19
- data/lib/psd/layer/position_and_channels.rb +2 -6
- data/lib/psd/layer.rb +13 -16
- data/lib/psd/layer_info.rb +0 -4
- data/lib/psd/layer_mask.rb +61 -50
- data/lib/psd/lazy_execute.rb +5 -1
- data/lib/psd/mask.rb +7 -1
- data/lib/psd/node.rb +142 -49
- data/lib/psd/nodes/ancestry.rb +7 -6
- data/lib/psd/nodes/build_preview.rb +4 -4
- data/lib/psd/nodes/group.rb +36 -0
- data/lib/psd/nodes/layer.rb +45 -0
- data/lib/psd/nodes/layer_comps.rb +93 -0
- data/lib/psd/nodes/locking.rb +36 -0
- data/lib/psd/nodes/root.rb +87 -0
- data/lib/psd/nodes/search.rb +8 -65
- data/lib/psd/path_record.rb +5 -70
- data/lib/psd/renderer/blender.rb +10 -5
- data/lib/psd/renderer/cairo_helpers.rb +46 -0
- data/lib/psd/renderer/canvas.rb +41 -20
- data/lib/psd/renderer/canvas_management.rb +2 -2
- data/lib/psd/renderer/clipping_mask.rb +5 -4
- data/lib/psd/renderer/compose.rb +59 -69
- data/lib/psd/renderer/layer_styles/color_overlay.rb +45 -27
- data/lib/psd/renderer/layer_styles.rb +15 -5
- data/lib/psd/renderer/mask.rb +26 -22
- data/lib/psd/renderer/mask_canvas.rb +12 -0
- data/lib/psd/renderer/vector_shape.rb +239 -0
- data/lib/psd/renderer.rb +18 -7
- data/lib/psd/resource_section.rb +13 -6
- data/lib/psd/resources/base.rb +33 -0
- data/lib/psd/resources/guides.rb +6 -4
- data/lib/psd/resources/layer_comps.rb +6 -4
- data/lib/psd/resources/resolution_info.rb +48 -0
- data/lib/psd/resources/saved_path.rb +19 -0
- data/lib/psd/resources/slices.rb +7 -5
- data/lib/psd/resources/work_path.rb +22 -0
- data/lib/psd/resources/xmp_metadata.rb +46 -0
- data/lib/psd/resources.rb +17 -21
- data/lib/psd/slice.rb +44 -0
- data/lib/psd/slices.rb +13 -0
- data/lib/psd/util.rb +4 -2
- data/lib/psd/version.rb +1 -1
- data/lib/psd.rb +31 -45
- data/psd.gemspec +2 -3
- data/spec/files/alignment_modes.psd +0 -0
- data/spec/files/blendmodes.psd +0 -0
- data/spec/files/example.psb +0 -0
- data/spec/hierarchy_spec.rb +5 -0
- data/spec/locked_spec.rb +8 -8
- data/spec/psb_parsing_spec.rb +57 -0
- data/spec/text_spec.rb +13 -1
- metadata +115 -75
- data/circle.yml +0 -6
- data/lib/psd/layer_info/vector_mask_2.rb +0 -10
- data/lib/psd/node_exporting.rb +0 -20
- data/lib/psd/node_group.rb +0 -86
- data/lib/psd/node_layer.rb +0 -81
- data/lib/psd/node_root.rb +0 -93
- data/lib/psd/nodes/has_children.rb +0 -13
- data/lib/psd/nodes/lock_to_origin.rb +0 -7
- data/lib/psd/nodes/parse_layers.rb +0 -18
- data/lib/psd/renderer/layer_styles/drop_shadow.rb +0 -75
- data/lib/psd/section.rb +0 -26
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Exposure < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'expA'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :exposure, :offset, :gamma
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@file.seek 2, IO::SEEK_CUR
|
13
|
+
|
14
|
+
# Why this shit is big endian is beyond me. Thanks Adobe.
|
15
|
+
@exposure = @file.read(4).unpack('g')[0]
|
16
|
+
@offset = @file.read(4).unpack('g')[0]
|
17
|
+
@gamma = @file.read(4).unpack('g')[0]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class GradientMap < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'grdm'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :reverse, :dither, :name, :color_stops, :transparency_stops,
|
10
|
+
:interpolation, :mode, :random_seed, :showing_transparency, :using_vector_color,
|
11
|
+
:roughness_factor, :color_model, :minimum_color, :maximum_color
|
12
|
+
|
13
|
+
def parse
|
14
|
+
# Version
|
15
|
+
@file.seek 2, IO::SEEK_CUR
|
16
|
+
|
17
|
+
@reverse = @file.read_boolean
|
18
|
+
@dither = @file.read_boolean
|
19
|
+
|
20
|
+
@name = @file.read_unicode_string
|
21
|
+
|
22
|
+
color_stops = @file.read_short
|
23
|
+
@color_stops = color_stops.times.map do
|
24
|
+
color = {
|
25
|
+
location: @file.read_int,
|
26
|
+
midpoint: @file.read_int,
|
27
|
+
color: @file.read_space_color
|
28
|
+
}
|
29
|
+
|
30
|
+
# Mystery padding
|
31
|
+
@file.seek 2, IO::SEEK_CUR
|
32
|
+
color
|
33
|
+
end
|
34
|
+
|
35
|
+
transparency_stops = @file.read_short
|
36
|
+
@transparency_stops = transparency_stops.times.map do
|
37
|
+
{
|
38
|
+
location: @file.read_int,
|
39
|
+
midpoint: @file.read_int,
|
40
|
+
opacity: @file.read_short
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
expansion_count = @file.read_short
|
45
|
+
if expansion_count > 0
|
46
|
+
@interpolation = @file.read_short
|
47
|
+
length = @file.read_short
|
48
|
+
if length >= 32
|
49
|
+
@mode = @file.read_short
|
50
|
+
@random_seed = @file.read_int
|
51
|
+
@showing_transparency = @file.read_short > 0
|
52
|
+
@using_vector_color = @file.read_short > 0
|
53
|
+
@roughness_factor = @file.read_int
|
54
|
+
|
55
|
+
@color_model = @file.read_short
|
56
|
+
@minimum_color = 4.times.map do
|
57
|
+
@file.read_short >> 8
|
58
|
+
end
|
59
|
+
|
60
|
+
@maximum_color = 4.times.map do
|
61
|
+
@file.read_short >> 8
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
@file.seek 2, IO::SEEK_CUR
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class HueSaturation < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'hue2'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :type, :colorization, :master, :range_values, :setting_values
|
10
|
+
|
11
|
+
def parse
|
12
|
+
# Version
|
13
|
+
@file.seek 2, IO::SEEK_CUR
|
14
|
+
|
15
|
+
@type = @file.read_byte == 0 ? :hue : :colorization
|
16
|
+
|
17
|
+
# Padding byte
|
18
|
+
@file.seek 1, IO::SEEK_CUR
|
19
|
+
|
20
|
+
@colorization = {
|
21
|
+
hue: @file.read_short,
|
22
|
+
saturation: @file.read_short,
|
23
|
+
lightness: @file.read_short
|
24
|
+
}
|
25
|
+
|
26
|
+
@master = {
|
27
|
+
hue: @file.read_short,
|
28
|
+
saturation: @file.read_short,
|
29
|
+
lightness: @file.read_short
|
30
|
+
}
|
31
|
+
|
32
|
+
@range_values = []
|
33
|
+
@setting_values = []
|
34
|
+
|
35
|
+
6.times do
|
36
|
+
@range_values << 4.times.map { @file.read_short }
|
37
|
+
@setting_values << 3.times.map { @file.read_short }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Invert < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'nvrt'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :inverted
|
10
|
+
|
11
|
+
def parse
|
12
|
+
# There is no data. The presence of this info block is
|
13
|
+
# all that's provided.
|
14
|
+
@inverted = true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Knockout < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'knko'
|
7
|
+
end
|
8
|
+
|
9
|
+
MODES = [:shallow, :deep]
|
10
|
+
|
11
|
+
attr_reader :enabled, :mode
|
12
|
+
|
13
|
+
def parse
|
14
|
+
val = @file.read_byte
|
15
|
+
|
16
|
+
@enabled = val > 0
|
17
|
+
@mode = MODES[val - 1]
|
18
|
+
|
19
|
+
@file.seek 3, IO::SEEK_CUR
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class LayerEffects < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'lfxs'
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
version = @file.read_int
|
11
|
+
descriptor_version = @file.read_int
|
12
|
+
|
13
|
+
@data = Descriptor.new(@file).parse
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'psd/layer_info'
|
2
2
|
|
3
3
|
class PSD
|
4
4
|
# Not 100% sure what the purpose of this key is, but it seems to exist
|
@@ -7,7 +7,9 @@ class PSD
|
|
7
7
|
#
|
8
8
|
# See https://github.com/layervault/psd.rb/issues/38
|
9
9
|
class NestedLayerDivider < LayerInfo
|
10
|
-
|
10
|
+
def self.should_parse?(key)
|
11
|
+
key == 'lsdk'
|
12
|
+
end
|
11
13
|
|
12
14
|
attr_reader :is_folder, :is_hidden
|
13
15
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class LayerMaskAsGlobalMask < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'lmgm'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :enabled
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@enabled = @file.read_boolean
|
13
|
+
@file.seek 3, IO::SEEK_CUR
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
require 'psd/layer_info'
|
2
2
|
|
3
3
|
class PSD
|
4
4
|
class LayerSectionDivider < LayerInfo
|
5
|
-
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'lsct'
|
7
|
+
end
|
6
8
|
|
7
9
|
attr_reader :layer_type, :is_folder, :is_hidden, :blend_mode, :sub_type
|
8
10
|
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'psd/layer_info'
|
2
|
+
require 'psd/layer/info/typetool'
|
3
3
|
|
4
4
|
class PSD
|
5
5
|
class LegacyTypeTool < TypeTool
|
6
|
-
|
6
|
+
def self.should_parse?(key)
|
7
|
+
key == 'tySh'
|
8
|
+
end
|
7
9
|
|
8
10
|
def parse
|
9
11
|
version = @file.read_short
|
@@ -85,4 +87,4 @@ class PSD
|
|
85
87
|
""
|
86
88
|
end
|
87
89
|
end
|
88
|
-
end
|
90
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Levels < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'levl'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :records
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@file.seek 2, IO::SEEK_CUR
|
13
|
+
|
14
|
+
@records = 29.times.map do
|
15
|
+
{
|
16
|
+
input_floor: @file.read_short,
|
17
|
+
input_ceiling: @file.read_short,
|
18
|
+
output_floor: @file.read_short,
|
19
|
+
output_ceiling: @file.read_short,
|
20
|
+
gamma: @file.read_short / 100.0,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Photoshop CS (8.0) additional information
|
25
|
+
if @file.tell < @section_end - 4
|
26
|
+
tag = @file.read_string(4)
|
27
|
+
raise 'Extra levels key error' if tag != 'Lvls'
|
28
|
+
|
29
|
+
@file.seek 2, IO::SEEK_CUR
|
30
|
+
|
31
|
+
# Count of total level record structures. Subtract the legacy number of
|
32
|
+
# level record structures, 29, to determine how many are remaining in
|
33
|
+
# the file for reading.
|
34
|
+
extra_levels = @file.read_short - 29
|
35
|
+
|
36
|
+
extra_levels.times do
|
37
|
+
@records << {
|
38
|
+
input_floor: @file.read_short,
|
39
|
+
input_ceiling: @file.read_short,
|
40
|
+
output_floor: @file.read_short,
|
41
|
+
output_ceiling: @file.read_short,
|
42
|
+
gamma: @file.read_short / 100.0
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
require 'psd/layer_info'
|
2
2
|
|
3
3
|
class PSD
|
4
4
|
class Locked < LayerInfo
|
5
|
-
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'lspf'
|
7
|
+
end
|
6
8
|
|
7
9
|
attr_reader :all_locked, :transparency_locked, :composite_locked, :position_locked
|
8
10
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
require 'psd/layer_info'
|
2
2
|
|
3
3
|
class PSD
|
4
4
|
class MetadataSetting < LayerInfo
|
5
|
-
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'shmd'
|
7
|
+
end
|
6
8
|
|
7
9
|
def parse
|
8
10
|
count = @file.read_int
|
@@ -32,4 +34,4 @@ class PSD
|
|
32
34
|
@data[:layer_comp] = Descriptor.new(@file).parse
|
33
35
|
end
|
34
36
|
end
|
35
|
-
end
|
37
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
|
1
|
+
require 'psd/layer_info'
|
2
2
|
|
3
3
|
class PSD
|
4
4
|
class ObjectEffects < LayerInfo
|
5
|
-
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'lfx2'
|
7
|
+
end
|
6
8
|
|
7
9
|
def parse
|
8
10
|
version = @file.read_int
|
9
11
|
descriptor_version = @file.read_int
|
10
12
|
|
11
13
|
@data = Descriptor.new(@file).parse
|
12
|
-
|
13
|
-
return self
|
14
14
|
end
|
15
15
|
end
|
16
|
-
end
|
16
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class PhotoFilter < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'phfl'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :color, :density, :preserve_luminosity
|
10
|
+
|
11
|
+
def parse
|
12
|
+
version = @file.read_short
|
13
|
+
|
14
|
+
case version
|
15
|
+
when 2 then parse_version_2
|
16
|
+
when 3 then parse_version_3
|
17
|
+
else return
|
18
|
+
end
|
19
|
+
|
20
|
+
@density = @file.read_int
|
21
|
+
@preserve_luminosity = @file.read_boolean
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_version_2
|
27
|
+
color_space = @file.read_short
|
28
|
+
color_components = 4.times.map { @file.read_short }
|
29
|
+
|
30
|
+
@color = {
|
31
|
+
color_space: Color::COLOR_SPACE[color_space],
|
32
|
+
components: color_components
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_version_3
|
37
|
+
@color = {
|
38
|
+
x: @file.read_int >> 8,
|
39
|
+
y: @file.read_int >> 8,
|
40
|
+
z: @file.read_int >> 8
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Posterize < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'post'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :levels
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@levels = @file.read_short
|
13
|
+
@file.seek 2, IO::SEEK_CUR # Padding?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class SelectiveColor < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'selc'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :correction_mode, :cyan_correction, :magenta_correction,
|
10
|
+
:yellow_correction, :black_correction
|
11
|
+
|
12
|
+
def parse
|
13
|
+
@file.seek 2, IO::SEEK_CUR
|
14
|
+
|
15
|
+
@correction_mode = @file.read_short == 0 ? :relative : :absolute
|
16
|
+
@cyan_correction = []
|
17
|
+
@magenta_correction = []
|
18
|
+
@yellow_correction = []
|
19
|
+
@black_correction = []
|
20
|
+
|
21
|
+
10.times do |i|
|
22
|
+
# First record is all 0 and is ignored by Photoshop
|
23
|
+
@file.seek(8, IO::SEEK_CUR) and next if i == 0
|
24
|
+
|
25
|
+
@cyan_correction << @file.read_short
|
26
|
+
@magenta_correction << @file.read_short
|
27
|
+
@yellow_correction << @file.read_short
|
28
|
+
@black_correction << @file.read_short
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
# This is the color label for a group/layer. Not sure why Adobe
|
5
|
+
# refers to it as the "Sheet Color".
|
6
|
+
class SheetColor < LayerInfo
|
7
|
+
def self.should_parse?(key)
|
8
|
+
key == 'lclr'
|
9
|
+
end
|
10
|
+
|
11
|
+
COLORS = [
|
12
|
+
:no_color,
|
13
|
+
:red,
|
14
|
+
:orange,
|
15
|
+
:yellow,
|
16
|
+
:green,
|
17
|
+
:blue,
|
18
|
+
:violet,
|
19
|
+
:gray
|
20
|
+
]
|
21
|
+
|
22
|
+
def parse
|
23
|
+
# Only the first entry is used, the rest are always 0.
|
24
|
+
@data = [
|
25
|
+
@file.read_short,
|
26
|
+
@file.read_short,
|
27
|
+
@file.read_short,
|
28
|
+
@file.read_short
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def color
|
33
|
+
COLORS[@data[0]]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class SolidColor < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'SoCo'
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
@file.seek 4, IO::SEEK_CUR
|
11
|
+
@data = Descriptor.new(@file).parse
|
12
|
+
end
|
13
|
+
|
14
|
+
def color
|
15
|
+
ChunkyPNG::Color.rgb(r, g, b)
|
16
|
+
end
|
17
|
+
|
18
|
+
def r
|
19
|
+
@r ||= color_data['Rd '].round
|
20
|
+
end
|
21
|
+
|
22
|
+
def g
|
23
|
+
@g ||= color_data['Grn '].round
|
24
|
+
end
|
25
|
+
|
26
|
+
def b
|
27
|
+
@b ||= color_data['Bl '].round
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def color_data
|
33
|
+
@data['Clr ']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Threshold < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'thrs'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :level
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@level = @file.read_short
|
13
|
+
@file.seek 2, IO::SEEK_CUR # Padding?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'psd/layer_info'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class TransparencyShapesLayer < LayerInfo
|
5
|
+
def self.should_parse?(key)
|
6
|
+
key == 'tsly'
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :enabled
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@enabled = @file.read_byte == 1
|
13
|
+
@file.seek 3, IO::SEEK_CUR
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|