dist/jspdf.node.debug.js
function putImage(img) {
    var objectNumber = this.internal.newObject(),
        out = this.internal.write,
        putStream = this.internal.putStream,
        getFilters = this.internal.getFilters;
    var filters = getFilters();

    while (filters.indexOf('FlateEncode') !== -1) {
      filters.splice(filters.indexOf('FlateEncode'), 1);
    }

    img['n'] = objectNumber;
    var additionalKeyValues = [];
    additionalKeyValues.push({
      key: 'Type',
      value: '/XObject'
    });
    additionalKeyValues.push({
      key: 'Subtype',
      value: '/Image'
    });
    additionalKeyValues.push({
      key: 'Width',
      value: img['w']
    });
    additionalKeyValues.push({
      key: 'Height',
      value: img['h']
    });

    if (img['cs'] === this.color_spaces.INDEXED) {
      additionalKeyValues.push({
        key: 'ColorSpace',
        value: '[/Indexed /DeviceRGB ' // if an indexed png defines more than one colour with transparency, we've created a smask
        + (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]'
      });
    } else {
      additionalKeyValues.push({
        key: 'ColorSpace',
        value: '/' + img['cs']
      });

      if (img['cs'] === this.color_spaces.DEVICE_CMYK) {
        additionalKeyValues.push({
          key: 'Decode',
          value: '[1 0 1 0 1 0 1 0]'
        });
      }
    }

    additionalKeyValues.push({
      key: 'BitsPerComponent',
      value: img['bpc']
    });

    if ('dp' in img) {
      additionalKeyValues.push({
        key: 'DecodeParms',
        value: '<<' + img['dp'] + '>>'
      });
    }

    if ('trns' in img && img['trns'].constructor == Array) {
      var trns = '',
          i = 0,
          len = img['trns'].length;

      for (; i < len; i++) {
        trns += img['trns'][i] + ' ' + img['trns'][i] + ' ';
      }

      additionalKeyValues.push({
        key: 'Mask',
        value: '[' + trns + ']'
      });
    }

    if ('smask' in img) {
      additionalKeyValues.push({
        key: 'SMask',
        value: objectNumber + 1 + ' 0 R'
      });
    }

    var alreadyAppliedFilters = typeof img['f'] !== "undefined" ? ['/' + img['f']] : undefined;
    putStream({
      data: img['data'],
      additionalKeyValues: additionalKeyValues,
      alreadyAppliedFilters: alreadyAppliedFilters
    });
    out('endobj'); // Soft mask

    if ('smask' in img) {
      var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];
      var smask = {
        'w': img['w'],
        'h': img['h'],
        'cs': 'DeviceGray',
        'bpc': img['bpc'],
        'dp': dp,
        'data': img['smask']
      };
      if ('f' in img) smask.f = img['f'];
      putImage.call(this, smask);
    } //Palette


    if (img['cs'] === this.color_spaces.INDEXED) {
      this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
      //putStream(zlib.compress(img['pal']));

      putStream({
        data: this.arrayBufferToBinaryString(new Uint8Array(img['pal']))
      });
      out('endobj');
    }
  }
function putImage(img) {
    var objectNumber = this.internal.newObject(),
        out = this.internal.write,
        putStream = this.internal.putStream,
        getFilters = this.internal.getFilters;
    var filters = getFilters();

    while (filters.indexOf('FlateEncode') !== -1) {
      filters.splice(filters.indexOf('FlateEncode'), 1);
    }

    img['n'] = objectNumber;
    var additionalKeyValues = [];
    additionalKeyValues.push({
      key: 'Type',
      value: '/XObject'
    });
    additionalKeyValues.push({
      key: 'Subtype',
      value: '/Image'
    });
    additionalKeyValues.push({
      key: 'Width',
      value: img['w']
    });
    additionalKeyValues.push({
      key: 'Height',
      value: img['h']
    });

    if (img['cs'] === this.color_spaces.INDEXED) {
      additionalKeyValues.push({
        key: 'ColorSpace',
        value: '[/Indexed /DeviceRGB ' // if an indexed png defines more than one colour with transparency, we've created a smask
        + (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]'
      });
    } else {
      additionalKeyValues.push({
        key: 'ColorSpace',
        value: '/' + img['cs']
      });

      if (img['cs'] === this.color_spaces.DEVICE_CMYK) {
        additionalKeyValues.push({
          key: 'Decode',
          value: '[1 0 1 0 1 0 1 0]'
        });
      }
    }

    additionalKeyValues.push({
      key: 'BitsPerComponent',
      value: img['bpc']
    });

    if ('dp' in img) {
      additionalKeyValues.push({
        key: 'DecodeParms',
        value: '<<' + img['dp'] + '>>'
      });
    }

    if ('trns' in img && img['trns'].constructor == Array) {
      var trns = '',
          i = 0,
          len = img['trns'].length;

      for (; i < len; i++) {
        trns += img['trns'][i] + ' ' + img['trns'][i] + ' ';
      }

      additionalKeyValues.push({
        key: 'Mask',
        value: '[' + trns + ']'
      });
    }

    if ('smask' in img) {
      additionalKeyValues.push({
        key: 'SMask',
        value: objectNumber + 1 + ' 0 R'
      });
    }

    var alreadyAppliedFilters = typeof img['f'] !== "undefined" ? ['/' + img['f']] : undefined;
    putStream({
      data: img['data'],
      additionalKeyValues: additionalKeyValues,
      alreadyAppliedFilters: alreadyAppliedFilters
    });
    out('endobj'); // Soft mask

    if ('smask' in img) {
      var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];
      var smask = {
        'w': img['w'],
        'h': img['h'],
        'cs': 'DeviceGray',
        'bpc': img['bpc'],
        'dp': dp,
        'data': img['smask']
      };
      if ('f' in img) smask.f = img['f'];
      putImage.call(this, smask);
    } //Palette


    if (img['cs'] === this.color_spaces.INDEXED) {
      this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
      //putStream(zlib.compress(img['pal']));

      putStream({
        data: this.arrayBufferToBinaryString(new Uint8Array(img['pal']))
      });
      out('endobj');
    }
  }
Image functionality ported from pdf.js