Jump To …
READMElib / psd / blend_mode.coffeelib / psd / channel_image.coffeelib / psd / color.coffeelib / psd / descriptor.coffeelib / psd / file.coffeelib / psd / header.coffeelib / psd / image.coffeelib / psd / image_export.coffeelib / psd / image_exports / png.coffeelib / psd / image_format.coffeelib / psd / image_formats / layer_raw.coffeelib / psd / image_formats / layer_rle.coffeelib / psd / image_formats / raw.coffeelib / psd / image_formats / rle.coffeelib / psd / image_mode.coffeelib / psd / image_modes / cmyk.coffeelib / psd / image_modes / greyscale.coffeelib / psd / image_modes / rgb.coffeelib / psd / init.coffeelib / psd / layer / blend_modes.coffeelib / psd / layer / blending_ranges.coffeelib / psd / layer / channel_image.coffeelib / psd / layer / helpers.coffeelib / psd / layer / info.coffeelib / psd / layer / mask.coffeelib / psd / layer / name.coffeelib / psd / layer / position_channels.coffeelib / psd / layer.coffeelib / psd / layer_info / blend_clipping_elements.coffeelib / psd / layer_info / blend_interior_elements.coffeelib / psd / layer_info / fill_opacity.coffeelib / psd / layer_info / gradient_fill.coffeelib / psd / layer_info / layer_id.coffeelib / psd / layer_info / layer_name_source.coffeelib / psd / layer_info / legacy_typetool.coffeelib / psd / layer_info / locked.coffeelib / psd / layer_info / metadata.coffeelib / psd / layer_info / nested_section_divider.coffeelib / psd / layer_info / object_effects.coffeelib / psd / layer_info / section_divider.coffeelib / psd / layer_info / solid_color.coffeelib / psd / layer_info / typetool.coffeelib / psd / layer_info / unicode_name.coffeelib / psd / layer_info / vector_mask.coffeelib / psd / layer_info / vector_origination.coffeelib / psd / layer_info / vector_stroke.coffeelib / psd / layer_info / vector_stroke_content.coffeelib / psd / layer_info.coffeelib / psd / layer_mask.coffeelib / psd / lazy_execute.coffeelib / psd / mask.coffeelib / psd / node.coffeelib / psd / nodes / ancestry.coffeelib / psd / nodes / build_preview.coffeelib / psd / nodes / group.coffeelib / psd / nodes / layer.coffeelib / psd / nodes / root.coffeelib / psd / nodes / search.coffeelib / psd / path_record.coffeelib / psd / resource.coffeelib / psd / resource_section.coffeelib / psd / resources / layer_comps.coffeelib / psd / resources.coffeelib / psd / util.coffeelib / psd.coffeeshims / init.coffeeshims / png.coffee

image.coffee

lib/psd/
{Module}    = require 'coffeescript-module'

ImageFormat = require './image_format.coffee'
ImageMode   = require './image_mode.coffee'
Export      = require './image_export.coffee'

Represents the full preview image at the end of the PSD document. For this image, the compression is defined for all channels, and there is no mask data. The width and height are derived from the PSD header, which is the full size of the PSD document.

module.exports = class Image extends Module

Here we include all of our important mixins.

  @includes ImageFormat.RAW
  @includes ImageFormat.RLE
  @includes ImageMode.Greyscale
  @includes ImageMode.RGB
  @includes ImageMode.CMYK
  @includes Export.PNG
  

Images can be 1 of 4 different compression types. RLE is the most prevalent, followed by RAW. ZIP compression only happens under special circumstances, and is somewhat rare.

  COMPRESSIONS = [
    'Raw'
    'RLE'
    'ZIP'
    'ZIPPrediction'
  ]

  constructor: (@file, @header) ->

We can easily calculate the number of pixels with the width and height.

    @numPixels = @width() * @height()
    @numPixels *= 2 if @depth() is 16

    @calculateLength()

The resulting array that stores the pixel data, formatted in RGBA format.

    @pixelData = []

This temporarily holds the raw channel data after it's been parsed, but not processed.

    @channelData = []
    @opacity = 1.0
    @hasMask = false

    @startPos = @file.tell()
    @endPos = @startPos + @length

    @setChannelsInfo()

Some helper methods that grab data from the PSD header.

  for attr in ['width', 'height', 'channels', 'depth', 'mode'] then do (attr) =>
    @::[attr] = -> @header[attr]

Sets the channel info based on the PSD color mode.

  setChannelsInfo: ->
    switch @mode()
      when 1 then @setGreyscaleChannels()
      when 3 then @setRgbChannels()
      when 4 then @setCmykChannels()

Calculates the length of the image data.

  calculateLength: ->
    @length = switch @depth()
      when 1 then (@width() + 7) / 8 * @height()
      when 16 then @width() * @height() * 2
      else @width() * @height()

    @channelLength = @length
    @length *= @channels()

Parses the image and formats the image data.

  parse: ->
    @compression = @parseCompression()

    if @compression in [2, 3]
      @file.seek @endPos
      return

    @parseImageData()

Parses the compression mode.

  parseCompression: -> @file.readShort()
    

Parses the image data based on the compression mode.

  parseImageData: ->
    switch @compression
      when 0 then @parseRaw()
      when 1 then @parseRLE()
      when 2, 3 then @parseZip()
      else @file.seek(@endPos)

    @processImageData()

Processes the parsed image data based on the color mode.

  processImageData: ->
    switch @mode()
      when 1 then @combineGreyscaleChannel()
      when 3 then @combineRgbChannel()
      when 4 then @combineCmykChannel()

    @channelData = null

generated Tue May 12 2015 11:08:10 GMT-0400 (EDT)