Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 230 lines (204 sloc) 75.619 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
<!DOCTYPE html> <html> <head> <title>render.js</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 &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="events.html"> events.js </a> <a class="source" href="filters.html"> filters.js </a> <a class="source" href="header.html"> header.js </a> <a class="source" href="io.html"> io.js </a> <a class="source" href="layers.html"> layers.js </a> <a class="source" href="loader.html"> loader.js </a> <a class="source" href="pixelInfo.html"> pixelInfo.js </a> <a class="source" href="render.html"> render.js </a> <a class="source" href="util.html"> util.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> render.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>CamanJS's rendering system. This covers convolution kernels,
pixel-wise filters, and plugins. All of the actual pixel/image
manipulation is executed here when render() is called.</p> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/*global Caman: true */</span>
<span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">Caman</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>Defines how many slices we want to split the canvas up into for rendering.
While Javascript is not multi-threaded, it does help to make each rendering
job shorter, and to allow the browser more control in managing the render jobs.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <ul>
<li>SINGLE = traverse the image 1 pixel at a time</li>
<li>KERNEL = traverse the image using convolution kernels</li>
<li>LAYER_DEQUEUE = shift a layer off the canvasQueue</li>
<li>LAYER_FINISHED = finished processing a layer</li>
<li>LOAD_OVERLAY = load a local/remote image into the layer canvas</li>
<li>PLUGIN = executes a plugin function that isn't pixelwise or kernel</li>
</ul> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">SINGLE</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
  <span class="nx">KERNEL</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span>
  <span class="nx">LAYER_DEQUEUE</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
  <span class="nx">LAYER_FINISHED</span><span class="o">:</span> <span class="mi">4</span><span class="p">,</span>
  <span class="nx">LOAD_OVERLAY</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span>
  <span class="nx">PLUGIN</span><span class="o">:</span> <span class="mi">6</span>
<span class="p">};</span>

<span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">process</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">adjust</span><span class="p">,</span> <span class="nx">processFn</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Since the block-based renderer is asynchronous, we simply build
up a render queue and execute the filters in order once
render() is called instead of executing them as they're called
synchronously.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">renderQueue</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">adjust</span><span class="o">:</span> <span class="nx">adjust</span><span class="p">,</span> <span class="nx">processFn</span><span class="o">:</span> <span class="nx">processFn</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">SINGLE</span><span class="p">});</span>
  
  <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Process info about kernel and store it for later rendering.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">processKernel</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">adjust</span><span class="p">,</span> <span class="nx">divisor</span><span class="p">,</span> <span class="nx">bias</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">divisor</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>No divisor provided, so we need to calculate the default</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">divisor</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>The divisor is the sum of all the values in the convolution matrix</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">divisor</span> <span class="o">+=</span> <span class="nx">adjust</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
    <span class="p">}</span>
  <span class="p">}</span>
  </pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Store all of the info for this kernel in an object for later retrieval</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="nx">name</span><span class="p">,</span>
    <span class="nx">adjust</span><span class="o">:</span> <span class="nx">adjust</span><span class="p">,</span>
    <span class="nx">divisor</span><span class="o">:</span> <span class="nx">divisor</span><span class="p">,</span>
    <span class="nx">bias</span><span class="o">:</span> <span class="nx">bias</span> <span class="o">||</span> <span class="mi">0</span>
  <span class="p">};</span>
  </pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Add the convolution to the render queue and move on</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">renderQueue</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">adjust</span><span class="o">:</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">processFn</span><span class="o">:</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">processKernel</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">KERNEL</span><span class="p">});</span>
  
  <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Process an advanced plugin and add it to the render queue. Not much to do here since so much
of the control lies with the plugin itself.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">processPlugin</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">plugin</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">renderQueue</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">type</span><span class="o">:</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">PLUGIN</span><span class="p">,</span> <span class="nx">plugin</span><span class="o">:</span> <span class="nx">plugin</span><span class="p">,</span> <span class="nx">args</span><span class="o">:</span> <span class="nx">args</span><span class="p">});</span>
  <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Executes an advanced plugin. Simply calls the plugin function while setting the context to
the manip object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">executePlugin</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">plugin</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Executing plugin: &quot;</span> <span class="o">+</span> <span class="nx">plugin</span><span class="p">);</span>
  <span class="nx">Caman</span><span class="p">.</span><span class="nx">plugin</span><span class="p">[</span><span class="nx">plugin</span><span class="p">].</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Plugin &quot;</span> <span class="o">+</span> <span class="nx">plugin</span> <span class="o">+</span> <span class="s2">&quot; finished!&quot;</span><span class="p">);</span>
  </pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Continue to the next rendering operation</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">processNext</span><span class="p">();</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Begins the render process if it's not started, or moves to the next
filter in the queue and processes it. Calls the finishedFn callback
when the render queue is empty.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">processNext</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">finishedFn</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">finishedFn</span> <span class="o">===</span> <span class="s2">&quot;function&quot;</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Since this function is indirectly recursive, it would be a pain to pass the processFn
around each time. Instead, we simply store it with the manip object for later usage.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">finishedFn</span> <span class="o">=</span> <span class="nx">finishedFn</span><span class="p">;</span>
  <span class="p">}</span>
  </pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Rendering is complete when the render queue is empty</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">renderQueue</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Trigger the render finished event</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Caman</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">&quot;renderFinished&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">canvas_id</span><span class="p">});</span>
    </pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>If we have a render finished callback, execute it now</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="k">this</span><span class="p">.</span><span class="nx">finishedFn</span> <span class="o">===</span> <span class="s2">&quot;function&quot;</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">finishedFn</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>
  </pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Retrive the next operation from the render queue</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">renderQueue</span><span class="p">.</span><span class="nx">shift</span><span class="p">();</span>
  
  <span class="k">if</span> <span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">LAYER_DEQUEUE</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>New layer operative. Shift the next layer off the canvas queue and execute
it's transformations.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">layer</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">canvasQueue</span><span class="p">.</span><span class="nx">shift</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">executeLayer</span><span class="p">(</span><span class="nx">layer</span><span class="p">);</span>
    
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">LAYER_FINISHED</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Layer is finished rendering. Blend it with the parent layer, change context back to
the parent layer, and move onto the next operation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">applyCurrentLayer</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">popContext</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">processNext</span><span class="p">();</span>
    
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">LOAD_OVERLAY</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Load an image to be used as a layer overlay.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">loadOverlay</span><span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">layer</span><span class="p">,</span> <span class="nx">next</span><span class="p">.</span><span class="nx">src</span><span class="p">);</span>
    
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">PLUGIN</span><span class="p">)</span> <span class="p">{</span>
    </pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Execute an advanced plugin</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">executePlugin</span><span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">plugin</span><span class="p">,</span> <span class="nx">next</span><span class="p">.</span><span class="nx">args</span><span class="p">);</span>
    
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>Execute a normal pixel-wise filter and apply it to the current layer/canvas</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">executeFilter</span><span class="p">(</span><span class="nx">next</span><span class="p">.</span><span class="nx">adjust</span><span class="p">,</span> <span class="nx">next</span><span class="p">.</span><span class="nx">processFn</span><span class="p">,</span> <span class="nx">next</span><span class="p">.</span><span class="nx">type</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="nx">Caman</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span> <span class="nx">Caman</span><span class="p">,</span> <span class="p">{</span> </pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Convolution kernel rendering. Given an array of pixels based on the current location in the
rendering process, and a convolution matrix, calculate the new value of the kernel.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">processKernel</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">adjust</span><span class="p">,</span> <span class="nx">kernel</span><span class="p">,</span> <span class="nx">divisor</span><span class="p">,</span> <span class="nx">bias</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="p">{</span><span class="nx">r</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">g</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">b</span><span class="o">:</span> <span class="mi">0</span><span class="p">};</span>
    </pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Loop through each pixel in the kernel and apply it to the matching pixel in the matrix
from the image.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">val</span><span class="p">.</span><span class="nx">r</span> <span class="o">+=</span> <span class="nx">adjust</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">*</span> <span class="nx">kernel</span><span class="p">[</span><span class="nx">i</span> <span class="o">*</span> <span class="mi">3</span><span class="p">];</span>
      <span class="nx">val</span><span class="p">.</span><span class="nx">g</span> <span class="o">+=</span> <span class="nx">adjust</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">*</span> <span class="nx">kernel</span><span class="p">[</span><span class="nx">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">1</span><span class="p">];</span>
      <span class="nx">val</span><span class="p">.</span><span class="nx">b</span> <span class="o">+=</span> <span class="nx">adjust</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">*</span> <span class="nx">kernel</span><span class="p">[</span><span class="nx">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">2</span><span class="p">];</span>
    <span class="p">}</span>
    </pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Finally, apply the divisor and the bias to the calculated kernel</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">val</span><span class="p">.</span><span class="nx">r</span> <span class="o">=</span> <span class="p">(</span><span class="nx">val</span><span class="p">.</span><span class="nx">r</span> <span class="o">/</span> <span class="nx">divisor</span><span class="p">)</span> <span class="o">+</span> <span class="nx">bias</span><span class="p">;</span>
    <span class="nx">val</span><span class="p">.</span><span class="nx">g</span> <span class="o">=</span> <span class="p">(</span><span class="nx">val</span><span class="p">.</span><span class="nx">g</span> <span class="o">/</span> <span class="nx">divisor</span><span class="p">)</span> <span class="o">+</span> <span class="nx">bias</span><span class="p">;</span>
    <span class="nx">val</span><span class="p">.</span><span class="nx">b</span> <span class="o">=</span> <span class="p">(</span><span class="nx">val</span><span class="p">.</span><span class="nx">b</span> <span class="o">/</span> <span class="nx">divisor</span><span class="p">)</span> <span class="o">+</span> <span class="nx">bias</span><span class="p">;</span>

    <span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>The core of the image rendering, this function executes
the provided filter and updates the canvas pixel data
accordingly.</p>

<p>NOTE: this does not write the updated pixel
data to the canvas. That happens when all filters are finished
rendering in order to be as fast as possible.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">.</span><span class="nx">executeFilter</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">adjust</span><span class="p">,</span> <span class="nx">processFn</span><span class="p">,</span> <span class="nx">type</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Shortcut to the length of the pixel array</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">n</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span>
  </pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>(n/4) == # of pixels in image
Give remaining pixels to last block in case it doesn't
divide evenly.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">blockPixelLength</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">((</span><span class="nx">n</span> <span class="o">/</span> <span class="mi">4</span><span class="p">)</span> <span class="o">/</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span><span class="p">),</span>
  </pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>expand it again to make the loop easier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">blockN</span> <span class="o">=</span> <span class="nx">blockPixelLength</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span>
  </pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>add the remainder pixels to the last block.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">lastBlockN</span> <span class="o">=</span> <span class="nx">blockN</span> <span class="o">+</span> <span class="p">((</span><span class="nx">n</span> <span class="o">/</span> <span class="mi">4</span><span class="p">)</span> <span class="o">%</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span><span class="p">)</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Stupid context proxying >.></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span>
  </pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>Keep track of how many blocks are done so we know when rendering finishes</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">blocks_done</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
  </pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Called whenever a block finishes. It's used to determine when all blocks
finish rendering.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">block_finished</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">bnum</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">bnum</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Block #&quot;</span> <span class="o">+</span> <span class="nx">bnum</span> <span class="o">+</span> <span class="s2">&quot; finished! Filter: &quot;</span> <span class="o">+</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="nx">blocks_done</span><span class="o">++</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>All blocks finished rendering</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">blocks_done</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span> <span class="o">||</span> <span class="nx">bnum</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">if</span> <span class="p">(</span><span class="nx">bnum</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Filter &quot;</span> <span class="o">+</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot; finished!&quot;</span><span class="p">);</span>
      <span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Due to the nature of convolution, it does not divide the image into blocks</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Kernel filter finished!&quot;</span><span class="p">);</span>
      <span class="p">}</span>
      
      <span class="nx">Caman</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">&quot;processComplete&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="nx">self</span><span class="p">.</span><span class="nx">canvas_id</span><span class="p">,</span> <span class="nx">completed</span><span class="o">:</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">name</span><span class="p">});</span>
      </pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Since this filter is finished, it's time to move on to the next render operation</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">self</span><span class="p">.</span><span class="nx">processNext</span><span class="p">();</span>
    <span class="p">}</span>
  <span class="p">},</span>
  </pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>Renders a block of the image bounded by the start and end parameters.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render_block</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">bnum</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">end</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;BLOCK #&quot;</span> <span class="o">+</span> <span class="nx">bnum</span> <span class="o">+</span> <span class="s2">&quot; - Filter: &quot;</span> <span class="o">+</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;, Start: &quot;</span> <span class="o">+</span> <span class="nx">start</span> <span class="o">+</span> <span class="s2">&quot;, End: &quot;</span> <span class="o">+</span> <span class="nx">end</span><span class="p">);</span>
    
    <span class="kd">var</span> <span class="nx">renderFunc</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>Create an RGB object to pass to the filter functions</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">{</span><span class="nx">r</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">g</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">b</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">0</span><span class="p">};</span>
      </pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>Prepare the PixelInfo object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">pixelInfo</span> <span class="o">=</span> <span class="k">new</span> <span class="k">this</span><span class="p">.</span><span class="nx">pixelInfo</span><span class="p">(</span><span class="nx">self</span><span class="p">);</span>
      <span class="kd">var</span> <span class="nx">res</span><span class="p">;</span>
      
      <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">start</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">end</span><span class="p">;</span> <span class="nx">i</span> <span class="o">+=</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>Set the location of the pixelInfo object to the current pixel</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">pixelInfo</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="nx">i</span><span class="p">;</span>
        </pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>Update the values of the RGB object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">data</span><span class="p">.</span><span class="nx">r</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
        <span class="nx">data</span><span class="p">.</span><span class="nx">g</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span>
        <span class="nx">data</span><span class="p">.</span><span class="nx">b</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">2</span><span class="p">];</span>
        </pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>Execute the filter!</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">res</span> <span class="o">=</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">pixelInfo</span><span class="p">,</span> <span class="nx">adjust</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
        </pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Apply the modified RGB object to the current pixel array. These values are automatically clamped in
order to conform to the latest canvas spec.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">r</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">g</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">b</span><span class="p">);</span>
      <span class="p">}</span>
      </pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>Signal that this block is finished rendering</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">block_finished</span><span class="p">(</span><span class="nx">bnum</span><span class="p">);</span>
    <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    </pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Begin rendering asynchronously</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">renderFunc</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
  <span class="p">},</span>
  </pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Renders a convolution matrix. This is admittedly confusing, especially since it was designed with
flexibility in mind. Bear with me here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render_kernel</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
  </pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Function that executes the rendering process</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">renderFunc</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
      <span class="kd">var</span> <span class="nx">kernel</span> <span class="o">=</span> <span class="p">[],</span>
      <span class="nx">pixelInfo</span><span class="p">,</span> <span class="nx">pixel</span><span class="p">,</span>
      <span class="nx">start</span><span class="p">,</span> <span class="nx">end</span><span class="p">,</span>
      <span class="nx">mod_pixel_data</span><span class="p">,</span>
      <span class="nx">name</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span>
      <span class="nx">bias</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">bias</span><span class="p">,</span>
      <span class="nx">divisor</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">divisor</span><span class="p">,</span>
      <span class="nx">adjustSize</span><span class="p">,</span>
      <span class="nx">builder</span><span class="p">,</span> <span class="nx">builder_index</span><span class="p">,</span>
      <span class="nx">i</span><span class="p">,</span> <span class="nx">j</span><span class="p">,</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">res</span><span class="p">;</span>
      </pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Simple shortcut</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">adjust</span> <span class="o">=</span> <span class="nx">adjust</span><span class="p">.</span><span class="nx">adjust</span><span class="p">;</span>
      </pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>The size of one side of the convolutinon matrix is simply the square root (matrix must be square)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">adjustSize</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">sqrt</span><span class="p">(</span><span class="nx">adjust</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
      </pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Will store the modified pixel data since we can't directly update the original pixel array while
simultaneously modifing it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">mod_pixel_data</span> <span class="o">=</span> <span class="p">[];</span>
      
      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Rendering kernel - Filter: &quot;</span> <span class="o">+</span> <span class="nx">name</span><span class="p">);</span>
      </pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Calculate the beginning and end of the pixel array loop</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">start</span> <span class="o">=</span> <span class="nx">self</span><span class="p">.</span><span class="nx">dimensions</span><span class="p">.</span><span class="nx">width</span> <span class="o">*</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">((</span><span class="nx">adjustSize</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
      <span class="nx">end</span> <span class="o">=</span> <span class="nx">n</span> <span class="o">-</span> <span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">dimensions</span><span class="p">.</span><span class="nx">width</span> <span class="o">*</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">((</span><span class="nx">adjustSize</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
      </pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Calculate the index for the kernel we're going to generate for the current pixel. This is where it
begins to get confusing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">builder</span> <span class="o">=</span> <span class="p">(</span><span class="nx">adjustSize</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
      </pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>Set our pixelInfo object so we can easily grab pixels for the kernel.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">pixelInfo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">self</span><span class="p">.</span><span class="nx">pixelInfo</span><span class="p">(</span><span class="nx">self</span><span class="p">);</span>
      
      <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="nx">start</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">end</span><span class="p">;</span> <span class="nx">i</span> <span class="o">+=</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">pixelInfo</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="nx">i</span><span class="p">;</span>
        
        <span class="nx">builder_index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>This generates the kernel for the current pixel based on the size of the provided convolution matrix.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="nx">j</span> <span class="o">=</span> <span class="o">-</span><span class="nx">builder</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;=</span> <span class="nx">builder</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
          <span class="k">for</span> <span class="p">(</span><span class="nx">k</span> <span class="o">=</span> <span class="nx">builder</span><span class="p">;</span> <span class="nx">k</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="nx">builder</span><span class="p">;</span> <span class="nx">k</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">pixel</span> <span class="o">=</span> <span class="nx">pixelInfo</span><span class="p">.</span><span class="nx">getPixelRelative</span><span class="p">(</span><span class="nx">j</span><span class="p">,</span> <span class="nx">k</span><span class="p">);</span>
            <span class="nx">kernel</span><span class="p">[</span><span class="nx">builder_index</span> <span class="o">*</span> <span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="nx">pixel</span><span class="p">.</span><span class="nx">r</span><span class="p">;</span>
            <span class="nx">kernel</span><span class="p">[</span><span class="nx">builder_index</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">pixel</span><span class="p">.</span><span class="nx">g</span><span class="p">;</span>
            <span class="nx">kernel</span><span class="p">[</span><span class="nx">builder_index</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nx">pixel</span><span class="p">.</span><span class="nx">b</span><span class="p">;</span>
            
            <span class="nx">builder_index</span><span class="o">++</span><span class="p">;</span>
          <span class="p">}</span>
        <span class="p">}</span>
                </pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>Execute the kernel processing function</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">res</span> <span class="o">=</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">pixelInfo</span><span class="p">,</span> <span class="nx">adjust</span><span class="p">,</span> <span class="nx">kernel</span><span class="p">,</span> <span class="nx">divisor</span><span class="p">,</span> <span class="nx">bias</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>Update the new pixel array since we can't modify the original
until the convolutions are finished on the entire image.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">mod_pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">r</span><span class="p">);</span>
        <span class="nx">mod_pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">g</span><span class="p">);</span>
        <span class="nx">mod_pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">clampRGB</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">b</span><span class="p">);</span>
        <span class="nx">mod_pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="mi">255</span><span class="p">;</span>
      <span class="p">}</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>Update the actual canvas pixel data. Unfortunately we have to set
this one by one or else it won't work properly.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="nx">start</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">end</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">self</span><span class="p">.</span><span class="nx">pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">mod_pixel_data</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
      <span class="p">}</span>
      </pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>Signal that the kernel is done rendering.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">block_finished</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
      
    <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    </pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>Begin rendering the kernel asychronously</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">renderFunc</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
  <span class="p">};</span>
  
  <span class="nx">Caman</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">&quot;processStart&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">canvas_id</span><span class="p">,</span> <span class="nx">start</span><span class="o">:</span> <span class="nx">processFn</span><span class="p">.</span><span class="nx">name</span><span class="p">});</span>
  </pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Decide which type of filter we have to render.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">type</span> <span class="o">===</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">ProcessType</span><span class="p">.</span><span class="nx">SINGLE</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p>Split the image into its blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>Calculate the start and end for this image block.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">j</span> <span class="o">*</span> <span class="nx">blockN</span><span class="p">,</span>
      </pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>If this is the last block and there is some remainder, add it here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">end</span> <span class="o">=</span> <span class="nx">start</span> <span class="o">+</span> <span class="p">((</span><span class="nx">j</span> <span class="o">==</span> <span class="nx">Caman</span><span class="p">.</span><span class="nx">renderBlocks</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">?</span> <span class="nx">lastBlockN</span> <span class="o">:</span> <span class="nx">blockN</span><span class="p">);</span>
      </pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Begin rendering</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render_block</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">j</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">end</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Render the kernel</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render_kernel</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="nx">Caman</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Caman</span><span class="p">.</span><span class="nx">manip</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>Reverts an image back to its original state by re-initializing Caman</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">revert</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">ready</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">loadCanvas</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">image</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">canvas</span><span class="p">,</span> <span class="nx">ready</span><span class="p">);</span>
  <span class="p">},</span>
  </pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>The render function that the user uses in order to begin the rendering process.
Once all the rendering is complete, it applies the updated pixel data to the canvas
and calls the finished callback (if any).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">processNext</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">putImageData</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">image_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
      
      <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">callback</span> <span class="o">===</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">callback</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">});</span>
  <span class="p">}</span>
<span class="p">});</span>

<span class="p">}(</span><span class="nx">Caman</span><span class="p">));</span>

</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
Something went wrong with that request. Please try again.