psd 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/psd.rb +4 -3
- data/lib/psd/channel_image.rb +79 -0
- data/lib/psd/image.rb +13 -13
- data/lib/psd/image_exports/png.rb +16 -14
- data/lib/psd/image_formats/layer_raw.rb +21 -0
- data/lib/psd/image_formats/layer_rle.rb +22 -0
- data/lib/psd/image_formats/raw.rb +3 -3
- data/lib/psd/image_formats/rle.rb +2 -2
- data/lib/psd/image_modes/cmyk.rb +22 -20
- data/lib/psd/image_modes/greyscale.rb +15 -13
- data/lib/psd/image_modes/rgb.rb +21 -19
- data/lib/psd/layer.rb +3 -2
- data/lib/psd/layer_mask.rb +3 -3
- data/lib/psd/node.rb +8 -0
- data/lib/psd/version.rb +1 -1
- data/spec/files/pixel.psd +0 -0
- data/spec/image_spec.rb +72 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93b149110f6660cd6b6231f8e8e1bcf440ffac4c
|
4
|
+
data.tar.gz: 7762bab9c1c6504a5fd39f54602acd27e30746ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d198525b3c71df4b3c4d869a3d56752f709bde1ccda35f25c22b4da0d68775bbe7ed09adfdb013fce65600953a4a421eb618430a613017c16c93aa404887ff19
|
7
|
+
data.tar.gz: 90ba4242c94d7cb725ed2180188cee87ba2230a2cc45bd77ed33bf6e2e7046561efabd6c9293847343e55fa13d7efba9e4b7491e004c100a3c8c32ab304ee51f
|
data/lib/psd.rb
CHANGED
@@ -28,7 +28,8 @@ class PSD
|
|
28
28
|
parse_layer_images: false
|
29
29
|
}
|
30
30
|
|
31
|
-
attr_reader :file
|
31
|
+
attr_reader :file, :opts
|
32
|
+
alias :options :opts
|
32
33
|
|
33
34
|
# Opens the named file, parses it, and makes it available for reading. Then, closes it after you're finished.
|
34
35
|
# @param filename [String] the name of the file to open
|
@@ -112,7 +113,7 @@ class PSD
|
|
112
113
|
ensure_header
|
113
114
|
ensure_resources
|
114
115
|
|
115
|
-
@layer_mask ||= LayerMask.new(@file, @header).parse
|
116
|
+
@layer_mask ||= LayerMask.new(@file, @header, @opts).parse
|
116
117
|
end
|
117
118
|
|
118
119
|
# Get the full size flattened preview Image.
|
@@ -164,7 +165,7 @@ class PSD
|
|
164
165
|
def ensure_layer_mask
|
165
166
|
return unless @layer_mask.nil?
|
166
167
|
|
167
|
-
@layer_mask = LayerMask.new(@file, @header)
|
168
|
+
@layer_mask = LayerMask.new(@file, @header, @opts)
|
168
169
|
@layer_mask.skip
|
169
170
|
end
|
170
171
|
end
|
data/lib/psd/channel_image.rb
CHANGED
@@ -4,6 +4,85 @@ class PSD
|
|
4
4
|
# Represents an image for a single layer, which differs slightly in format from
|
5
5
|
# the full size preview image.
|
6
6
|
class ChannelImage < Image
|
7
|
+
include ImageFormat::LayerRLE
|
8
|
+
include ImageFormat::LayerRAW
|
7
9
|
|
10
|
+
attr_reader :width, :height
|
11
|
+
|
12
|
+
def initialize(file, header, layer)
|
13
|
+
@layer = layer
|
14
|
+
|
15
|
+
@width = @layer.width
|
16
|
+
@height = @layer.height
|
17
|
+
|
18
|
+
super(file, header)
|
19
|
+
|
20
|
+
@channels_info = @layer.channels_info
|
21
|
+
end
|
22
|
+
|
23
|
+
def skip
|
24
|
+
PSD.logger.debug "Skipping channel image data. Layer = #{@layer.name}"
|
25
|
+
@channels_info.each do |ch|
|
26
|
+
@file.seek ch.length, IO::SEEK_CUR
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def channels
|
31
|
+
@layer.channels
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse
|
35
|
+
PSD.logger.debug "Layer = #{@layer.name}, Size = #{width}x#{height}"
|
36
|
+
|
37
|
+
@chan_pos = 0
|
38
|
+
|
39
|
+
@channels_info.each do |ch_info|
|
40
|
+
@ch_info = ch_info
|
41
|
+
if ch_info[:length] <= 0
|
42
|
+
parse_compression! and next
|
43
|
+
end
|
44
|
+
|
45
|
+
# If the ID of this current channel is -2, then we assume the dimensions
|
46
|
+
# of the layer mask.
|
47
|
+
if ch_info[:id] == -2
|
48
|
+
@width = @layer.mask.width
|
49
|
+
@height = @layer.mask.height
|
50
|
+
else
|
51
|
+
@width = @layer.width
|
52
|
+
@height = @layer.height
|
53
|
+
end
|
54
|
+
|
55
|
+
start = @file.tell
|
56
|
+
|
57
|
+
PSD.logger.debug "Channel ##{ch_info[:id]}, length = #{ch_info[:length]}"
|
58
|
+
parse_image_data!
|
59
|
+
|
60
|
+
finish = @file.tell
|
61
|
+
|
62
|
+
if finish != start + ch_info[:length]
|
63
|
+
PSD.logger.error "Read incorrect number of bytes for channel ##{ch_info[:id]}. Expected = #{ch_info[:length]}, Actual = #{finish - start}"
|
64
|
+
@file.seek start + @ch_info[:length]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if @channel_data.length != @length
|
69
|
+
PSD.logger.error "#{channel_data.length} read; expected #{@length}"
|
70
|
+
end
|
71
|
+
|
72
|
+
process_image_data
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_image_data!
|
76
|
+
@compression = parse_compression!
|
77
|
+
|
78
|
+
case @compression
|
79
|
+
when 0 then parse_raw!
|
80
|
+
when 1 then parse_rle!
|
81
|
+
when 2, 3 then parse_zip!
|
82
|
+
else
|
83
|
+
PSD.logger.error "Unknown image compression. Attempting to skip."
|
84
|
+
@file.seek(@end_pos)
|
85
|
+
end
|
86
|
+
end
|
8
87
|
end
|
9
88
|
end
|
data/lib/psd/image.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
class PSD
|
2
2
|
# Parses the full preview image at the end of the PSD document.
|
3
3
|
class Image
|
4
|
-
include
|
5
|
-
include
|
6
|
-
include
|
7
|
-
include
|
8
|
-
include
|
4
|
+
include ImageFormat::RAW
|
5
|
+
include ImageFormat::RLE
|
6
|
+
include ImageMode::CMYK
|
7
|
+
include ImageMode::Greyscale
|
8
|
+
include ImageMode::RGB
|
9
9
|
include Export::PNG
|
10
10
|
|
11
11
|
# All of the possible compression formats Photoshop uses.
|
@@ -16,14 +16,6 @@ class PSD
|
|
16
16
|
'ZIPPrediction'
|
17
17
|
]
|
18
18
|
|
19
|
-
# Each color channel is represented by a unique ID
|
20
|
-
CHANNEL_INFO = [
|
21
|
-
{id: 0},
|
22
|
-
{id: 1},
|
23
|
-
{id: 2},
|
24
|
-
{id: -1}
|
25
|
-
]
|
26
|
-
|
27
19
|
# Store a reference to the file and the header. We also do a few simple calculations
|
28
20
|
# to figure out the number of pixels in the image and the length of each channel.
|
29
21
|
def initialize(file, header)
|
@@ -42,6 +34,14 @@ class PSD
|
|
42
34
|
@pixel_data = []
|
43
35
|
|
44
36
|
PSD.logger.debug "Image: #{width}x#{height}, length = #{@length}, mode = #{@header.mode_name}, position = #{@start_pos}"
|
37
|
+
|
38
|
+
# Each color channel is represented by a unique ID
|
39
|
+
@channels_info = [
|
40
|
+
{id: 0},
|
41
|
+
{id: 1},
|
42
|
+
{id: 2},
|
43
|
+
{id: -1}
|
44
|
+
]
|
45
45
|
end
|
46
46
|
|
47
47
|
# Begins parsing the image by first figuring out the compression format used, and then
|
@@ -7,24 +7,26 @@ class PSD::Image
|
|
7
7
|
# Load the image pixels into a PNG file and return a reference to the
|
8
8
|
# data.
|
9
9
|
def to_png
|
10
|
-
|
11
|
-
|
10
|
+
@png ||= (
|
11
|
+
PSD.logger.debug "Beginning PNG export"
|
12
|
+
png = ChunkyPNG::Image.new(width.to_i, height.to_i, ChunkyPNG::Color::TRANSPARENT)
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
i = 0
|
15
|
+
height.times do |y|
|
16
|
+
width.times do |x|
|
17
|
+
png[x,y] = ChunkyPNG::Color.rgba(
|
18
|
+
@pixel_data[i],
|
19
|
+
@pixel_data[i+1],
|
20
|
+
@pixel_data[i+2],
|
21
|
+
@pixel_data[i+3]
|
22
|
+
)
|
22
23
|
|
23
|
-
|
24
|
+
i += 4
|
25
|
+
end
|
24
26
|
end
|
25
|
-
end
|
26
27
|
|
27
|
-
|
28
|
+
png
|
29
|
+
)
|
28
30
|
end
|
29
31
|
alias :export :to_png
|
30
32
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class PSD
|
2
|
+
module ImageFormat
|
3
|
+
module LayerRAW
|
4
|
+
private
|
5
|
+
|
6
|
+
# Since we're parsing on a per-channel basis, we need to modify the behavior
|
7
|
+
# of the RAW encoding parser a bit. This version is aware of the current
|
8
|
+
# channel data position, since layers that have RAW encoding often use RLE
|
9
|
+
# encoded alpha channels.
|
10
|
+
def parse_raw!(length = @length)
|
11
|
+
PSD.logger.debug "Attempting to parse RAW encoded channel..."
|
12
|
+
|
13
|
+
(@chan_pos...(@chan_pos + @ch_info[:length] - 2)).each do |i|
|
14
|
+
@channel_data[i] = @file.read(1).bytes.to_a[0]
|
15
|
+
end
|
16
|
+
|
17
|
+
@chan_pos += @ch_info[:length] - 2
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class PSD
|
2
|
+
module ImageFormat
|
3
|
+
# Some method overrides for layer images.
|
4
|
+
module LayerRLE
|
5
|
+
private
|
6
|
+
|
7
|
+
def parse_byte_counts!
|
8
|
+
byte_counts = []
|
9
|
+
height.times do
|
10
|
+
byte_counts << @file.read_short
|
11
|
+
end
|
12
|
+
|
13
|
+
return byte_counts
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_channel_data!
|
17
|
+
PSD.logger.debug "Parsing layer RLE channel ##{@ch_info[:id]}: position = #{@chan_pos}"
|
18
|
+
@chan_pos = decode_rle_channel(@chan_pos, 0)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
class PSD
|
2
|
-
module
|
1
|
+
class PSD
|
2
|
+
module ImageFormat
|
3
3
|
# Parses a RAW uncompressed image
|
4
4
|
module RAW
|
5
5
|
private
|
6
6
|
|
7
7
|
def parse_raw!(length = @length)
|
8
8
|
@length.times do |i|
|
9
|
-
@channel_data[i] = @file.read(1).
|
9
|
+
@channel_data[i] = @file.read(1).bytes.to_a[0]
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/psd/image_modes/cmyk.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
class PSD
|
2
|
-
module
|
3
|
-
|
1
|
+
class PSD
|
2
|
+
module ImageMode
|
3
|
+
module CMYK
|
4
|
+
private
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
def combine_cmyk_channel
|
7
|
+
(0...@num_pixels).step(pixel_step) do |i|
|
8
|
+
if channels == 5
|
9
|
+
a = @channel_data[i]
|
10
|
+
c = @channel_data[i + @channel_length]
|
11
|
+
m = @channel_data[i + @channel_length * 2]
|
12
|
+
y = @channel_data[i + @channel_length * 3]
|
13
|
+
k = @channel_data[i + @channel_length * 4]
|
14
|
+
else
|
15
|
+
a = 255
|
16
|
+
c = @channel_data[i]
|
17
|
+
m = @channel_data[i + @channel_length]
|
18
|
+
y = @channel_data[i + @channel_length * 2]
|
19
|
+
k = @channel_data[i + @channel_length * 3]
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
+
rgb = PSD::Color.cmyk_to_rgb(255 - c, 255 - m, 255 - y, 255 - k)
|
22
23
|
|
23
|
-
|
24
|
+
@pixel_data.push *rgb.values, a
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -1,18 +1,20 @@
|
|
1
|
-
class PSD
|
2
|
-
module
|
3
|
-
|
1
|
+
class PSD
|
2
|
+
module ImageMode
|
3
|
+
module Greyscale
|
4
|
+
private
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
def combine_greyscale_channel
|
7
|
+
if channels == 2
|
8
|
+
(0...@num_pixels).step(pixel_step) do |i|
|
9
|
+
alpha = @channel_data[i]
|
10
|
+
grey = @channel_data[@channel_length + i]
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
@pixel_data.push grey, grey, grey, alpha
|
13
|
+
end
|
14
|
+
else
|
15
|
+
(0...@num_pixels).step(pixel_step) do |i|
|
16
|
+
@pixel_data.push *([@channel_data[i]] * 3), 255
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
data/lib/psd/image_modes/rgb.rb
CHANGED
@@ -1,28 +1,30 @@
|
|
1
|
-
class PSD
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
class PSD
|
2
|
+
module ImageMode
|
3
|
+
# Combines the channel data from the image into RGB pixel values
|
4
|
+
module RGB
|
5
|
+
private
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def combine_rgb_channel
|
8
|
+
PSD.logger.debug "Beginning RGB processing"
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
(0...@num_pixels).step(pixel_step) do |i|
|
11
|
+
r = g = b = 0
|
12
|
+
a = 255
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
@channels_info.each_with_index do |chan, index|
|
15
|
+
next if channels == 3 && chan[:id] == -1
|
16
|
+
val = @channel_data[i + (@channel_length * index)]
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
case chan[:id]
|
19
|
+
when -1 then a = val
|
20
|
+
when 0 then r = val
|
21
|
+
when 1 then g = val
|
22
|
+
when 2 then b = val
|
23
|
+
end
|
22
24
|
end
|
23
|
-
end
|
24
25
|
|
25
|
-
|
26
|
+
@pixel_data.push r, g, b, a
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
data/lib/psd/layer.rb
CHANGED
@@ -96,8 +96,9 @@ class PSD
|
|
96
96
|
self.send(val)
|
97
97
|
end
|
98
98
|
|
99
|
-
def parse_channel_image!(header)
|
100
|
-
|
99
|
+
def parse_channel_image!(header, parse)
|
100
|
+
@image = ChannelImage.new(@file, header, self)
|
101
|
+
parse ? @image.parse : @image.skip
|
101
102
|
end
|
102
103
|
|
103
104
|
# Does this layer represent the start of a folder section?
|
data/lib/psd/layer_mask.rb
CHANGED
@@ -7,9 +7,10 @@ class PSD
|
|
7
7
|
attr_reader :layers, :global_mask
|
8
8
|
|
9
9
|
# Store a reference to the file and the header and initialize the defaults.
|
10
|
-
def initialize(file, header)
|
10
|
+
def initialize(file, header, options)
|
11
11
|
@file = file
|
12
12
|
@header = header
|
13
|
+
@options = options
|
13
14
|
|
14
15
|
@layers = []
|
15
16
|
@merged_alpha = false
|
@@ -55,8 +56,7 @@ class PSD
|
|
55
56
|
|
56
57
|
layers.each do |layer|
|
57
58
|
@file.seek 8, IO::SEEK_CUR and next if layer.folder? || layer.folder_end?
|
58
|
-
|
59
|
-
layer.parse_channel_image!(@header)
|
59
|
+
layer.parse_channel_image!(@header, @options[:parse_layer_images])
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/lib/psd/node.rb
CHANGED
data/lib/psd/version.rb
CHANGED
Binary file
|
data/spec/image_spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Image Exporting' do
|
4
|
+
before(:each) do
|
5
|
+
class PSD::Image
|
6
|
+
attr_accessor :pixel_data
|
7
|
+
end
|
8
|
+
|
9
|
+
@psd = PSD.new('spec/files/pixel.psd')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "the full preview image" do
|
13
|
+
it "should successfully parse the image data" do
|
14
|
+
@psd.parse!
|
15
|
+
expect(@psd).to be_parsed
|
16
|
+
expect(@psd.image).to_not be_nil
|
17
|
+
expect(@psd.image.width).to eq(1)
|
18
|
+
expect(@psd.image.height).to eq(1)
|
19
|
+
expect(@psd.image.pixel_data).to eq([0, 100, 200, 255])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be able to skip to the image" do
|
23
|
+
expect(@psd).to_not be_parsed
|
24
|
+
expect(@psd.image.width).to eq(1)
|
25
|
+
expect(@psd.image.height).to eq(1)
|
26
|
+
expect(@psd.image.pixel_data).to eq([0, 100, 200, 255])
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "as PNG" do
|
30
|
+
it "should produce a valid PNG object" do
|
31
|
+
expect(@psd.image.to_png).to be_an_instance_of(ChunkyPNG::Image)
|
32
|
+
|
33
|
+
# Ensure it's cached
|
34
|
+
expect(@psd.image.to_png).to be @psd.image.to_png
|
35
|
+
expect(@psd.image.to_png.width).to eq(1)
|
36
|
+
expect(@psd.image.to_png.height).to eq(1)
|
37
|
+
expect(
|
38
|
+
ChunkyPNG::Color.to_truecolor_alpha_bytes(@psd.image.to_png[0,0])
|
39
|
+
).to eq([0, 100, 200, 255])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "layer images" do
|
45
|
+
it "should successfully parse the image data" do
|
46
|
+
@psd.options[:parse_layer_images] = true
|
47
|
+
@psd.parse!
|
48
|
+
|
49
|
+
image = @psd.tree.children.first.image
|
50
|
+
expect(image).to be_an_instance_of(PSD::ChannelImage)
|
51
|
+
expect(image.width).to eq(1)
|
52
|
+
expect(image.height).to eq(1)
|
53
|
+
|
54
|
+
expect(image.pixel_data).to eq([0, 100, 200, 255])
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "as PNG" do
|
58
|
+
it "should produce a valid PNG object" do
|
59
|
+
@psd.options[:parse_layer_images] = true
|
60
|
+
@psd.parse!
|
61
|
+
|
62
|
+
png = @psd.tree.children.first.image.to_png
|
63
|
+
expect(png).to be_an_instance_of(ChunkyPNG::Image)
|
64
|
+
expect(png.width).to eq(1)
|
65
|
+
expect(png.height).to eq(1)
|
66
|
+
expect(
|
67
|
+
ChunkyPNG::Color.to_truecolor_alpha_bytes(png[0,0])
|
68
|
+
).to eq([0, 100, 200, 255])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: psd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan LeFevre
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bindata
|
@@ -136,6 +136,8 @@ files:
|
|
136
136
|
- lib/psd/helpers.rb
|
137
137
|
- lib/psd/image.rb
|
138
138
|
- lib/psd/image_exports/png.rb
|
139
|
+
- lib/psd/image_formats/layer_raw.rb
|
140
|
+
- lib/psd/image_formats/layer_rle.rb
|
139
141
|
- lib/psd/image_formats/raw.rb
|
140
142
|
- lib/psd/image_formats/rle.rb
|
141
143
|
- lib/psd/image_modes/cmyk.rb
|
@@ -179,10 +181,12 @@ files:
|
|
179
181
|
- spec/files/example.psd
|
180
182
|
- spec/files/one_layer.psd
|
181
183
|
- spec/files/path.psd
|
184
|
+
- spec/files/pixel.psd
|
182
185
|
- spec/files/simplest.psd
|
183
186
|
- spec/files/text.psd
|
184
187
|
- spec/hierarchy_spec.rb
|
185
188
|
- spec/identity_spec.rb
|
189
|
+
- spec/image_spec.rb
|
186
190
|
- spec/parsing_spec.rb
|
187
191
|
- spec/psd_spec.rb
|
188
192
|
- spec/spec_helper.rb
|
@@ -215,10 +219,12 @@ test_files:
|
|
215
219
|
- spec/files/example.psd
|
216
220
|
- spec/files/one_layer.psd
|
217
221
|
- spec/files/path.psd
|
222
|
+
- spec/files/pixel.psd
|
218
223
|
- spec/files/simplest.psd
|
219
224
|
- spec/files/text.psd
|
220
225
|
- spec/hierarchy_spec.rb
|
221
226
|
- spec/identity_spec.rb
|
227
|
+
- spec/image_spec.rb
|
222
228
|
- spec/parsing_spec.rb
|
223
229
|
- spec/psd_spec.rb
|
224
230
|
- spec/spec_helper.rb
|