psd 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c100d128dba86088c063508116bc3a1acd0bd650
4
- data.tar.gz: 042fe61f2579e7f7dfeda0e223abac81375908b4
3
+ metadata.gz: 3ad5fbd51101b2362d57e17fe0fe5544ebc51ea8
4
+ data.tar.gz: bb899376edd469fd83536d6bf2b50b96fb044b6e
5
5
  SHA512:
6
- metadata.gz: f261b03bea18d788a5d3c608fdb4c41886a2f76030ee4d670a21ae03305940fd610743ea089bcde1c5dd15643b464b7655f591e592950020fd80151547963288
7
- data.tar.gz: 3547fe009db381c5e0286c2e7a66e14944388f02591436d20cef0c4d470c4b4cf870bcd105a793aa44cf0d3d38880a2be52f893d49eb4ed40ef310d8dd640b96
6
+ metadata.gz: 92068cabd35464e01395b673cc8a4322fd0cd5e8f9317fcc33571df8cea9d0bd59cc98e4faeeca91399634f5549c3b04b4fbf3f891d5b32a154a54843a46e98d
7
+ data.tar.gz: 26686e5b31b29de64da12dce875cc9edde976451028cd0ccd1f25c855db2851e00be26619c4a8d49e84d8ee076b05e3015acd92bb978a24b014203489890b4ea
@@ -0,0 +1,7 @@
1
+ ## Contributing
2
+
3
+ 1. Fork it
4
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
5
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
6
+ 4. Push to the branch (`git push origin my-new-feature`)
7
+ 5. Create new Pull Request
data/README.md CHANGED
@@ -142,6 +142,20 @@ png = psd.image.to_png # reference to PNG data
142
142
  psd.image.save_as_png 'path/to/output.png' # writes PNG to disk
143
143
  ```
144
144
 
145
+ **Debugging**
146
+
147
+ If you run into any problems parsing a PSD, you can enable debug logging via the `PSD_DEBUG` environment variable. For example:
148
+
149
+ ``` bash
150
+ PSD_DEBUG=STDOUT bundle exec examples/parse.rb
151
+ ```
152
+
153
+ You can also give a path to a file instead. If you need to enable debugging programatically:
154
+
155
+ ``` ruby
156
+ PSD.debug = true
157
+ ```
158
+
145
159
  ## To-do
146
160
 
147
161
  There are a few features that are currently missing from PSD.rb.
@@ -150,11 +164,3 @@ There are a few features that are currently missing from PSD.rb.
150
164
  * Individual layer image exporting
151
165
  * More image modes + depths for image exporting
152
166
  * A few layer info blocks
153
-
154
- ## Contributing
155
-
156
- 1. Fork it
157
- 2. Create your feature branch (`git checkout -b my-new-feature`)
158
- 3. Commit your changes (`git commit -am 'Add some feature'`)
159
- 4. Push to the branch (`git push origin my-new-feature`)
160
- 5. Create new Pull Request
data/lib/psd.rb CHANGED
@@ -19,13 +19,10 @@ end
19
19
  # the header, resources, the layer mask (including layers), and the preview image. We parse
20
20
  # each of these sections in order.
21
21
  class PSD
22
+ include Logger
22
23
  include Helpers
23
24
  include NodeExporting
24
25
 
25
- # Just used to track what layer info keys we didn't parse in this file for development purposes.
26
- def self.keys; @@keys; end
27
- @@keys = []
28
-
29
26
  DEFAULTS = {
30
27
  parse_image: false,
31
28
  parse_layer_images: false
@@ -66,7 +63,10 @@ class PSD
66
63
 
67
64
  # Get the Header, parsing it if needed.
68
65
  def header
69
- @header ||= Header.read(@file)
66
+ return @header if @header
67
+
68
+ @header = Header.read(@file)
69
+ PSD.logger.debug @header.inspect
70
70
  end
71
71
 
72
72
  # Get the Resources section, parsing if needed.
@@ -78,6 +78,8 @@ class PSD
78
78
  @resources = Resources.new(@file)
79
79
  @resources.parse
80
80
 
81
+ PSD.logger.debug @resources.inspect
82
+
81
83
  return @resources.data
82
84
  end
83
85
 
@@ -40,6 +40,8 @@ class PSD
40
40
  @end_pos = @start_pos + @length
41
41
 
42
42
  @pixel_data = []
43
+
44
+ PSD.logger.debug "Image: #{width}x#{height}, length = #{@length}, mode = #{@header.mode_name}, position = #{@start_pos}"
43
45
  end
44
46
 
45
47
  # Begins parsing the image by first figuring out the compression format used, and then
@@ -49,9 +51,12 @@ class PSD
49
51
 
50
52
  # ZIP not implemented
51
53
  if [2, 3].include?(@compression)
54
+ PSD.logger.debug "Warning: ZIP image compression not supported yet. Skipping."
52
55
  @file.seek @end_pos and return
53
56
  end
54
57
 
58
+ PSD.logger.debug "Compression: id = #{@compression}, name = #{COMPRESSIONS[@compression]}"
59
+
55
60
  parse_image_data!
56
61
 
57
62
  return self
@@ -7,6 +7,7 @@ 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
+ PSD.logger.debug "Beginning PNG export"
10
11
  png = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)
11
12
 
12
13
  i = 0
@@ -29,7 +30,7 @@ class PSD::Image
29
30
 
30
31
  # Saves the PNG data to disk.
31
32
  def save_as_png(file)
32
- to_png.save(file)
33
+ to_png.save(file, :fast_rgba)
33
34
  end
34
35
  end
35
36
  end
@@ -25,6 +25,7 @@ class PSD::Image
25
25
  line_index = 0
26
26
 
27
27
  channels.times do |i|
28
+ PSD.logger.debug "Parsing RLE channel ##{i}: position = #{chan_pos}, line = #{line_index}"
28
29
  chan_pos = decode_rle_channel(chan_pos, line_index)
29
30
  line_index += height
30
31
  end
@@ -34,9 +35,9 @@ class PSD::Image
34
35
  height.times do |j|
35
36
  byte_count = @byte_counts[line_index]
36
37
  line_index += 1
37
- start = @file.tell
38
+ finish = @file.tell + byte_count
38
39
 
39
- while @file.tell < start + byte_count
40
+ while @file.tell < finish
40
41
  len = @file.read(1).bytes.to_a[0]
41
42
 
42
43
  if len < 128
@@ -4,21 +4,25 @@ class PSD::Image::Mode
4
4
  private
5
5
 
6
6
  def combine_rgb_channel
7
+ PSD.logger.debug "Beginning RGB processing"
8
+
7
9
  (0...@num_pixels).step(pixel_step) do |i|
8
- pixel = {r: 0, g: 0, b: 0, a: 255}
10
+ r = g = b = 0
11
+ a = 255
9
12
 
10
- PSD::Image::CHANNEL_INFO[0...channels].each_with_index do |chan, index|
13
+ PSD::Image::CHANNEL_INFO.each_with_index do |chan, index|
14
+ next if channels == 3 && chan[:id] == -1
11
15
  val = @channel_data[i + (@channel_length * index)]
12
16
 
13
17
  case chan[:id]
14
- when -1 then pixel[:a] = val
15
- when 0 then pixel[:r] = val
16
- when 1 then pixel[:g] = val
17
- when 2 then pixel[:b] = val
18
+ when -1 then a = val
19
+ when 0 then r = val
20
+ when 1 then g = val
21
+ when 2 then b = val
18
22
  end
19
23
  end
20
24
 
21
- @pixel_data.push *pixel.values
25
+ @pixel_data.push r, g, b, a
22
26
  end
23
27
  end
24
28
  end
@@ -68,6 +68,8 @@ class PSD
68
68
  parse_legacy_layer_name
69
69
  parse_extra_data
70
70
 
71
+ PSD.logger.debug "Layer name = #{name}"
72
+
71
73
  @file.seek @layer_end # Skip over any filler zeros
72
74
 
73
75
  end_section
@@ -310,21 +312,24 @@ class PSD
310
312
  LAYER_INFO.each do |name, info|
311
313
  next unless info.key == key
312
314
 
315
+ PSD.logger.debug "Layer Info: key = #{key}, start = #{pos}, length = #{length}"
316
+
313
317
  begin
314
318
  i = info.new(@file, length)
315
319
  i.parse
316
320
 
317
321
  @adjustments[name] = i
318
322
  info_parsed = true
319
- rescue Exception
323
+ rescue Exception => e
324
+ PSD.logger.error "Parsing error: key = #{key}, message = #{e.message}"
325
+ PSD.logger.error e.backtrace.join("\n")
320
326
  end
321
327
 
322
328
  break
323
329
  end
324
330
 
325
331
  if !info_parsed
326
- PSD.keys << key
327
- # puts "SKIPPING #{key}, length = #{length}"
332
+ PSD.logger.debug "SKIPPING: key = #{key}, length = #{length}"
328
333
  @file.seek pos + length
329
334
  end
330
335
 
@@ -64,7 +64,9 @@ class PSD
64
64
  layers.reverse!
65
65
  group_layers
66
66
 
67
- # Temporarily seek to the end of this section
67
+ parse_global_mask
68
+
69
+ # Ensure we're at the end of this section
68
70
  @file.seek finish
69
71
  end_section
70
72
 
@@ -102,5 +104,26 @@ class PSD
102
104
  end
103
105
  end
104
106
  end
107
+
108
+ def parse_global_mask
109
+ length = @file.read_int
110
+ return if length == 0
111
+
112
+ mask_end = @file.tell + length
113
+ PSD.logger.debug "Global Mask: length = #{length}"
114
+
115
+ @global_mask = {}
116
+ @global_mask[:overlay_color_space] = @file.read_short
117
+ @global_mask[:color_components] = 4.times.map { |i| @file.read_short >> 8 }
118
+ @global_mask[:opacity] = @file.read_short
119
+
120
+ # 0 = color selected, 1 = color protected, 128 = use value per layer
121
+ @global_mask[:kind] = @file.read(1).bytes.to_a[0]
122
+
123
+ PSD.logger.debug @global_mask
124
+
125
+ # Filler zeros
126
+ @file.seek mask_end
127
+ end
105
128
  end
106
129
  end
@@ -0,0 +1,42 @@
1
+ require 'logger'
2
+
3
+ class PSD
4
+ module Logger
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :debug
11
+
12
+ def logger
13
+ return @logger if @logger
14
+
15
+ if debug || ENV['PSD_DEBUG']
16
+ @logger = ::Logger.new(debug_output)
17
+ @logger.formatter = proc do |severity, datetime, progname, msg|
18
+ "#{severity}: #{msg}\n"
19
+ end
20
+ else
21
+ @logger = DisabledLogger.new
22
+ end
23
+
24
+ return @logger
25
+ end
26
+
27
+ def debug_output
28
+ if ENV['PSD_DEBUG']
29
+ ENV['PSD_DEBUG'] == 'STDOUT' ? STDOUT : ENV['PSD_DEBUG']
30
+ end
31
+
32
+ STDOUT
33
+ end
34
+ end
35
+ end
36
+
37
+ class DisabledLogger
38
+ def method_missing(method, *args, &block)
39
+ # silence
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  class PSD
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  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: 0.3.4
4
+ version: 0.3.5
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-07-31 00:00:00.000000000 Z
12
+ date: 2013-08-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bindata
@@ -119,6 +119,7 @@ extra_rdoc_files: []
119
119
  files:
120
120
  - .gitignore
121
121
  - .rspec
122
+ - CONTRIBUTING.md
122
123
  - Gemfile
123
124
  - Guardfile
124
125
  - LICENSE.txt
@@ -154,6 +155,7 @@ files:
154
155
  - lib/psd/layer_info/unicode_name.rb
155
156
  - lib/psd/layer_info/vector_mask.rb
156
157
  - lib/psd/layer_mask.rb
158
+ - lib/psd/logger.rb
157
159
  - lib/psd/mask.rb
158
160
  - lib/psd/node.rb
159
161
  - lib/psd/node_exporting.rb