{"version":3,"file":"image-blob-reduce.mjs","names":[],"sources":["../src/image_traverse.ts","../src/jpeg_plugins.ts","../src/index.ts"],"sourcesContent":["// ////////////////////////////////////////////////////////////////////////\n// Helpers\n//\ninterface ErrorWithCode extends Error {\n  code?: string\n}\n\ninterface JpegSegment {\n  code: number\n  offset: number\n  length: number\n}\n\ninterface ExifEntry {\n  is_big_endian: boolean\n  ifd: number\n  tag: number\n  format: number\n  count: number\n  entry_offset: number\n  data_length: number\n  data_offset: number\n  value: number[] | string | null\n  is_subifd_link: boolean\n}\n\ntype JpegSegmentIterator = (segment: JpegSegment) => unknown\ntype JpegSegmentFilter = (segment: JpegSegment) => unknown\ntype ExifEntryIterator = (entry: ExifEntry) => unknown\n\ninterface Ifd {\n  id: number\n  offset?: number\n  entries: ExifEntry[]\n  written_offset?: number\n  link_offset?: number\n}\n\ninterface IfdToRead {\n  id: number\n  offset: number\n}\n\ntype SegmentRange =\n  | { data: Uint8Array, start?: never, end?: never }\n  | { data?: never, start: number, end: number }\n\nfunction error (message: string, code?: string): ErrorWithCode {\n  const err = new Error(message) as ErrorWithCode\n  err.code = code\n  return err\n}\n\n// Convert number to 0xHH string\n//\nfunction to_hex (number: number): string {\n  let n = number.toString(16).toUpperCase()\n  for (let i = 2 - n.length; i > 0; i--) n = '0' + n\n  return '0x' + n\n}\n\nfunction utf8_encode (str: string): string {\n  try {\n    return unescape(encodeURIComponent(str))\n  } catch (_) {\n    return str\n  }\n}\n\nfunction utf8_decode (str: string): string {\n  try {\n    return decodeURIComponent(escape(str))\n  } catch (_) {\n    return str\n  }\n}\n\n// Check if input is a Uint8Array\n//\nfunction is_uint8array (bin: unknown): bin is Uint8Array {\n  return Object.prototype.toString.call(bin) === '[object Uint8Array]'\n}\n\n// ////////////////////////////////////////////////////////////////////////\n// Exif parser\n//\n// Input:\n//  - jpeg_bin:   Uint8Array - jpeg file\n//  - exif_start: Number     - start of TIFF header (after Exif\\0\\0)\n//  - exif_end:   Number     - end of Exif segment\n//  - on_entry:   Number     - callback\n//\nclass ExifParser {\n  input: Uint8Array\n  start: number\n  big_endian: boolean\n  aborted = false\n  ifds_to_read: IfdToRead[] = []\n  output: Uint8Array = new Uint8Array(0)\n\n  constructor (jpeg_bin: Uint8Array, exif_start: number, exif_end: number) {\n    // Uint8Array, exif without signature (which isn't included in offsets)\n    this.input = jpeg_bin.subarray(exif_start, exif_end)\n\n    // offset correction for `on_entry` callback\n    this.start = exif_start\n\n    // Check TIFF header (includes byte alignment and first IFD offset)\n    const sig = String.fromCharCode.apply(null, this.input.subarray(0, 4) as unknown as number[])\n\n    if (sig !== 'II\\x2A\\0' && sig !== 'MM\\0\\x2A') {\n      throw error('invalid TIFF signature', 'EBADDATA')\n    }\n\n    // true if motorola (big endian) byte alignment, false if intel\n    this.big_endian = sig[0] === 'M'\n  }\n\n  each (on_entry: ExifEntryIterator): void {\n    // allow premature exit\n    this.aborted = false\n\n    const offset = this.read_uint32(4)\n\n    this.ifds_to_read = [{\n      id: 0,\n      offset\n    }]\n\n    while (this.ifds_to_read.length > 0 && !this.aborted) {\n      const i = this.ifds_to_read.shift()\n      if (!i || !i.offset) continue\n      this.scan_ifd(i.id, i.offset, on_entry)\n    }\n  }\n\n  filter (on_entry: ExifEntryIterator): Uint8Array {\n    const ifds: Record<string, Ifd> = {}\n\n    // make sure IFD0 always exists\n    ifds.ifd0 = { id: 0, entries: [] }\n\n    this.each(function (entry: ExifEntry) {\n      if (on_entry(entry) === false && !entry.is_subifd_link) return\n      if (entry.is_subifd_link && entry.count !== 1 && entry.format !== 4) return // filter out bogus links\n\n      if (!ifds['ifd' + entry.ifd]) {\n        ifds['ifd' + entry.ifd] = { id: entry.ifd, entries: [] }\n      }\n\n      ifds['ifd' + entry.ifd].entries.push(entry)\n    })\n\n    // Thumbnails are not supported just yet, so delete all information related\n    // to them.\n    delete ifds.ifd1\n\n    // Calculate output size\n    let length = 8\n    Object.keys(ifds).forEach(function (ifd_no) {\n      length += 2\n\n      ifds[ifd_no].entries.forEach(function (entry: ExifEntry) {\n        length += 12 + (entry.data_length > 4 ? Math.ceil(entry.data_length / 2) * 2 : 0)\n      })\n\n      length += 4\n    })\n\n    this.output = new Uint8Array(length)\n    this.output[0] = this.output[1] = (this.big_endian ? 'M' : 'I').charCodeAt(0)\n    this.write_uint16(2, 0x2A)\n\n    let offset = 8\n    this.write_uint32(4, offset)\n\n    Object.keys(ifds).forEach((ifd_no) => {\n      ifds[ifd_no].written_offset = offset\n\n      const ifd_start = offset\n      const ifd_end = ifd_start + 2 + ifds[ifd_no].entries.length * 12 + 4\n      offset = ifd_end\n\n      this.write_uint16(ifd_start, ifds[ifd_no].entries.length)\n\n      ifds[ifd_no].entries.sort(function (a: ExifEntry, b: ExifEntry) {\n        // IFD entries must be in order of increasing tag IDs.\n        return a.tag - b.tag\n      }).forEach((entry: ExifEntry, idx: number) => {\n        const entry_offset = ifd_start + 2 + idx * 12\n\n        this.write_uint16(entry_offset, entry.tag)\n        this.write_uint16(entry_offset + 2, entry.format)\n        this.write_uint32(entry_offset + 4, entry.count)\n\n        if (entry.is_subifd_link) {\n          // Filled in later.\n          if (ifds['ifd' + entry.tag]) ifds['ifd' + entry.tag].link_offset = entry_offset + 8\n        } else if (entry.data_length <= 4) {\n          this.output.set(\n            this.input.subarray(entry.data_offset - this.start, entry.data_offset - this.start + 4),\n            entry_offset + 8\n          )\n        } else {\n          this.write_uint32(entry_offset + 8, offset)\n          this.output.set(\n            this.input.subarray(entry.data_offset - this.start, entry.data_offset - this.start + entry.data_length),\n            offset\n          )\n          offset += Math.ceil(entry.data_length / 2) * 2\n        }\n      })\n\n      const next_ifd = ifds['ifd' + (ifds[ifd_no].id + 1)]\n      if (next_ifd) next_ifd.link_offset = ifd_end - 4\n    })\n\n    Object.keys(ifds).forEach((ifd_no) => {\n      if (ifds[ifd_no].written_offset && ifds[ifd_no].link_offset) {\n        this.write_uint32(ifds[ifd_no].link_offset, ifds[ifd_no].written_offset)\n      }\n    })\n\n    if (this.output.length !== offset) throw error('internal error: incorrect buffer size allocated')\n\n    return this.output\n  }\n\n  read_uint16 (offset: number): number {\n    const d = this.input\n    if (offset + 2 > d.length) throw error('unexpected EOF', 'EBADDATA')\n\n    return this.big_endian\n      ? d[offset] * 0x100 + d[offset + 1]\n      : d[offset] + d[offset + 1] * 0x100\n  }\n\n  read_uint32 (offset: number): number {\n    const d = this.input\n    if (offset + 4 > d.length) throw error('unexpected EOF', 'EBADDATA')\n\n    return this.big_endian\n      ? d[offset] * 0x1000000 + d[offset + 1] * 0x10000 + d[offset + 2] * 0x100 + d[offset + 3]\n      : d[offset] + d[offset + 1] * 0x100 + d[offset + 2] * 0x10000 + d[offset + 3] * 0x1000000\n  }\n\n  write_uint16 (offset: number, value: number): void {\n    const d = this.output\n\n    if (this.big_endian) {\n      d[offset] = (value >>> 8) & 0xFF\n      d[offset + 1] = value & 0xFF\n    } else {\n      d[offset] = value & 0xFF\n      d[offset + 1] = (value >>> 8) & 0xFF\n    }\n  }\n\n  write_uint32 (offset: number, value: number): void {\n    const d = this.output\n\n    if (this.big_endian) {\n      d[offset] = (value >>> 24) & 0xFF\n      d[offset + 1] = (value >>> 16) & 0xFF\n      d[offset + 2] = (value >>> 8) & 0xFF\n      d[offset + 3] = value & 0xFF\n    } else {\n      d[offset] = value & 0xFF\n      d[offset + 1] = (value >>> 8) & 0xFF\n      d[offset + 2] = (value >>> 16) & 0xFF\n      d[offset + 3] = (value >>> 24) & 0xFF\n    }\n  }\n\n  is_subifd_link (ifd: number, tag: number): boolean {\n    return (ifd === 0 && tag === 0x8769) || // SubIFD\n           (ifd === 0 && tag === 0x8825) || // GPS Info\n           (ifd === 0x8769 && tag === 0xA005) // Interop IFD\n  }\n\n  // Returns the byte length of a single component of a given format.\n  //\n  exif_format_length (format: number): number {\n    switch (format) {\n      case 1: // byte\n      case 2: // ascii\n      case 6: // sbyte\n      case 7: // undefined\n        return 1\n\n      case 3: // short\n      case 8: // sshort\n        return 2\n\n      case 4: // long\n      case 9: // slong\n      case 11: // float\n        return 4\n\n      case 5: // rational\n      case 10: // srational\n      case 12: // double\n        return 8\n\n      default:\n      // Unknown type.\n        return 0\n    }\n  }\n\n  // Reads Exif data.\n  //\n  exif_format_read (format: number, offset: number): number | null {\n    let v\n\n    switch (format) {\n      case 1: // byte\n      case 2: // ascii\n        v = this.input[offset]\n        return v\n\n      case 6: // sbyte\n        v = this.input[offset]\n        return v | (v & 0x80) * 0x1fffffe\n\n      case 3: // short\n        v = this.read_uint16(offset)\n        return v\n\n      case 8: // sshort\n        v = this.read_uint16(offset)\n        return v | (v & 0x8000) * 0x1fffe\n\n      case 4: // long\n        v = this.read_uint32(offset)\n        return v\n\n      case 9: // slong\n        v = this.read_uint32(offset)\n        return v | 0\n\n      case 5: // rational\n      case 10: // srational\n      case 11: // float\n      case 12: // double\n        return null // not implemented\n\n      case 7: // undefined\n        return null // blob\n\n      default:\n      // Unknown type.\n        return null\n    }\n  }\n\n  scan_ifd (ifd_no: number, offset: number, on_entry: ExifEntryIterator): void {\n    const entry_count = this.read_uint16(offset)\n\n    offset += 2\n\n    for (let i = 0; i < entry_count; i++) {\n      const tag = this.read_uint16(offset)\n      const format = this.read_uint16(offset + 2)\n      const count = this.read_uint32(offset + 4)\n\n      const comp_length = this.exif_format_length(format)\n      const data_length = count * comp_length\n      const data_offset = data_length <= 4 ? offset + 8 : this.read_uint32(offset + 8)\n      let is_subifd_link = false\n\n      if (data_offset + data_length > this.input.length) {\n        throw error('unexpected EOF', 'EBADDATA')\n      }\n\n      let value: number[] | string | null = []\n      let comp_offset = data_offset\n\n      for (let j = 0; j < count; j++, comp_offset += comp_length) {\n        const item = this.exif_format_read(format, comp_offset)\n        if (item === null) {\n          value = null\n          break\n        }\n        value.push(item)\n      }\n\n      if (Array.isArray(value) && format === 2) {\n        try {\n          value = utf8_decode(String.fromCharCode.apply(null, value))\n        } catch (_) {\n          value = null\n        }\n\n        if (value && value[value.length - 1] === '\\0') value = value.slice(0, -1)\n      }\n\n      if (this.is_subifd_link(ifd_no, tag)) {\n        if (Array.isArray(value) && Number.isInteger(value[0]) && value[0] > 0) {\n          this.ifds_to_read.push({\n            id: tag,\n            offset: value[0]\n          })\n          is_subifd_link = true\n        }\n      }\n\n      const entry = {\n        is_big_endian: this.big_endian,\n        ifd: ifd_no,\n        tag,\n        format,\n        count,\n        entry_offset: offset + this.start,\n        data_length,\n        data_offset: data_offset + this.start,\n        value,\n        is_subifd_link\n      }\n\n      if (on_entry(entry) === false) {\n        this.aborted = true\n        return\n      }\n\n      offset += 12\n    }\n\n    if (ifd_no === 0) {\n      this.ifds_to_read.push({\n        id: 1,\n        offset: this.read_uint32(offset)\n      })\n    }\n  }\n}\n\n// Check whether input is a JPEG image\n//\n// Input:\n//  - jpeg_bin: Uint8Array - jpeg file\n//\n// Returns true if it is and false otherwise\n//\nfunction is_jpeg (jpeg_bin: Uint8Array): boolean {\n  return jpeg_bin.length >= 4 && jpeg_bin[0] === 0xFF && jpeg_bin[1] === 0xD8 && jpeg_bin[2] === 0xFF\n}\n\n// Call an iterator on each segment in the given JPEG image\n//\n// Input:\n//  - jpeg_bin:   Uint8Array - jpeg file\n//  - on_segment: Function - callback executed on each JPEG marker segment\n//    - segment:  Object\n//      - code:   Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n//      - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n//      - length: Number - length of the entire marker segment, including marker bytes and length field\n//        - 2 for standalone markers\n//        - 4+length for markers with data\n//\n// Iteration stops when `EOI` (0xFFD9) marker is reached or if `on_segment`\n// function returns `false`.\n//\nfunction jpeg_segments_each (jpeg_bin: Uint8Array, on_segment: JpegSegmentIterator): void {\n  if (!is_uint8array(jpeg_bin)) {\n    throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL')\n  }\n\n  if (typeof on_segment !== 'function') {\n    throw error('Invalid argument (on_segment), Function expected', 'EINVAL')\n  }\n\n  if (!is_jpeg(jpeg_bin)) {\n    throw error('Unknown file format', 'ENOTJPEG')\n  }\n\n  let offset = 0, inside_scan = false\n  const length = jpeg_bin.length\n\n  for (;;) {\n    let segment_code\n    let segment_length\n\n    if (offset + 1 >= length) throw error('Unexpected EOF', 'EBADDATA')\n    const byte1 = jpeg_bin[offset]\n    const byte2 = jpeg_bin[offset + 1]\n\n    if (byte1 === 0xFF && byte2 === 0xFF) {\n      // padding\n      segment_code = 0xFF\n      segment_length = 1\n    } else if (byte1 === 0xFF && byte2 !== 0) {\n      // marker\n      segment_code = byte2\n      segment_length = 2\n\n      if ((segment_code >= 0xD0 && segment_code <= 0xD9) || segment_code === 0x01) {\n        // standalone markers, according to JPEG 1992,\n        // http://www.w3.org/Graphics/JPEG/itu-t81.pdf, see Table B.1\n      } else {\n        if (offset + 3 >= length) throw error('Unexpected EOF', 'EBADDATA')\n        segment_length += jpeg_bin[offset + 2] * 0x100 + jpeg_bin[offset + 3]\n        if (segment_length < 2) throw error('Invalid segment length', 'EBADDATA')\n        if (offset + segment_length - 1 >= length) throw error('Unexpected EOF', 'EBADDATA')\n      }\n\n      if (inside_scan) {\n        if (segment_code >= 0xD0 && segment_code <= 0xD7) {\n          // reset markers\n        } else {\n          inside_scan = false\n        }\n      }\n\n      if (segment_code === 0xDA /* SOS */) inside_scan = true\n    } else if (inside_scan) {\n      // entropy-encoded segment\n      for (let pos = offset + 1; ; pos++) {\n        // scan until we find FF\n        if (pos >= length) throw error('Unexpected EOF', 'EBADDATA')\n        if (jpeg_bin[pos] === 0xFF) {\n          if (pos + 1 >= length) throw error('Unexpected EOF', 'EBADDATA')\n          if (jpeg_bin[pos + 1] !== 0) {\n            segment_code = 0\n            segment_length = pos - offset\n            break\n          }\n        }\n      }\n    } else {\n      throw error('Unexpected byte at segment start: ' + to_hex(byte1) +\n        ' (offset ' + to_hex(offset) + ')', 'EBADDATA')\n    }\n\n    if (on_segment({ code: segment_code, offset, length: segment_length }) === false) break\n    if (segment_code === 0xD9 /* EOI */) break\n    offset += segment_length\n  }\n}\n\n// Replace or remove segments in the given JPEG image\n//\n// Input:\n//  - jpeg_bin:   Uint8Array - jpeg file\n//  - on_segment: Function - callback executed on each JPEG marker segment\n//    - segment:  Object\n//      - code:   Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n//      - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n//      - length: Number - length of the entire marker segment, including marker bytes and length field\n//        - 2 for standalone markers\n//        - 4+length for markers with data\n//\n// `on_segment` function should return one of the following:\n//  - `false`        - segment is removed from the output\n//  - Uint8Array     - segment is replaced with the new data\n//  - [ Uint8Array ] - segment is replaced with the new data\n//  - anything else  - segment is copied to the output as is\n//\n// Any data after `EOI` (0xFFD9) marker is removed.\n//\nfunction jpeg_segments_filter (jpeg_bin: Uint8Array, on_segment: JpegSegmentFilter): Uint8Array {\n  if (!is_uint8array(jpeg_bin)) {\n    throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL')\n  }\n\n  if (typeof on_segment !== 'function') {\n    throw error('Invalid argument (on_segment), Function expected', 'EINVAL')\n  }\n\n  const ranges: SegmentRange[] = []\n  let out_length = 0\n\n  jpeg_segments_each(jpeg_bin, function (segment) {\n    const new_segment = on_segment(segment)\n\n    if (is_uint8array(new_segment)) {\n      ranges.push({ data: new_segment })\n      out_length += new_segment.length\n    } else if (Array.isArray(new_segment)) {\n      new_segment.filter(is_uint8array).forEach(function (s: Uint8Array) {\n        ranges.push({ data: s })\n        out_length += s.length\n      })\n    } else if (new_segment !== false) {\n      const new_range = { start: segment.offset, end: segment.offset + segment.length }\n\n      if (ranges.length > 0 && ranges[ranges.length - 1].end === new_range.start) {\n        ranges[ranges.length - 1].end = new_range.end\n      } else {\n        ranges.push(new_range)\n      }\n\n      out_length += segment.length\n    }\n  })\n\n  const result = new Uint8Array(out_length)\n  let offset = 0\n\n  ranges.forEach(function (range) {\n    const data = range.data || jpeg_bin.subarray(range.start, range.end)\n    result.set(data, offset)\n    offset += data.length\n  })\n\n  return result\n}\n\n// Call an iterator on each Exif entry in the given JPEG image\n//\n// Input:\n//  - jpeg_bin: Uint8Array - jpeg file\n//  - on_entry: Function - callback executed on each Exif entry\n//    - entry:  Object\n//      - is_big_endian:  Boolean - whether Exif uses big or little endian byte alignment\n//      - ifd:            Number  - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n//                                 0x8825 for GPS Info, 0xA005 for Interop IFD)\n//      - tag:            Number  - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n//      - format:         Number  - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n//      - count:          Number  - number of components of the given format inside data\n//                                 (usually 1, or string length for ascii format)\n//      - entry_offset:   Number  - start of Exif entry (entry length is always 12, so not included)\n//      - data_offset:    Number  - start of data attached to Exif entry (will overlap with entry if length <= 4)\n//      - data_length:    Number  - length of data attached to Exif entry\n//      - value:          Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n//      - is_subifd_link: Boolean - whether this entry is recognized as a link to SubIFD (can't filter these out)\n//\n// Iteration stops early if iterator returns `false`.\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed.\n//\nfunction jpeg_exif_tags_each (jpeg_bin: Uint8Array, on_exif_entry: ExifEntryIterator): void {\n  if (!is_uint8array(jpeg_bin)) {\n    throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL')\n  }\n\n  if (typeof on_exif_entry !== 'function') {\n    throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL')\n  }\n\n  jpeg_segments_each(jpeg_bin, function (segment) {\n    if (segment.code === 0xDA /* SOS */) return false\n\n    // Look for an APP1 segment and compare the header with 'Exif\\0\\0'.\n    if (segment.code === 0xE1 && segment.length >= 10 &&\n        jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n        jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n        jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n      new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length).each(on_exif_entry)\n      return false\n    }\n  })\n}\n\n// Remove Exif entries in the given JPEG image\n//\n// Input:\n//  - jpeg_bin: Uint8Array - jpeg file\n//  - on_entry: Function - callback executed on each Exif entry\n//    - entry:  Object\n//      - is_big_endian:  Boolean - whether Exif uses big or little endian byte alignment\n//      - ifd:            Number  - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n//                                  0x8825 for GPS Info, 0xA005 for Interop IFD)\n//      - tag:            Number  - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n//      - format:         Number  - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n//      - count:          Number  - number of components of the given format inside data\n//                                  (usually 1, or string length for ascii format)\n//      - entry_offset:   Number  - start of Exif entry (entry length is always 12, so not included)\n//      - data_offset:    Number  - start of data attached to Exif entry (will overlap with entry if length <= 4)\n//      - data_length:    Number  - length of data attached to Exif entry\n//      - value:          Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n//      - is_subifd_link: Boolean - whether this entry is recognized as a link to SubIFD (can't filter these out)\n//\n// This function removes the following from Exif:\n//  - all entries where the iterator returned false (except subifd links which are mandatory)\n//  - IFD1 and thumbnail image (the purpose of this function is to reduce file size,\n//    so thumbnail is usually the first thing to go)\n//  - all other data that isn't in IFD0, SubIFD, GPSIFD or InteropIFD\n//    (theoretically possible proprietary extensions, I haven't seen any of these yet)\n//\n// Changing data inside Exif entries is NOT supported yet (modifying the `entry` object inside the callback may break stuff).\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed, and original JPEG is returned as is.\n//\nfunction jpeg_exif_tags_filter (jpeg_bin: Uint8Array, on_exif_entry: ExifEntryIterator): Uint8Array {\n  if (!is_uint8array(jpeg_bin)) {\n    throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL')\n  }\n\n  if (typeof on_exif_entry !== 'function') {\n    throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL')\n  }\n\n  let stop_search = false\n\n  return jpeg_segments_filter(jpeg_bin, function (segment) {\n    if (stop_search) return\n    if (segment.code === 0xDA /* SOS */) stop_search = true\n\n    // Look for an APP1 segment and compare the header with 'Exif\\0\\0'.\n    if (segment.code === 0xE1 && segment.length >= 10 &&\n        jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n        jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n        jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n      const new_exif = new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length)\n        .filter(on_exif_entry)\n      if (!new_exif) return false\n\n      const header = new Uint8Array(10)\n\n      header.set(jpeg_bin.slice(segment.offset, segment.offset + 10))\n      header[2] = ((new_exif.length + 8) >>> 8) & 0xFF\n      header[3] = (new_exif.length + 8) & 0xFF\n\n      stop_search = true\n      return [header, new_exif]\n    }\n  })\n}\n\n// Inserts a custom comment marker segment into a JPEG file.\n//\n// Input:\n//  - jpeg_bin: Uint8Array - jpeg file\n//  - comment:  String\n//\n// The comment is inserted after the first two bytes (FFD8, SOI).\n//\n// If JFIF (APP0) marker exists immediately after SOI (as mandated by the JFIF\n// spec), we insert the comment after it instead.\n//\nfunction jpeg_add_comment (jpeg_bin: Uint8Array, comment: string): Uint8Array {\n  let comment_inserted = false, segment_count = 0\n\n  return jpeg_segments_filter(jpeg_bin, function (segment) {\n    segment_count++\n    if (segment_count === 1 && segment.code === 0xD8 /* SOI  */) return\n    if (segment_count === 2 && segment.code === 0xE0 /* APP0 */) return\n\n    if (comment_inserted) return\n    comment = utf8_encode(comment)\n\n    // comment segment\n    const csegment = new Uint8Array(5 + comment.length)\n    let offset = 0\n\n    csegment[offset++] = 0xFF\n    csegment[offset++] = 0xFE\n    csegment[offset++] = ((comment.length + 3) >>> 8) & 0xFF\n    csegment[offset++] = (comment.length + 3) & 0xFF\n\n    comment.split('').forEach(function (c) {\n      csegment[offset++] = c.charCodeAt(0) & 0xFF\n    })\n\n    csegment[offset++] = 0\n    comment_inserted = true\n\n    return [csegment, jpeg_bin.subarray(segment.offset, segment.offset + segment.length)]\n  })\n}\n\nexport {\n  is_jpeg,\n  jpeg_segments_each,\n  jpeg_segments_filter,\n  jpeg_exif_tags_each,\n  jpeg_exif_tags_filter,\n  jpeg_add_comment\n}\n\nexport type {\n  ErrorWithCode,\n  JpegSegment,\n  JpegSegmentIterator,\n  JpegSegmentFilter,\n  ExifEntry,\n  ExifEntryIterator\n}\n","import * as image_traverse from './image_traverse'\nimport type { ImageBlobReduce, ImageBlobReduceEnv } from './index'\n\nasync function jpeg_patch_exif (this: ImageBlobReduce, env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n  const data = await this._getUint8Array(env.blob)\n\n  env.is_jpeg = image_traverse.is_jpeg(data)\n\n  if (!env.is_jpeg) return env\n\n  env.orig_blob = env.blob\n\n  try {\n    let exif_is_big_endian: boolean | undefined\n    let orientation_offset: number | undefined\n\n    image_traverse.jpeg_exif_tags_each(data, function (entry) {\n      if (entry.ifd === 0 && entry.tag === 0x112 && Array.isArray(entry.value)) {\n        env.orientation = entry.value[0] || 1\n        exif_is_big_endian = entry.is_big_endian\n        orientation_offset = entry.data_offset\n        return false\n      }\n    })\n\n    if (orientation_offset) {\n      const orientation_patch = exif_is_big_endian\n        ? new Uint8Array([0, 1])\n        : new Uint8Array([1, 0])\n\n      env.blob = new Blob([\n        data.slice(0, orientation_offset),\n        orientation_patch,\n        data.slice(orientation_offset + 2)\n      ], { type: 'image/jpeg' })\n    }\n  } catch (_) {}\n\n  return env\n}\n\nasync function jpeg_rotate_canvas (this: ImageBlobReduce, env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n  if (!env.is_jpeg) return env\n\n  const orientation = (env.orientation || 1) - 1\n  if (!orientation) return env\n\n  let canvas\n\n  if (orientation & 4) {\n    canvas = this.pica.createCanvas(env.out_canvas!.height, env.out_canvas!.width)\n  } else {\n    canvas = this.pica.createCanvas(env.out_canvas!.width, env.out_canvas!.height)\n  }\n\n  const ctx = canvas.getContext('2d')!\n\n  ctx.save()\n\n  if (orientation & 1) ctx.transform(-1, 0, 0, 1, canvas.width, 0)\n  if (orientation & 2) ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height)\n  if (orientation & 4) ctx.transform(0, 1, 1, 0, 0, 0)\n\n  ctx.drawImage(env.out_canvas!, 0, 0)\n  ctx.restore()\n\n  // Safari 12 workaround\n  // https://github.com/nodeca/pica/issues/199\n  env.out_canvas!.width = env.out_canvas!.height = 0\n\n  env.out_canvas = canvas\n\n  return env\n}\n\nasync function jpeg_attach_orig_segments (this: ImageBlobReduce, env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n  if (!env.is_jpeg) return env\n\n  const [data, data_out] = await Promise.all([\n    this._getUint8Array(env.blob),\n    this._getUint8Array(env.out_blob!)\n  ])\n\n  if (!image_traverse.is_jpeg(data)) return env\n\n  const segments: image_traverse.JpegSegment[] = []\n\n  image_traverse.jpeg_segments_each(data, function (segment) {\n    if (segment.code === 0xDA /* SOS */) return false\n    segments.push(segment)\n  })\n\n  const segment_data = segments\n    .filter(function (segment) {\n      // Drop ICC_PROFILE\n      //\n      if (segment.code === 0xE2) return false\n\n      // Keep all APPn segments excluding APP2 (ICC_PROFILE),\n      // remove the others because most of them depend on image data\n      // (DCT and such).\n      //\n      // APP0 - JFIF, APP1 - Exif, the rest are Photoshop metadata and such.\n      //\n      // See full list at https://www.w3.org/Graphics/JPEG/itu-t81.pdf (table B.1 on page 32)\n      //\n      if (segment.code >= 0xE0 && segment.code < 0xF0) return true\n\n      // Keep comments\n      //\n      if (segment.code === 0xFE) return true\n\n      return false\n    })\n    .map(function (segment) {\n      return data.slice(segment.offset, segment.offset + segment.length)\n    })\n\n  env.out_blob = new Blob(\n    // Intentionally omit the expected JFIF segment (offset 2 to 20).\n    [data_out.slice(0, 2)].concat(segment_data).concat([data_out.slice(20)]),\n    { type: 'image/jpeg' }\n  )\n\n  return env\n}\n\nfunction assign (reducer: ImageBlobReduce): void {\n  reducer.before('_blob_to_image', jpeg_patch_exif)\n  reducer.after('_transform', jpeg_rotate_canvas)\n  reducer.after('_create_blob', jpeg_attach_orig_segments)\n}\n\nexport {\n  jpeg_patch_exif,\n  jpeg_rotate_canvas,\n  jpeg_attach_orig_segments,\n  assign\n}\n","import pica, { Pica } from 'pica'\nimport type { PicaCanvas, ResizeOptions as PicaResizeOptions } from 'pica'\nimport * as image_traverse from './image_traverse'\nimport * as jpeg_plugins from './jpeg_plugins'\n\ninterface ImageBlobReduceOptions {\n  pica?: Pica\n}\n\ntype ImageBlobReduceResizeOptions = PicaResizeOptions & {\n  max?: number\n}\n\ninterface ImageBlobReduceEnv {\n  blob: Blob\n  opts: ImageBlobReduceResizeOptions & { max: number }\n  image?: HTMLImageElement | null\n  image_url?: string | null\n  transform_width?: number | null\n  transform_height?: number | null\n  scale_factor?: number\n  out_canvas?: PicaCanvas\n  out_blob?: Blob\n  is_jpeg?: boolean\n  orig_blob?: Blob\n  orientation?: number\n}\n\ntype PipelineMethod = (env: ImageBlobReduceEnv) => Promise<ImageBlobReduceEnv>\ntype HookMethodName = '_blob_to_image' | '_calculate_size' | '_transform' | '_cleanup' | '_create_blob'\ntype Hook = (this: ImageBlobReduce, env: ImageBlobReduceEnv) => Promise<ImageBlobReduceEnv>\ntype Plugin = (reducer: ImageBlobReduce, ...params: unknown[]) => void\n\ninterface ObjectURLAPI {\n  createObjectURL: (blob: Blob) => string\n  revokeObjectURL?: (url: string) => void\n}\n\ntype LegacyWindow = Window & {\n  URL: ObjectURLAPI\n  webkitURL?: ObjectURLAPI\n  mozURL?: ObjectURLAPI\n  msURL?: ObjectURLAPI\n}\n\nclass ImageBlobReduce {\n  pica: Pica\n  private initialized: boolean\n  private _initPromise?: Promise<void>\n\n  constructor (options?: ImageBlobReduceOptions) {\n    options = options || {}\n\n    this.pica = options.pica || pica({})\n    this.initialized = false\n  }\n\n  use (plugin: Plugin, ...params: unknown[]): this {\n    plugin(this, ...params)\n    return this\n  }\n\n  setup (): void {\n    this.use(jpeg_plugins.assign)\n  }\n\n  private async _ensureInitialized (): Promise<void> {\n    if (!this._initPromise) {\n      this._initPromise = Promise.resolve()\n        .then(async () => {\n          this.setup()\n          await this.pica.init()\n          this.initialized = true\n        })\n    }\n\n    return this._initPromise\n  }\n\n  async toBlob (blob: Blob, options?: ImageBlobReduceResizeOptions): Promise<Blob> {\n    const opts = { max: Infinity, ...options }\n    let env: ImageBlobReduceEnv = {\n      blob,\n      opts\n    }\n\n    await this._ensureInitialized()\n\n    env = await this._blob_to_image(env)\n    env = await this._calculate_size(env)\n    env = await this._transform(env)\n    env = await this._cleanup(env)\n    env = await this._create_blob(env)\n\n    // Safari 12 workaround\n    // https://github.com/nodeca/pica/issues/199\n    env.out_canvas!.width = env.out_canvas!.height = 0\n\n    return env.out_blob!\n  }\n\n  async toCanvas (blob: Blob, options?: ImageBlobReduceResizeOptions): Promise<PicaCanvas> {\n    const opts = { max: Infinity, ...options }\n    let env: ImageBlobReduceEnv = {\n      blob,\n      opts\n    }\n\n    await this._ensureInitialized()\n\n    env = await this._blob_to_image(env)\n    env = await this._calculate_size(env)\n    env = await this._transform(env)\n    env = await this._cleanup(env)\n\n    return env.out_canvas!\n  }\n\n  before (method_name: HookMethodName, fn: Hook): this {\n    if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist')\n    if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected')\n\n    const old_fn = this[method_name] as PipelineMethod\n\n    this[method_name] = (async (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> => {\n      const _env = await fn.call(this, env)\n      return old_fn.call(this, _env)\n    }) as this[HookMethodName]\n\n    return this\n  }\n\n  after (method_name: HookMethodName, fn: Hook): this {\n    if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist')\n    if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected')\n\n    const old_fn = this[method_name] as PipelineMethod\n\n    this[method_name] = (async (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> => {\n      const _env = await old_fn.call(this, env)\n      return fn.call(this, _env)\n    }) as this[HookMethodName]\n\n    return this\n  }\n\n  _blob_to_image (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n    const win = window as LegacyWindow\n    const URL = win.URL || win.webkitURL || win.mozURL || win.msURL\n\n    env.image = document.createElement('img')\n    env.image_url = URL!.createObjectURL(env.blob)\n    env.image.src = env.image_url\n\n    return new Promise(function (resolve: (env: ImageBlobReduceEnv) => void, reject) {\n      env.image!.onerror = function () { reject(new Error('ImageBlobReduce: failed to create Image() from blob')) }\n      env.image!.onload = function () { resolve(env) }\n    })\n  }\n\n  async _calculate_size (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n    //\n    // Note: if you need non-symmetric resize logic, you MUST check\n    // `env.orientation` (set by plugins) and swap width/height appropriately.\n    //\n    let scale_factor = env.opts.max / Math.max(env.image!.width, env.image!.height)\n\n    if (scale_factor > 1) scale_factor = 1\n\n    env.transform_width = Math.max(Math.round(env.image!.width * scale_factor), 1)\n    env.transform_height = Math.max(Math.round(env.image!.height * scale_factor), 1)\n\n    // Info for user plugins to check whether scaling was applied.\n    env.scale_factor = scale_factor\n\n    return env\n  }\n\n  async _transform (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n    env.out_canvas = this.pica.createCanvas(env.transform_width!, env.transform_height!)\n\n    // Dim temporary env vars to prevent use and avoid confusion when orientation\n    // changes. Take the real size from the canvas.\n    env.transform_width = null\n    env.transform_height = null\n\n    const { max, ...pica_opts } = env.opts\n\n    await this.pica.resize(env.image!, env.out_canvas, pica_opts)\n\n    return env\n  }\n\n  async _cleanup (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n    env.image!.src = ''\n    env.image = null\n\n    const win = window as LegacyWindow\n    const URL = win.URL || win.webkitURL || win.mozURL || win.msURL\n    if (URL!.revokeObjectURL) URL!.revokeObjectURL(env.image_url!)\n\n    env.image_url = null\n\n    return env\n  }\n\n  async _create_blob (env: ImageBlobReduceEnv): Promise<ImageBlobReduceEnv> {\n    env.out_blob = await this.pica.toBlob(env.out_canvas!, env.blob.type)\n    return env\n  }\n\n  async _getUint8Array (blob: Blob): Promise<Uint8Array> {\n    if (blob.arrayBuffer) {\n      return new Uint8Array(await blob.arrayBuffer())\n    }\n\n    return new Promise(function (resolve: (data: Uint8Array) => void, reject) {\n      const fr = new FileReader()\n\n      fr.readAsArrayBuffer(blob)\n\n      fr.onload = function () { resolve(new Uint8Array(fr.result as ArrayBuffer)) }\n      fr.onerror = function () {\n        reject(new Error('ImageBlobReduce: failed to load data from input blob'))\n        fr.abort()\n      }\n      fr.onabort = function () {\n        reject(new Error('ImageBlobReduce: failed to load data from input blob (aborted)'))\n      }\n    })\n  }\n}\n\nfunction imageBlobReduce (options?: ImageBlobReduceOptions): ImageBlobReduce {\n  return new ImageBlobReduce(options)\n}\n\nexport {\n  ImageBlobReduce,\n  image_traverse,\n  pica,\n  Pica\n}\n\nexport type {\n  ImageBlobReduceEnv,\n  ImageBlobReduceOptions,\n  ImageBlobReduceResizeOptions,\n  Hook as ImageBlobReduceHook,\n  HookMethodName as ImageBlobReduceHookMethodName,\n  Plugin as ImageBlobReducePlugin\n}\n\nexport default imageBlobReduce\n"],"mappings":"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"}