PsdLayer constructor

PsdLayer([
  1. InputBuffer? input
])

Implementation

PsdLayer([InputBuffer? input]) {
  if (input == null) {
    return;
  }

  top = input.readInt32();
  left = input.readInt32();
  bottom = input.readInt32();
  right = input.readInt32();
  width = right - left!;
  height = bottom - top!;

  channels = [];
  final numChannels = input.readUint16();
  for (var i = 0; i < numChannels; ++i) {
    final id = input.readInt16();
    final len = input.readUint32();
    channels.add(PsdChannel(id, len));
  }

  final sig = input.readUint32();
  if (sig != SIGNATURE) {
    throw ImageException('Invalid PSD layer signature: '
        '${sig.toRadixString(16)}');
  }

  blendMode = input.readUint32();
  opacity = input.readByte();
  clipping = input.readByte();
  flags = input.readByte();

  final filler = input.readByte(); // should be 0
  if (filler != 0) {
    throw ImageException('Invalid PSD layer data');
  }

  var len = input.readUint32();
  final extra = input.readBytes(len);

  if (len > 0) {
    // Mask Data
    len = extra.readUint32();
    assert(len == 0 || len == 20 || len == 36);
    if (len > 0) {
      final maskData = extra.readBytes(len);
      mask = PsdMask(maskData);
    }

    // Layer Blending Ranges
    len = extra.readUint32();
    if (len > 0) {
      final data = extra.readBytes(len);
      blendingRanges = PsdBlendingRanges(data);
    }

    // Layer name
    len = extra.readByte();
    name = extra.readString(len);
    // Layer name is padded to a multiple of 4 bytes.
    final padding = (4 - (len % 4)) - 1;
    if (padding > 0) {
      extra.skip(padding);
    }

    // Additional layer sections
    while (!extra.isEOS) {
      final sig = extra.readUint32();
      if (sig != SIGNATURE) {
        throw ImageException('PSD invalid signature for layer additional '
            'data: ${sig.toRadixString(16)}');
      }

      final tag = extra.readString(4);

      len = extra.readUint32();
      final data = extra.readBytes(len);
      // pad to an even byte count.
      if (len & 1 == 1) {
        extra.skip(1);
      }

      additionalData[tag] = PsdLayerData(tag, data);

      // Layer effects data
      if (tag == 'lrFX') {
        final fxData = (additionalData['lrFX'] as PsdLayerAdditionalData);
        final data = InputBuffer.from(fxData.data);
        /*int version =*/
        data.readUint16();
        final numFx = data.readUint16();

        for (var j = 0; j < numFx; ++j) {
          /*var tag =*/ data.readString(4); // 8BIM
          final fxTag = data.readString(4);
          final size = data.readUint32();

          if (fxTag == 'dsdw') {
            final fx = PsdDropShadowEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.blur = data.readUint32();
            fx.intensity = data.readUint32();
            fx.angle = data.readUint32();
            fx.distance = data.readUint32();
            fx.color = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.blendMode = data.readString(8);
            fx.enabled = data.readByte() != 0;
            fx.globalAngle = data.readByte() != 0;
            fx.opacity = data.readByte();
            fx.nativeColor = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
          } else if (fxTag == 'isdw') {
            final fx = PsdInnerShadowEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.blur = data.readUint32();
            fx.intensity = data.readUint32();
            fx.angle = data.readUint32();
            fx.distance = data.readUint32();
            fx.color = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.blendMode = data.readString(8);
            fx.enabled = data.readByte() != 0;
            fx.globalAngle = data.readByte() != 0;
            fx.opacity = data.readByte();
            fx.nativeColor = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
          } else if (fxTag == 'oglw') {
            final fx = PsdOuterGlowEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.blur = data.readUint32();
            fx.intensity = data.readUint32();
            fx.color = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.blendMode = data.readString(8);
            fx.enabled = data.readByte() != 0;
            fx.opacity = data.readByte();
            if (fx.version == 2) {
              fx.nativeColor = [
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16()
              ];
            }
          } else if (fxTag == 'iglw') {
            final fx = PsdInnerGlowEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.blur = data.readUint32();
            fx.intensity = data.readUint32();
            fx.color = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.blendMode = data.readString(8);
            fx.enabled = data.readByte() != 0;
            fx.opacity = data.readByte();
            if (fx.version == 2) {
              fx.invert = data.readByte() != 0;
              fx.nativeColor = [
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16()
              ];
            }
          } else if (fxTag == 'bevl') {
            final fx = PsdBevelEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.angle = data.readUint32();
            fx.strength = data.readUint32();
            fx.blur = data.readUint32();
            fx.highlightBlendMode = data.readString(8);
            fx.shadowBlendMode = data.readString(8);
            fx.highlightColor = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.shadowColor = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.bevelStyle = data.readByte();
            fx.highlightOpacity = data.readByte();
            fx.shadowOpacity = data.readByte();
            fx.enabled = data.readByte() != 0;
            fx.globalAngle = data.readByte() != 0;
            fx.upOrDown = data.readByte();
            if (fx.version == 2) {
              fx.realHighlightColor = [
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16()
              ];
              fx.realShadowColor = [
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16(),
                data.readUint16()
              ];
            }
          } else if (fxTag == 'sofi') {
            final fx = PsdSolidFillEffect();
            effects.add(fx);
            fx.version = data.readUint32();
            fx.blendMode = data.readString(4);
            fx.color = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
            fx.opacity = data.readByte();
            fx.enabled = data.readByte() != 0;
            fx.nativeColor = [
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16(),
              data.readUint16()
            ];
          } else {
            data.skip(size);
          }
        }
      }
    }
  }
}