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

# channel_image.coffee

lib/psd/

¶

    _           = require 'lodash'
    Image       = require './image.coffee'
    ImageFormat = require './image_format.coffee'

¶

Represents an image for a single layer, which differs slightly in format from the full size preview image.

The full preview at the end of the PSD document has the same compression for all channels, whereas layer images define the compression per color channel. The dimensions can also differ per channel if we're parsing mask data (channel ID < -1).

    module.exports = class ChannelImage extends Image
      @includes ImageFormat.LayerRAW
      @includes ImageFormat.LayerRLE

¶

Creates a new ChannelImage.

      constructor: (file, header, @layer) ->

¶

We copy the layer's width and height to private variables because, as you'll see below, the dimensions can change if we're parsing a mask channel.

        @_width = @layer.width
        @_height = @layer.height

        super(file, header)

        @channelsInfo = @layer.channelsInfo
        @hasMask = _.any @channelsInfo, (c) -> c.id < -1
        @opacity = @layer.opacity / 255.0
        @maskData = []

¶

Skip parsing this image by jumping to the end of the data.

      skip: ->
        for chan in @channelsInfo
          @file.seek chan.length, true

¶

The width of the image.

      width: -> @_width

¶

The height of the image.

      height: -> @_height

¶

The number of color channels in the image.

      channels: -> @layer.channels

¶

Parse the image data. The resulting image data will be formatted to match the Javascript Canvas color format, e.g. `[R, G, B, A, R, G, B, A]`.

      parse: ->
        @chanPos = 0
        for chan in @channelsInfo
          if chan.length <= 0
            @parseCompression()
            continue

          @chan = chan

¶

If we're working with a mask channel, then the mask can define it's own dimensions separate from the image dimensions. We grab these dimensions from the layer's mask data.

          if chan.id < -1
            @_width = @layer.mask.width
            @_height = @layer.mask.height
          else
            @_width = @layer.width
            @_height = @layer.height

          @length = @_width * @_height
          start = @file.tell()

          @parseImageData()

          finish = @file.tell()

          if finish isnt start + @chan.length
            @file.seek(start + @chan.length)

        @_width = @layer.width
        @_height = @layer.height

        @processImageData()

¶

Initiates parsing of the image data, which is based on the compression type of the channel. Every channel defines it's own compression type, unlike the full PSD preview, which has a single compression type for the entire image.

      parseImageData: ->
        @compression = @parseCompression()

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

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