{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import type { Filter } from \"@vibrant/color\";\n\nexport { Histogram } from \"./histogram\";\nexport type { HistogramOptions } from \"./histogram\";\n\n/**\n * HTMLImageElement - browser only\n * Buffer - Node.js only\n */\nexport type ImageSource = string | HTMLImageElement | Buffer;\n\nexport type Pixels = Uint8ClampedArray | Buffer;\nexport interface ImageData {\n\tdata: Pixels;\n\twidth: number;\n\theight: number;\n}\n\nexport interface ImageOptions {\n\t/**\n\t * Scale down factor used in downsampling stage. 1 means no downsampling. If `maxDimension` is set, this value will not be used.\n\t * @default 5\n\t */\n\tquality: number;\n\t/**\n\t * The max size of the image's longer side used in downsampling stage. This field will override `quality`.\n\t * @default undefined\n\t */\n\tmaxDimension: number;\n}\n\nexport interface Image {\n\tload(image: ImageSource): Promise<Image>;\n\tclear(): void;\n\tupdate(imageData: ImageData): void;\n\tgetWidth(): number;\n\tgetHeight(): number;\n\tresize(targetWidth: number, targetHeight: number, ratio: number): void;\n\tgetPixelCount(): number;\n\tgetImageData(): ImageData;\n\tremove(): void;\n\tscaleDown(opts: ImageOptions): void;\n}\n\nexport interface ImageClass {\n\tnew (): Image;\n}\n\nexport abstract class ImageBase implements Image {\n\tabstract load(image: ImageSource): Promise<ImageBase>;\n\tabstract clear(): void;\n\tabstract update(imageData: ImageData): void;\n\tabstract getWidth(): number;\n\tabstract getHeight(): number;\n\tabstract resize(\n\t\ttargetWidth: number,\n\t\ttargetHeight: number,\n\t\tratio: number,\n\t): void;\n\tabstract getPixelCount(): number;\n\tabstract getImageData(): ImageData;\n\tabstract remove(): void;\n\n\tscaleDown(opts: ImageOptions): void {\n\t\tconst width: number = this.getWidth();\n\t\tconst height: number = this.getHeight();\n\n\t\tlet ratio = 1;\n\n\t\tif (opts.maxDimension > 0) {\n\t\t\tconst maxSide: number = Math.max(width, height);\n\t\t\tif (maxSide > opts.maxDimension) ratio = opts.maxDimension / maxSide;\n\t\t} else {\n\t\t\tratio = 1 / opts.quality;\n\t\t}\n\n\t\tif (ratio < 1) this.resize(width * ratio, height * ratio, ratio);\n\t}\n}\n\n/**\n * @private\n */\nexport function applyFilters(imageData: ImageData, filters: Filter[]) {\n\tif (filters.length > 0) {\n\t\tconst pixels = imageData.data;\n\t\tconst n = pixels.length / 4;\n\t\tlet offset;\n\t\tlet r;\n\t\tlet g;\n\t\tlet b;\n\t\tlet a;\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\toffset = i * 4;\n\t\t\tr = pixels[offset + 0]!;\n\t\t\tg = pixels[offset + 1]!;\n\t\t\tb = pixels[offset + 2]!;\n\t\t\ta = pixels[offset + 3]!;\n\t\t\t// Mark ignored color\n\t\t\tfor (let j = 0; j < filters.length; j++) {\n\t\t\t\tif (!filters[j]?.(r, g, b, a)) {\n\t\t\t\t\tpixels[offset + 3] = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn imageData;\n}\n"],"names":[],"mappings":";;;AAgDO,MAAe,UAA2B;AAAA,EAehD,UAAU,MAA0B;AACnC,UAAM,QAAgB,KAAK,SAAA;AAC3B,UAAM,SAAiB,KAAK,UAAA;AAE5B,QAAI,QAAQ;AAEZ,QAAI,KAAK,eAAe,GAAG;AAC1B,YAAM,UAAkB,KAAK,IAAI,OAAO,MAAM;AAC9C,UAAI,UAAU,KAAK,aAAc,SAAQ,KAAK,eAAe;AAAA,IAC9D,OAAO;AACN,cAAQ,IAAI,KAAK;AAAA,IAClB;AAEA,QAAI,QAAQ,EAAG,MAAK,OAAO,QAAQ,OAAO,SAAS,OAAO,KAAK;AAAA,EAChE;AACD;AAKO,SAAS,aAAa,WAAsB,SAAmB;AACrE,MAAI,QAAQ,SAAS,GAAG;AACvB,UAAM,SAAS,UAAU;AACzB,UAAM,IAAI,OAAO,SAAS;AAC1B,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,eAAS,IAAI;AACb,UAAI,OAAO,SAAS,CAAC;AACrB,UAAI,OAAO,SAAS,CAAC;AACrB,UAAI,OAAO,SAAS,CAAC;AACrB,UAAI,OAAO,SAAS,CAAC;AAErB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,YAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG;AAC9B,iBAAO,SAAS,CAAC,IAAI;AACrB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;;;;"}