1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.TXIOutputFormat = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const stream_1 = require("stream");
|
6 | const image_codec_txi_1 = require("@fitbit/image-codec-txi");
|
7 | Object.defineProperty(exports, "TXIOutputFormat", { enumerable: true, get: function () { return image_codec_txi_1.TXIOutputFormat; } });
|
8 | const plugin_error_1 = tslib_1.__importDefault(require("plugin-error"));
|
9 | const pngjs_1 = require("@fitbit/pngjs");
|
10 | const PLUGIN_NAME = 'convertImageToTXI';
|
11 | function pickOutputFormat(image, rgbaOutputFormat = image_codec_txi_1.TXIOutputFormat.RGBA8888) {
|
12 | if (!image.color)
|
13 | return image_codec_txi_1.TXIOutputFormat.A8;
|
14 | if (!image.alpha)
|
15 | return image_codec_txi_1.TXIOutputFormat.RGB565;
|
16 | return rgbaOutputFormat;
|
17 | }
|
18 | function transformPNG(png, rgbaOutputFormat) {
|
19 | return new Promise((resolve, reject) => {
|
20 | png.on('metadata', (metadata) => {
|
21 | png.on('parsed', () => {
|
22 | try {
|
23 | const txi = image_codec_txi_1.encode({
|
24 | data: new Uint8ClampedArray(png.data),
|
25 | width: png.width,
|
26 | height: png.height,
|
27 | }, {
|
28 | outputFormat: pickOutputFormat(metadata, rgbaOutputFormat),
|
29 | rle: 'auto',
|
30 | });
|
31 | resolve(Buffer.from(txi));
|
32 | }
|
33 | catch (e) {
|
34 | reject(e);
|
35 | }
|
36 | });
|
37 | });
|
38 | png.on('error', reject);
|
39 | });
|
40 | }
|
41 | function transformPNGBuffer(file, rgbaOutputFormat) {
|
42 | const png = new pngjs_1.PNG();
|
43 | const transformer = transformPNG(png, rgbaOutputFormat);
|
44 | png.parse(file);
|
45 | return transformer;
|
46 | }
|
47 | function transformPNGStream(file, rgbaOutputFormat) {
|
48 | let started = false;
|
49 | return new stream_1.Readable({
|
50 | read() {
|
51 | if (started)
|
52 | return;
|
53 | started = true;
|
54 | const png = new pngjs_1.PNG();
|
55 | transformPNG(png, rgbaOutputFormat)
|
56 | .then((txi) => {
|
57 | this.push(txi);
|
58 | this.push(null);
|
59 | })
|
60 | .catch((error) => this.emit('error', error));
|
61 | file.on('error', (err) => this.emit('error', err)).pipe(png);
|
62 | },
|
63 | });
|
64 | }
|
65 | function convertImageToTXI(options = {}) {
|
66 | return new stream_1.Transform({
|
67 | objectMode: true,
|
68 | transform(file, _, cb) {
|
69 | if (file.isNull() || file.extname !== '.png') {
|
70 | return cb(undefined, file);
|
71 | }
|
72 | const fileName = file.relative;
|
73 | file.basename += '.txi';
|
74 | if (file.isBuffer()) {
|
75 | transformPNGBuffer(file.contents, options.rgbaOutputFormat)
|
76 | .then((txi) => {
|
77 | file.contents = txi;
|
78 | cb(undefined, file);
|
79 | })
|
80 | .catch((err) => cb(new plugin_error_1.default(PLUGIN_NAME, err, { fileName })));
|
81 | }
|
82 | else if (file.isStream()) {
|
83 | file.contents = transformPNGStream(file.contents, options.rgbaOutputFormat).on('error', (err) => this.emit('error', new plugin_error_1.default(PLUGIN_NAME, err, { fileName })));
|
84 | cb(undefined, file);
|
85 | }
|
86 | },
|
87 | });
|
88 | }
|
89 | exports.default = convertImageToTXI;
|