psd
Version:
A general purpose Photoshop file parser.
80 lines (70 loc) • 19.6 kB
HTML
<html><head><title>lazy_execute.coffee</title><meta http-equiv="Content-Type" content="text/html" charset="UTF-8"><link rel="stylesheet" media="all" href="../../docco.css"></head><body><div id="container"><div id="background"></div><div id="jump_to">Jump To …<div id="jump_wrapper"><div id="jump_page"><a href="../../index.html" class="source"><span class="file_name">README</span></a><a href="../../lib/psd/blend_mode.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">blend_mode.coffee</span></a><a href="../../lib/psd/channel_image.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">channel_image.coffee</span></a><a href="../../lib/psd/color.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">color.coffee</span></a><a href="../../lib/psd/descriptor.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">descriptor.coffee</span></a><a href="../../lib/psd/file.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">file.coffee</span></a><a href="../../lib/psd/header.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">header.coffee</span></a><a href="../../lib/psd/image.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">image.coffee</span></a><a href="../../lib/psd/image_export.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">image_export.coffee</span></a><a href="../../lib/psd/image_exports/png.coffee.html" class="source "><span class="base_path">lib / psd / image_exports / </span><span class="file_name">png.coffee</span></a><a href="../../lib/psd/image_format.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">image_format.coffee</span></a><a href="../../lib/psd/image_formats/layer_raw.coffee.html" class="source "><span class="base_path">lib / psd / image_formats / </span><span class="file_name">layer_raw.coffee</span></a><a href="../../lib/psd/image_formats/layer_rle.coffee.html" class="source "><span class="base_path">lib / psd / image_formats / </span><span class="file_name">layer_rle.coffee</span></a><a href="../../lib/psd/image_formats/raw.coffee.html" class="source "><span class="base_path">lib / psd / image_formats / </span><span class="file_name">raw.coffee</span></a><a href="../../lib/psd/image_formats/rle.coffee.html" class="source "><span class="base_path">lib / psd / image_formats / </span><span class="file_name">rle.coffee</span></a><a href="../../lib/psd/image_mode.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">image_mode.coffee</span></a><a href="../../lib/psd/image_modes/cmyk.coffee.html" class="source "><span class="base_path">lib / psd / image_modes / </span><span class="file_name">cmyk.coffee</span></a><a href="../../lib/psd/image_modes/greyscale.coffee.html" class="source "><span class="base_path">lib / psd / image_modes / </span><span class="file_name">greyscale.coffee</span></a><a href="../../lib/psd/image_modes/rgb.coffee.html" class="source "><span class="base_path">lib / psd / image_modes / </span><span class="file_name">rgb.coffee</span></a><a href="../../lib/psd/init.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">init.coffee</span></a><a href="../../lib/psd/layer/blend_modes.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">blend_modes.coffee</span></a><a href="../../lib/psd/layer/blending_ranges.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">blending_ranges.coffee</span></a><a href="../../lib/psd/layer/channel_image.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">channel_image.coffee</span></a><a href="../../lib/psd/layer/helpers.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">helpers.coffee</span></a><a href="../../lib/psd/layer/info.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">info.coffee</span></a><a href="../../lib/psd/layer/mask.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">mask.coffee</span></a><a href="../../lib/psd/layer/name.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">name.coffee</span></a><a href="../../lib/psd/layer/position_channels.coffee.html" class="source "><span class="base_path">lib / psd / layer / </span><span class="file_name">position_channels.coffee</span></a><a href="../../lib/psd/layer.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">layer.coffee</span></a><a href="../../lib/psd/layer_info/blend_clipping_elements.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">blend_clipping_elements.coffee</span></a><a href="../../lib/psd/layer_info/blend_interior_elements.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">blend_interior_elements.coffee</span></a><a href="../../lib/psd/layer_info/fill_opacity.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">fill_opacity.coffee</span></a><a href="../../lib/psd/layer_info/gradient_fill.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">gradient_fill.coffee</span></a><a href="../../lib/psd/layer_info/layer_id.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">layer_id.coffee</span></a><a href="../../lib/psd/layer_info/layer_name_source.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">layer_name_source.coffee</span></a><a href="../../lib/psd/layer_info/legacy_typetool.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">legacy_typetool.coffee</span></a><a href="../../lib/psd/layer_info/locked.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">locked.coffee</span></a><a href="../../lib/psd/layer_info/metadata.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">metadata.coffee</span></a><a href="../../lib/psd/layer_info/nested_section_divider.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">nested_section_divider.coffee</span></a><a href="../../lib/psd/layer_info/object_effects.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">object_effects.coffee</span></a><a href="../../lib/psd/layer_info/section_divider.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">section_divider.coffee</span></a><a href="../../lib/psd/layer_info/solid_color.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">solid_color.coffee</span></a><a href="../../lib/psd/layer_info/typetool.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">typetool.coffee</span></a><a href="../../lib/psd/layer_info/unicode_name.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">unicode_name.coffee</span></a><a href="../../lib/psd/layer_info/vector_mask.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">vector_mask.coffee</span></a><a href="../../lib/psd/layer_info/vector_origination.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">vector_origination.coffee</span></a><a href="../../lib/psd/layer_info/vector_stroke.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">vector_stroke.coffee</span></a><a href="../../lib/psd/layer_info/vector_stroke_content.coffee.html" class="source "><span class="base_path">lib / psd / layer_info / </span><span class="file_name">vector_stroke_content.coffee</span></a><a href="../../lib/psd/layer_info.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">layer_info.coffee</span></a><a href="../../lib/psd/layer_mask.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">layer_mask.coffee</span></a><a href="../../lib/psd/lazy_execute.coffee.html" class="source selected"><span class="base_path">lib / psd / </span><span class="file_name">lazy_execute.coffee</span></a><a href="../../lib/psd/mask.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">mask.coffee</span></a><a href="../../lib/psd/node.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">node.coffee</span></a><a href="../../lib/psd/nodes/ancestry.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">ancestry.coffee</span></a><a href="../../lib/psd/nodes/build_preview.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">build_preview.coffee</span></a><a href="../../lib/psd/nodes/group.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">group.coffee</span></a><a href="../../lib/psd/nodes/layer.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">layer.coffee</span></a><a href="../../lib/psd/nodes/root.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">root.coffee</span></a><a href="../../lib/psd/nodes/search.coffee.html" class="source "><span class="base_path">lib / psd / nodes / </span><span class="file_name">search.coffee</span></a><a href="../../lib/psd/path_record.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">path_record.coffee</span></a><a href="../../lib/psd/resource.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">resource.coffee</span></a><a href="../../lib/psd/resource_section.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">resource_section.coffee</span></a><a href="../../lib/psd/resources/layer_comps.coffee.html" class="source "><span class="base_path">lib / psd / resources / </span><span class="file_name">layer_comps.coffee</span></a><a href="../../lib/psd/resources.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">resources.coffee</span></a><a href="../../lib/psd/util.coffee.html" class="source "><span class="base_path">lib / psd / </span><span class="file_name">util.coffee</span></a><a href="../../lib/psd.coffee.html" class="source "><span class="base_path">lib / </span><span class="file_name">psd.coffee</span></a><a href="../../shims/init.coffee.html" class="source "><span class="base_path">shims / </span><span class="file_name">init.coffee</span></a><a href="../../shims/png.coffee.html" class="source "><span class="base_path">shims / </span><span class="file_name">png.coffee</span></a></div></div></div><table cellpadding="0" cellspacing="0"><thead><tr><th class="docs"><h1>lazy_execute.coffee</h1><div class="filepath">lib/psd/</div></th><th class="code"></th></tr></thead><tbody><tr id="section-1"><td class="docs"><div class="pilwrap"><a href="#section-1" class="pilcrow">¶</a></div><p>LazyExecute is very important when it comes to speed. Because some PSD documents
can be extremely large and hold a LOT of data, we can significantly speed up
parsing by temporarily skipping over chunks of the PSD. Chances are that you aren't
going to use every piece of data in the document. This means, when you do request
some data that's proxied through LazyExecute, we can parse it on the fly. This overhead
should be incredibly minimal.</p>
<p>While not as elegant as the PSD.rb counterpart, it gets the job done. We look at the
object we need to proxy, and define proxies for every item on its prototype on this
one. The proxy checks to see if the object has been loaded first before passing on
the call to the object.</p>
<p>If the object has not been loaded yet, we record our current position in the file, jump
to the known start position of the data, parse it by calling a set method on the object,
jump back to the original position in the file, and then call the proxied property.</p>
<h2 id="example">Example</h2>
<pre><code class="lang-coffeescript">obj = new SomeObject()
data = new LazyExecute(obj, file)
.now('skip')
.later('parse')
.ignore('foo', 'bar')
.get()
</code></pre>
</td><td class="code"><div class="highlight"><pre><span class="nv">module.exports = </span><span class="k">class</span> <span class="nx">LazyExecute</span>
<span class="nv">constructor: </span><span class="nf">(@obj, @file) -></span>
<span class="vi">@startPos = </span><span class="nx">@file</span><span class="p">.</span><span class="nx">tell</span><span class="p">()</span>
<span class="vi">@loaded = </span><span class="kc">false</span>
<span class="vi">@loadMethod = </span><span class="kc">null</span>
<span class="vi">@loadArgs = </span><span class="p">[]</span>
<span class="vi">@passthru = </span><span class="p">[]</span></pre></div></td></tr><tr id="section-2"><td class="docs"><div class="pilwrap"><a href="#section-2" class="pilcrow">¶</a></div><p>This describes the method that we want to run at object instantiation. Typically this
will skip over the data that we will parse on-demand later. We can pass any arguments
we want to the method as well.</p>
</td><td class="code"><div class="highlight"><pre> <span class="nv">now: </span><span class="nf">(method, args...) -></span>
<span class="nx">@obj</span><span class="p">[</span><span class="nx">method</span><span class="p">].</span><span class="nx">apply</span><span class="p">(</span><span class="nx">@obj</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">@</span></pre></div></td></tr><tr id="section-3"><td class="docs"><div class="pilwrap"><a href="#section-3" class="pilcrow">¶</a></div><p>Here we describe the method we want to run when the first method/property on the object
is accessed. We can also define any arguments that need to be passed to the function.</p>
</td><td class="code"><div class="highlight"><pre> <span class="nv">later: </span><span class="nf">(method, args...) -></span>
<span class="vi">@loadMethod = </span><span class="nx">method</span>
<span class="vi">@loadArgs = </span><span class="nx">args</span>
<span class="k">return</span> <span class="nx">@</span></pre></div></td></tr><tr id="section-4"><td class="docs"><div class="pilwrap"><a href="#section-4" class="pilcrow">¶</a></div><p>Sometimes we don't have to parse the data in order to get some important information.
For example, we can get the widht/height from the full preview image without parsing the
image itself, since that data comes from the header. Purely convenience, but helps to
optimize usage.</p>
<p>The arguments are a list of method/property names we don't want to trigger on-demand parsing.</p>
</td><td class="code"><div class="highlight"><pre> <span class="nv">ignore: </span><span class="nf">(args...) -></span>
<span class="nx">@passthru</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">args</span>
<span class="k">return</span> <span class="nx">@</span></pre></div></td></tr><tr id="section-5"><td class="docs"><div class="pilwrap"><a href="#section-5" class="pilcrow">¶</a></div><p>This is called once all of the paramters of the proxy have been set up, i.e. now, later, and skip.
This defines all items on the proxied objects prototype on this object, and checks to make sure
the proxied object has been loaded before passing on the call.</p>
</td><td class="code"><div class="highlight"><pre> <span class="nv">get: </span><span class="nf">-></span>
<span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@obj</span> <span class="k">then</span> <span class="nx">do</span> <span class="nf">(key, val) =></span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">?</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span> <span class="nx">@</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span>
<span class="nv">get: </span><span class="nf">-></span>
<span class="nx">@load</span><span class="p">()</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">@loaded</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">@passthru</span><span class="p">)</span>
<span class="nx">@obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="nx">@</span></pre></div></td></tr><tr id="section-6"><td class="docs"><div class="pilwrap"><a href="#section-6" class="pilcrow">¶</a></div><p>If we are accessing a property for the first time, then this will call the load method, which
was defined during setup with <code>later()</code>. The steps this performs are:</p>
<ol>
<li>Records the current file position.</li>
<li>Jumps to the recorded start position for the proxied data.</li>
<li>Calls the load method, which was defined with <code>later()</code>.</li>
<li>Jumps back to the original file position.</li>
<li>Sets the <code>@loaded</code> flag to true so we know this object has been parsed.</li>
</ol>
</td><td class="code"><div class="highlight"><pre> <span class="nv">load: </span><span class="nf">-></span>
<span class="nv">origPos = </span><span class="nx">@file</span><span class="p">.</span><span class="nx">tell</span><span class="p">()</span>
<span class="nx">@file</span><span class="p">.</span><span class="nx">seek</span> <span class="nx">@startPos</span>
<span class="nx">@obj</span><span class="p">[</span><span class="nx">@loadMethod</span><span class="p">].</span><span class="nx">apply</span><span class="p">(</span><span class="nx">@obj</span><span class="p">,</span> <span class="nx">@loadArgs</span><span class="p">)</span>
<span class="nx">@file</span><span class="p">.</span><span class="nx">seek</span> <span class="nx">origPos</span>
<span class="vi">@loaded = </span><span class="kc">true</span>
</pre></div></td></tr></tbody></table><div id="generated">generated Tue May 12 2015 11:08:14 GMT-0400 (EDT) </div></div></body></html>