123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673 |
- 'use strict';
- var fs = require('fs');
- var util = require('util');
- var Stream = require('stream');
- var zlib = require('zlib');
- var require$$0 = require('assert');
- var require$$1 = require('buffer');
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
- var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
- var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
- var Stream__default = /*#__PURE__*/_interopDefaultLegacy(Stream);
- var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
- var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
- var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
- var pixelmatch_1 = pixelmatch;
- function pixelmatch(img1, img2, output, width, height, options) {
- if (!options) options = {};
- var threshold = options.threshold === undefined ? 0.1 : options.threshold;
- // maximum acceptable square distance between two colors;
- // 35215 is the maximum possible value for the YIQ difference metric
- var maxDelta = 35215 * threshold * threshold,
- diff = 0;
- // compare each pixel of one image against the other one
- for (var y = 0; y < height; y++) {
- for (var x = 0; x < width; x++) {
- var pos = (y * width + x) * 4;
- // squared YUV distance between colors at this pixel position
- var delta = colorDelta(img1, img2, pos, pos);
- // the color difference is above the threshold
- if (delta > maxDelta) {
- // check it's a real rendering difference or just anti-aliasing
- if (!options.includeAA && (antialiased(img1, x, y, width, height, img2) ||
- antialiased(img2, x, y, width, height, img1))) {
- // one of the pixels is anti-aliasing; draw as yellow and do not count as difference
- if (output) drawPixel(output, pos, 255, 255, 0);
- } else {
- // found substantial difference not caused by anti-aliasing; draw it as red
- if (output) drawPixel(output, pos, 255, 0, 0);
- diff++;
- }
- } else if (output) {
- // pixels are similar; draw background as grayscale image blended with white
- var val = blend(grayPixel(img1, pos), 0.1);
- drawPixel(output, pos, val, val, val);
- }
- }
- }
- // return the number of different pixels
- return diff;
- }
- // check if a pixel is likely a part of anti-aliasing;
- // based on "Anti-aliased Pixel and Intensity Slope Detector" paper by V. Vysniauskas, 2009
- function antialiased(img, x1, y1, width, height, img2) {
- var x0 = Math.max(x1 - 1, 0),
- y0 = Math.max(y1 - 1, 0),
- x2 = Math.min(x1 + 1, width - 1),
- y2 = Math.min(y1 + 1, height - 1),
- pos = (y1 * width + x1) * 4,
- zeroes = 0,
- positives = 0,
- negatives = 0,
- min = 0,
- max = 0,
- minX, minY, maxX, maxY;
- // go through 8 adjacent pixels
- for (var x = x0; x <= x2; x++) {
- for (var y = y0; y <= y2; y++) {
- if (x === x1 && y === y1) continue;
- // brightness delta between the center pixel and adjacent one
- var delta = colorDelta(img, img, pos, (y * width + x) * 4, true);
- // count the number of equal, darker and brighter adjacent pixels
- if (delta === 0) zeroes++;
- else if (delta < 0) negatives++;
- else if (delta > 0) positives++;
- // if found more than 2 equal siblings, it's definitely not anti-aliasing
- if (zeroes > 2) return false;
- if (!img2) continue;
- // remember the darkest pixel
- if (delta < min) {
- min = delta;
- minX = x;
- minY = y;
- }
- // remember the brightest pixel
- if (delta > max) {
- max = delta;
- maxX = x;
- maxY = y;
- }
- }
- }
- if (!img2) return true;
- // if there are no both darker and brighter pixels among siblings, it's not anti-aliasing
- if (negatives === 0 || positives === 0) return false;
- // if either the darkest or the brightest pixel has more than 2 equal siblings in both images
- // (definitely not anti-aliased), this pixel is anti-aliased
- return (!antialiased(img, minX, minY, width, height) && !antialiased(img2, minX, minY, width, height)) ||
- (!antialiased(img, maxX, maxY, width, height) && !antialiased(img2, maxX, maxY, width, height));
- }
- // calculate color difference according to the paper "Measuring perceived color difference
- // using YIQ NTSC transmission color space in mobile applications" by Y. Kotsarenko and F. Ramos
- function colorDelta(img1, img2, k, m, yOnly) {
- var a1 = img1[k + 3] / 255,
- a2 = img2[m + 3] / 255,
- r1 = blend(img1[k + 0], a1),
- g1 = blend(img1[k + 1], a1),
- b1 = blend(img1[k + 2], a1),
- r2 = blend(img2[m + 0], a2),
- g2 = blend(img2[m + 1], a2),
- b2 = blend(img2[m + 2], a2),
- y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2);
- if (yOnly) return y; // brightness difference only
- var i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),
- q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);
- return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q;
- }
- function rgb2y(r, g, b) { return r * 0.29889531 + g * 0.58662247 + b * 0.11448223; }
- function rgb2i(r, g, b) { return r * 0.59597799 - g * 0.27417610 - b * 0.32180189; }
- function rgb2q(r, g, b) { return r * 0.21147017 - g * 0.52261711 + b * 0.31114694; }
- // blend semi-transparent color with white
- function blend(c, a) {
- return 255 + (c - 255) * a;
- }
- function drawPixel(output, pos, r, g, b) {
- output[pos + 0] = r;
- output[pos + 1] = g;
- output[pos + 2] = b;
- output[pos + 3] = 255;
- }
- function grayPixel(img, i) {
- var a = img[i + 3] / 255,
- r = blend(img[i + 0], a),
- g = blend(img[i + 1], a),
- b = blend(img[i + 2], a);
- return rgb2y(r, g, b);
- }
- function createCommonjsModule(fn, basedir, module) {
- return module = {
- path: basedir,
- exports: {},
- require: function (path, base) {
- return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
- }
- }, fn(module, module.exports), module.exports;
- }
- function commonjsRequire () {
- throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
- }
- var chunkstream = createCommonjsModule(function (module) {
- var ChunkStream = module.exports = function() {
- Stream__default['default'].call(this);
- this._buffers = [];
- this._buffered = 0;
- this._reads = [];
- this._paused = false;
- this._encoding = 'utf8';
- this.writable = true;
- };
- util__default['default'].inherits(ChunkStream, Stream__default['default']);
- ChunkStream.prototype.read = function(length, callback) {
- this._reads.push({
- length: Math.abs(length), // if length < 0 then at most this length
- allowLess: length < 0,
- func: callback
- });
- process.nextTick(function() {
- this._process();
- // its paused and there is not enought data then ask for more
- if (this._paused && this._reads.length > 0) {
- this._paused = false;
- this.emit('drain');
- }
- }.bind(this));
- };
- ChunkStream.prototype.write = function(data, encoding) {
- if (!this.writable) {
- this.emit('error', new Error('Stream not writable'));
- return false;
- }
- var dataBuffer;
- if (Buffer.isBuffer(data)) {
- dataBuffer = data;
- }
- else {
- dataBuffer = new Buffer(data, encoding || this._encoding);
- }
- this._buffers.push(dataBuffer);
- this._buffered += dataBuffer.length;
- this._process();
- // ok if there are no more read requests
- if (this._reads && this._reads.length === 0) {
- this._paused = true;
- }
- return this.writable && !this._paused;
- };
- ChunkStream.prototype.end = function(data, encoding) {
- if (data) {
- this.write(data, encoding);
- }
- this.writable = false;
- // already destroyed
- if (!this._buffers) {
- return;
- }
- // enqueue or handle end
- if (this._buffers.length === 0) {
- this._end();
- }
- else {
- this._buffers.push(null);
- this._process();
- }
- };
- ChunkStream.prototype.destroySoon = ChunkStream.prototype.end;
- ChunkStream.prototype._end = function() {
- if (this._reads.length > 0) {
- this.emit('error',
- new Error('Unexpected end of input')
- );
- }
- this.destroy();
- };
- ChunkStream.prototype.destroy = function() {
- if (!this._buffers) {
- return;
- }
- this.writable = false;
- this._reads = null;
- this._buffers = null;
- this.emit('close');
- };
- ChunkStream.prototype._processReadAllowingLess = function(read) {
- // ok there is any data so that we can satisfy this request
- this._reads.shift(); // == read
- // first we need to peek into first buffer
- var smallerBuf = this._buffers[0];
- // ok there is more data than we need
- if (smallerBuf.length > read.length) {
- this._buffered -= read.length;
- this._buffers[0] = smallerBuf.slice(read.length);
- read.func.call(this, smallerBuf.slice(0, read.length));
- }
- else {
- // ok this is less than maximum length so use it all
- this._buffered -= smallerBuf.length;
- this._buffers.shift(); // == smallerBuf
- read.func.call(this, smallerBuf);
- }
- };
- ChunkStream.prototype._processRead = function(read) {
- this._reads.shift(); // == read
- var pos = 0;
- var count = 0;
- var data = new Buffer(read.length);
- // create buffer for all data
- while (pos < read.length) {
- var buf = this._buffers[count++];
- var len = Math.min(buf.length, read.length - pos);
- buf.copy(data, pos, 0, len);
- pos += len;
- // last buffer wasn't used all so just slice it and leave
- if (len !== buf.length) {
- this._buffers[--count] = buf.slice(len);
- }
- }
- // remove all used buffers
- if (count > 0) {
- this._buffers.splice(0, count);
- }
- this._buffered -= read.length;
- read.func.call(this, data);
- };
- ChunkStream.prototype._process = function() {
- try {
- // as long as there is any data and read requests
- while (this._buffered > 0 && this._reads && this._reads.length > 0) {
- var read = this._reads[0];
- // read any data (but no more than length)
- if (read.allowLess) {
- this._processReadAllowingLess(read);
- }
- else if (this._buffered >= read.length) {
- // ok we can meet some expectations
- this._processRead(read);
- }
- else {
- // not enought data to satisfy first request in queue
- // so we need to wait for more
- break;
- }
- }
- if (this._buffers && !this.writable) {
- this._end();
- }
- }
- catch (ex) {
- this.emit('error', ex);
- }
- };
- });
- // Adam 7
- // 0 1 2 3 4 5 6 7
- // 0 x 6 4 6 x 6 4 6
- // 1 7 7 7 7 7 7 7 7
- // 2 5 6 5 6 5 6 5 6
- // 3 7 7 7 7 7 7 7 7
- // 4 3 6 4 6 3 6 4 6
- // 5 7 7 7 7 7 7 7 7
- // 6 5 6 5 6 5 6 5 6
- // 7 7 7 7 7 7 7 7 7
- var imagePasses = [
- { // pass 1 - 1px
- x: [0],
- y: [0]
- },
- { // pass 2 - 1px
- x: [4],
- y: [0]
- },
- { // pass 3 - 2px
- x: [0, 4],
- y: [4]
- },
- { // pass 4 - 4px
- x: [2, 6],
- y: [0, 4]
- },
- { // pass 5 - 8px
- x: [0, 2, 4, 6],
- y: [2, 6]
- },
- { // pass 6 - 16px
- x: [1, 3, 5, 7],
- y: [0, 2, 4, 6]
- },
- { // pass 7 - 32px
- x: [0, 1, 2, 3, 4, 5, 6, 7],
- y: [1, 3, 5, 7]
- }
- ];
- var getImagePasses = function(width, height) {
- var images = [];
- var xLeftOver = width % 8;
- var yLeftOver = height % 8;
- var xRepeats = (width - xLeftOver) / 8;
- var yRepeats = (height - yLeftOver) / 8;
- for (var i = 0; i < imagePasses.length; i++) {
- var pass = imagePasses[i];
- var passWidth = xRepeats * pass.x.length;
- var passHeight = yRepeats * pass.y.length;
- for (var j = 0; j < pass.x.length; j++) {
- if (pass.x[j] < xLeftOver) {
- passWidth++;
- }
- else {
- break;
- }
- }
- for (j = 0; j < pass.y.length; j++) {
- if (pass.y[j] < yLeftOver) {
- passHeight++;
- }
- else {
- break;
- }
- }
- if (passWidth > 0 && passHeight > 0) {
- images.push({ width: passWidth, height: passHeight, index: i });
- }
- }
- return images;
- };
- var getInterlaceIterator = function(width) {
- return function(x, y, pass) {
- var outerXLeftOver = x % imagePasses[pass].x.length;
- var outerX = (((x - outerXLeftOver) / imagePasses[pass].x.length) * 8) + imagePasses[pass].x[outerXLeftOver];
- var outerYLeftOver = y % imagePasses[pass].y.length;
- var outerY = (((y - outerYLeftOver) / imagePasses[pass].y.length) * 8) + imagePasses[pass].y[outerYLeftOver];
- return (outerX * 4) + (outerY * width * 4);
- };
- };
- var interlace = {
- getImagePasses: getImagePasses,
- getInterlaceIterator: getInterlaceIterator
- };
- var paethPredictor = function paethPredictor(left, above, upLeft) {
- var paeth = left + above - upLeft;
- var pLeft = Math.abs(paeth - left);
- var pAbove = Math.abs(paeth - above);
- var pUpLeft = Math.abs(paeth - upLeft);
- if (pLeft <= pAbove && pLeft <= pUpLeft) {
- return left;
- }
- if (pAbove <= pUpLeft) {
- return above;
- }
- return upLeft;
- };
- var filterParse = createCommonjsModule(function (module) {
- function getByteWidth(width, bpp, depth) {
- var byteWidth = width * bpp;
- if (depth !== 8) {
- byteWidth = Math.ceil(byteWidth / (8 / depth));
- }
- return byteWidth;
- }
- var Filter = module.exports = function(bitmapInfo, dependencies) {
- var width = bitmapInfo.width;
- var height = bitmapInfo.height;
- var interlace$1 = bitmapInfo.interlace;
- var bpp = bitmapInfo.bpp;
- var depth = bitmapInfo.depth;
- this.read = dependencies.read;
- this.write = dependencies.write;
- this.complete = dependencies.complete;
- this._imageIndex = 0;
- this._images = [];
- if (interlace$1) {
- var passes = interlace.getImagePasses(width, height);
- for (var i = 0; i < passes.length; i++) {
- this._images.push({
- byteWidth: getByteWidth(passes[i].width, bpp, depth),
- height: passes[i].height,
- lineIndex: 0
- });
- }
- }
- else {
- this._images.push({
- byteWidth: getByteWidth(width, bpp, depth),
- height: height,
- lineIndex: 0
- });
- }
- // when filtering the line we look at the pixel to the left
- // the spec also says it is done on a byte level regardless of the number of pixels
- // so if the depth is byte compatible (8 or 16) we subtract the bpp in order to compare back
- // a pixel rather than just a different byte part. However if we are sub byte, we ignore.
- if (depth === 8) {
- this._xComparison = bpp;
- }
- else if (depth === 16) {
- this._xComparison = bpp * 2;
- }
- else {
- this._xComparison = 1;
- }
- };
- Filter.prototype.start = function() {
- this.read(this._images[this._imageIndex].byteWidth + 1, this._reverseFilterLine.bind(this));
- };
- Filter.prototype._unFilterType1 = function(rawData, unfilteredLine, byteWidth) {
- var xComparison = this._xComparison;
- var xBiggerThan = xComparison - 1;
- for (var x = 0; x < byteWidth; x++) {
- var rawByte = rawData[1 + x];
- var f1Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
- unfilteredLine[x] = rawByte + f1Left;
- }
- };
- Filter.prototype._unFilterType2 = function(rawData, unfilteredLine, byteWidth) {
- var lastLine = this._lastLine;
- for (var x = 0; x < byteWidth; x++) {
- var rawByte = rawData[1 + x];
- var f2Up = lastLine ? lastLine[x] : 0;
- unfilteredLine[x] = rawByte + f2Up;
- }
- };
- Filter.prototype._unFilterType3 = function(rawData, unfilteredLine, byteWidth) {
- var xComparison = this._xComparison;
- var xBiggerThan = xComparison - 1;
- var lastLine = this._lastLine;
- for (var x = 0; x < byteWidth; x++) {
- var rawByte = rawData[1 + x];
- var f3Up = lastLine ? lastLine[x] : 0;
- var f3Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
- var f3Add = Math.floor((f3Left + f3Up) / 2);
- unfilteredLine[x] = rawByte + f3Add;
- }
- };
- Filter.prototype._unFilterType4 = function(rawData, unfilteredLine, byteWidth) {
- var xComparison = this._xComparison;
- var xBiggerThan = xComparison - 1;
- var lastLine = this._lastLine;
- for (var x = 0; x < byteWidth; x++) {
- var rawByte = rawData[1 + x];
- var f4Up = lastLine ? lastLine[x] : 0;
- var f4Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
- var f4UpLeft = x > xBiggerThan && lastLine ? lastLine[x - xComparison] : 0;
- var f4Add = paethPredictor(f4Left, f4Up, f4UpLeft);
- unfilteredLine[x] = rawByte + f4Add;
- }
- };
- Filter.prototype._reverseFilterLine = function(rawData) {
- var filter = rawData[0];
- var unfilteredLine;
- var currentImage = this._images[this._imageIndex];
- var byteWidth = currentImage.byteWidth;
- if (filter === 0) {
- unfilteredLine = rawData.slice(1, byteWidth + 1);
- }
- else {
- unfilteredLine = new Buffer(byteWidth);
- switch (filter) {
- case 1:
- this._unFilterType1(rawData, unfilteredLine, byteWidth);
- break;
- case 2:
- this._unFilterType2(rawData, unfilteredLine, byteWidth);
- break;
- case 3:
- this._unFilterType3(rawData, unfilteredLine, byteWidth);
- break;
- case 4:
- this._unFilterType4(rawData, unfilteredLine, byteWidth);
- break;
- default:
- throw new Error('Unrecognised filter type - ' + filter);
- }
- }
- this.write(unfilteredLine);
- currentImage.lineIndex++;
- if (currentImage.lineIndex >= currentImage.height) {
- this._lastLine = null;
- this._imageIndex++;
- currentImage = this._images[this._imageIndex];
- }
- else {
- this._lastLine = unfilteredLine;
- }
- if (currentImage) {
- // read, using the byte width that may be from the new current image
- this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this));
- }
- else {
- this._lastLine = null;
- this.complete();
- }
- };
- });
- var filterParseAsync = createCommonjsModule(function (module) {
- var FilterAsync = module.exports = function(bitmapInfo) {
- chunkstream.call(this);
- var buffers = [];
- var that = this;
- this._filter = new filterParse(bitmapInfo, {
- read: this.read.bind(this),
- write: function(buffer) {
- buffers.push(buffer);
- },
- complete: function() {
- that.emit('complete', Buffer.concat(buffers));
- }
- });
- this._filter.start();
- };
- util__default['default'].inherits(FilterAsync, chunkstream);
- });
- var constants = {
- PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],
- TYPE_IHDR: 0x49484452,
- TYPE_IEND: 0x49454e44,
- TYPE_IDAT: 0x49444154,
- TYPE_PLTE: 0x504c5445,
- TYPE_tRNS: 0x74524e53, // eslint-disable-line camelcase
- TYPE_gAMA: 0x67414d41, // eslint-disable-line camelcase
- // color-type bits
- COLORTYPE_GRAYSCALE: 0,
- COLORTYPE_PALETTE: 1,
- COLORTYPE_COLOR: 2,
- COLORTYPE_ALPHA: 4, // e.g. grayscale and alpha
- // color-type combinations
- COLORTYPE_PALETTE_COLOR: 3,
- COLORTYPE_COLOR_ALPHA: 6,
- COLORTYPE_TO_BPP_MAP: {
- 0: 1,
- 2: 3,
- 3: 1,
- 4: 2,
- 6: 4
- },
- GAMMA_DIVISION: 100000
- };
- var crc = createCommonjsModule(function (module) {
- var crcTable = [];
- (function() {
- for (var i = 0; i < 256; i++) {
- var currentCrc = i;
- for (var j = 0; j < 8; j++) {
- if (currentCrc & 1) {
- currentCrc = 0xedb88320 ^ (currentCrc >>> 1);
- }
- else {
- currentCrc = currentCrc >>> 1;
- }
- }
- crcTable[i] = currentCrc;
- }
- }());
- var CrcCalculator = module.exports = function() {
- this._crc = -1;
- };
- CrcCalculator.prototype.write = function(data) {
- for (var i = 0; i < data.length; i++) {
- this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8);
- }
- return true;
- };
- CrcCalculator.prototype.crc32 = function() {
- return this._crc ^ -1;
- };
- CrcCalculator.crc32 = function(buf) {
- var crc = -1;
- for (var i = 0; i < buf.length; i++) {
- crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
- }
- return crc ^ -1;
- };
- });
- var parser = createCommonjsModule(function (module) {
- var Parser = module.exports = function(options, dependencies) {
- this._options = options;
- options.checkCRC = options.checkCRC !== false;
- this._hasIHDR = false;
- this._hasIEND = false;
- this._emittedHeadersFinished = false;
- // input flags/metadata
- this._palette = [];
- this._colorType = 0;
- this._chunks = {};
- this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this);
- this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this);
- this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this);
- this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this);
- this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this);
- this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this);
- this.read = dependencies.read;
- this.error = dependencies.error;
- this.metadata = dependencies.metadata;
- this.gamma = dependencies.gamma;
- this.transColor = dependencies.transColor;
- this.palette = dependencies.palette;
- this.parsed = dependencies.parsed;
- this.inflateData = dependencies.inflateData;
- this.finished = dependencies.finished;
- this.simpleTransparency = dependencies.simpleTransparency;
- this.headersFinished = dependencies.headersFinished || function() {};
- };
- Parser.prototype.start = function() {
- this.read(constants.PNG_SIGNATURE.length,
- this._parseSignature.bind(this)
- );
- };
- Parser.prototype._parseSignature = function(data) {
- var signature = constants.PNG_SIGNATURE;
- for (var i = 0; i < signature.length; i++) {
- if (data[i] !== signature[i]) {
- this.error(new Error('Invalid file signature'));
- return;
- }
- }
- this.read(8, this._parseChunkBegin.bind(this));
- };
- Parser.prototype._parseChunkBegin = function(data) {
- // chunk content length
- var length = data.readUInt32BE(0);
- // chunk type
- var type = data.readUInt32BE(4);
- var name = '';
- for (var i = 4; i < 8; i++) {
- name += String.fromCharCode(data[i]);
- }
- //console.log('chunk ', name, length);
- // chunk flags
- var ancillary = Boolean(data[4] & 0x20); // or critical
- // priv = Boolean(data[5] & 0x20), // or public
- // safeToCopy = Boolean(data[7] & 0x20); // or unsafe
- if (!this._hasIHDR && type !== constants.TYPE_IHDR) {
- this.error(new Error('Expected IHDR on beggining'));
- return;
- }
- this._crc = new crc();
- this._crc.write(new Buffer(name));
- if (this._chunks[type]) {
- return this._chunks[type](length);
- }
- if (!ancillary) {
- this.error(new Error('Unsupported critical chunk type ' + name));
- return;
- }
- this.read(length + 4, this._skipChunk.bind(this));
- };
- Parser.prototype._skipChunk = function(/*data*/) {
- this.read(8, this._parseChunkBegin.bind(this));
- };
- Parser.prototype._handleChunkEnd = function() {
- this.read(4, this._parseChunkEnd.bind(this));
- };
- Parser.prototype._parseChunkEnd = function(data) {
- var fileCrc = data.readInt32BE(0);
- var calcCrc = this._crc.crc32();
- // check CRC
- if (this._options.checkCRC && calcCrc !== fileCrc) {
- this.error(new Error('Crc error - ' + fileCrc + ' - ' + calcCrc));
- return;
- }
- if (!this._hasIEND) {
- this.read(8, this._parseChunkBegin.bind(this));
- }
- };
- Parser.prototype._handleIHDR = function(length) {
- this.read(length, this._parseIHDR.bind(this));
- };
- Parser.prototype._parseIHDR = function(data) {
- this._crc.write(data);
- var width = data.readUInt32BE(0);
- var height = data.readUInt32BE(4);
- var depth = data[8];
- var colorType = data[9]; // bits: 1 palette, 2 color, 4 alpha
- var compr = data[10];
- var filter = data[11];
- var interlace = data[12];
- // console.log(' width', width, 'height', height,
- // 'depth', depth, 'colorType', colorType,
- // 'compr', compr, 'filter', filter, 'interlace', interlace
- // );
- if (depth !== 8 && depth !== 4 && depth !== 2 && depth !== 1 && depth !== 16) {
- this.error(new Error('Unsupported bit depth ' + depth));
- return;
- }
- if (!(colorType in constants.COLORTYPE_TO_BPP_MAP)) {
- this.error(new Error('Unsupported color type'));
- return;
- }
- if (compr !== 0) {
- this.error(new Error('Unsupported compression method'));
- return;
- }
- if (filter !== 0) {
- this.error(new Error('Unsupported filter method'));
- return;
- }
- if (interlace !== 0 && interlace !== 1) {
- this.error(new Error('Unsupported interlace method'));
- return;
- }
- this._colorType = colorType;
- var bpp = constants.COLORTYPE_TO_BPP_MAP[this._colorType];
- this._hasIHDR = true;
- this.metadata({
- width: width,
- height: height,
- depth: depth,
- interlace: Boolean(interlace),
- palette: Boolean(colorType & constants.COLORTYPE_PALETTE),
- color: Boolean(colorType & constants.COLORTYPE_COLOR),
- alpha: Boolean(colorType & constants.COLORTYPE_ALPHA),
- bpp: bpp,
- colorType: colorType
- });
- this._handleChunkEnd();
- };
- Parser.prototype._handlePLTE = function(length) {
- this.read(length, this._parsePLTE.bind(this));
- };
- Parser.prototype._parsePLTE = function(data) {
- this._crc.write(data);
- var entries = Math.floor(data.length / 3);
- // console.log('Palette:', entries);
- for (var i = 0; i < entries; i++) {
- this._palette.push([
- data[i * 3],
- data[i * 3 + 1],
- data[i * 3 + 2],
- 0xff
- ]);
- }
- this.palette(this._palette);
- this._handleChunkEnd();
- };
- Parser.prototype._handleTRNS = function(length) {
- this.simpleTransparency();
- this.read(length, this._parseTRNS.bind(this));
- };
- Parser.prototype._parseTRNS = function(data) {
- this._crc.write(data);
- // palette
- if (this._colorType === constants.COLORTYPE_PALETTE_COLOR) {
- if (this._palette.length === 0) {
- this.error(new Error('Transparency chunk must be after palette'));
- return;
- }
- if (data.length > this._palette.length) {
- this.error(new Error('More transparent colors than palette size'));
- return;
- }
- for (var i = 0; i < data.length; i++) {
- this._palette[i][3] = data[i];
- }
- this.palette(this._palette);
- }
- // for colorType 0 (grayscale) and 2 (rgb)
- // there might be one gray/color defined as transparent
- if (this._colorType === constants.COLORTYPE_GRAYSCALE) {
- // grey, 2 bytes
- this.transColor([data.readUInt16BE(0)]);
- }
- if (this._colorType === constants.COLORTYPE_COLOR) {
- this.transColor([data.readUInt16BE(0), data.readUInt16BE(2), data.readUInt16BE(4)]);
- }
- this._handleChunkEnd();
- };
- Parser.prototype._handleGAMA = function(length) {
- this.read(length, this._parseGAMA.bind(this));
- };
- Parser.prototype._parseGAMA = function(data) {
- this._crc.write(data);
- this.gamma(data.readUInt32BE(0) / constants.GAMMA_DIVISION);
- this._handleChunkEnd();
- };
- Parser.prototype._handleIDAT = function(length) {
- if (!this._emittedHeadersFinished) {
- this._emittedHeadersFinished = true;
- this.headersFinished();
- }
- this.read(-length, this._parseIDAT.bind(this, length));
- };
- Parser.prototype._parseIDAT = function(length, data) {
- this._crc.write(data);
- if (this._colorType === constants.COLORTYPE_PALETTE_COLOR && this._palette.length === 0) {
- throw new Error('Expected palette not found');
- }
- this.inflateData(data);
- var leftOverLength = length - data.length;
- if (leftOverLength > 0) {
- this._handleIDAT(leftOverLength);
- }
- else {
- this._handleChunkEnd();
- }
- };
- Parser.prototype._handleIEND = function(length) {
- this.read(length, this._parseIEND.bind(this));
- };
- Parser.prototype._parseIEND = function(data) {
- this._crc.write(data);
- this._hasIEND = true;
- this._handleChunkEnd();
- if (this.finished) {
- this.finished();
- }
- };
- });
- var pixelBppMapper = [
- // 0 - dummy entry
- function() {},
- // 1 - L
- // 0: 0, 1: 0, 2: 0, 3: 0xff
- function(pxData, data, pxPos, rawPos) {
- if (rawPos === data.length) {
- throw new Error('Ran out of data');
- }
- var pixel = data[rawPos];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = 0xff;
- },
- // 2 - LA
- // 0: 0, 1: 0, 2: 0, 3: 1
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 1 >= data.length) {
- throw new Error('Ran out of data');
- }
- var pixel = data[rawPos];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = data[rawPos + 1];
- },
- // 3 - RGB
- // 0: 0, 1: 1, 2: 2, 3: 0xff
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 2 >= data.length) {
- throw new Error('Ran out of data');
- }
- pxData[pxPos] = data[rawPos];
- pxData[pxPos + 1] = data[rawPos + 1];
- pxData[pxPos + 2] = data[rawPos + 2];
- pxData[pxPos + 3] = 0xff;
- },
- // 4 - RGBA
- // 0: 0, 1: 1, 2: 2, 3: 3
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 3 >= data.length) {
- throw new Error('Ran out of data');
- }
- pxData[pxPos] = data[rawPos];
- pxData[pxPos + 1] = data[rawPos + 1];
- pxData[pxPos + 2] = data[rawPos + 2];
- pxData[pxPos + 3] = data[rawPos + 3];
- }
- ];
- var pixelBppCustomMapper = [
- // 0 - dummy entry
- function() {},
- // 1 - L
- // 0: 0, 1: 0, 2: 0, 3: 0xff
- function(pxData, pixelData, pxPos, maxBit) {
- var pixel = pixelData[0];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = maxBit;
- },
- // 2 - LA
- // 0: 0, 1: 0, 2: 0, 3: 1
- function(pxData, pixelData, pxPos) {
- var pixel = pixelData[0];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = pixelData[1];
- },
- // 3 - RGB
- // 0: 0, 1: 1, 2: 2, 3: 0xff
- function(pxData, pixelData, pxPos, maxBit) {
- pxData[pxPos] = pixelData[0];
- pxData[pxPos + 1] = pixelData[1];
- pxData[pxPos + 2] = pixelData[2];
- pxData[pxPos + 3] = maxBit;
- },
- // 4 - RGBA
- // 0: 0, 1: 1, 2: 2, 3: 3
- function(pxData, pixelData, pxPos) {
- pxData[pxPos] = pixelData[0];
- pxData[pxPos + 1] = pixelData[1];
- pxData[pxPos + 2] = pixelData[2];
- pxData[pxPos + 3] = pixelData[3];
- }
- ];
- function bitRetriever(data, depth) {
- var leftOver = [];
- var i = 0;
- function split() {
- if (i === data.length) {
- throw new Error('Ran out of data');
- }
- var byte = data[i];
- i++;
- var byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1;
- switch (depth) {
- default:
- throw new Error('unrecognised depth');
- case 16:
- byte2 = data[i];
- i++;
- leftOver.push(((byte << 8) + byte2));
- break;
- case 4:
- byte2 = byte & 0x0f;
- byte1 = byte >> 4;
- leftOver.push(byte1, byte2);
- break;
- case 2:
- byte4 = byte & 3;
- byte3 = byte >> 2 & 3;
- byte2 = byte >> 4 & 3;
- byte1 = byte >> 6 & 3;
- leftOver.push(byte1, byte2, byte3, byte4);
- break;
- case 1:
- byte8 = byte & 1;
- byte7 = byte >> 1 & 1;
- byte6 = byte >> 2 & 1;
- byte5 = byte >> 3 & 1;
- byte4 = byte >> 4 & 1;
- byte3 = byte >> 5 & 1;
- byte2 = byte >> 6 & 1;
- byte1 = byte >> 7 & 1;
- leftOver.push(byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8);
- break;
- }
- }
- return {
- get: function(count) {
- while (leftOver.length < count) {
- split();
- }
- var returner = leftOver.slice(0, count);
- leftOver = leftOver.slice(count);
- return returner;
- },
- resetAfterLine: function() {
- leftOver.length = 0;
- },
- end: function() {
- if (i !== data.length) {
- throw new Error('extra data found');
- }
- }
- };
- }
- function mapImage8Bit(image, pxData, getPxPos, bpp, data, rawPos) { // eslint-disable-line max-params
- var imageWidth = image.width;
- var imageHeight = image.height;
- var imagePass = image.index;
- for (var y = 0; y < imageHeight; y++) {
- for (var x = 0; x < imageWidth; x++) {
- var pxPos = getPxPos(x, y, imagePass);
- pixelBppMapper[bpp](pxData, data, pxPos, rawPos);
- rawPos += bpp; //eslint-disable-line no-param-reassign
- }
- }
- return rawPos;
- }
- function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) { // eslint-disable-line max-params
- var imageWidth = image.width;
- var imageHeight = image.height;
- var imagePass = image.index;
- for (var y = 0; y < imageHeight; y++) {
- for (var x = 0; x < imageWidth; x++) {
- var pixelData = bits.get(bpp);
- var pxPos = getPxPos(x, y, imagePass);
- pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
- }
- bits.resetAfterLine();
- }
- }
- var dataToBitMap = function(data, bitmapInfo) {
- var width = bitmapInfo.width;
- var height = bitmapInfo.height;
- var depth = bitmapInfo.depth;
- var bpp = bitmapInfo.bpp;
- var interlace$1 = bitmapInfo.interlace;
- if (depth !== 8) {
- var bits = bitRetriever(data, depth);
- }
- var pxData;
- if (depth <= 8) {
- pxData = new Buffer(width * height * 4);
- }
- else {
- pxData = new Uint16Array(width * height * 4);
- }
- var maxBit = Math.pow(2, depth) - 1;
- var rawPos = 0;
- var images;
- var getPxPos;
- if (interlace$1) {
- images = interlace.getImagePasses(width, height);
- getPxPos = interlace.getInterlaceIterator(width, height);
- }
- else {
- var nonInterlacedPxPos = 0;
- getPxPos = function() {
- var returner = nonInterlacedPxPos;
- nonInterlacedPxPos += 4;
- return returner;
- };
- images = [{ width: width, height: height }];
- }
- for (var imageIndex = 0; imageIndex < images.length; imageIndex++) {
- if (depth === 8) {
- rawPos = mapImage8Bit(images[imageIndex], pxData, getPxPos, bpp, data, rawPos);
- }
- else {
- mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp, bits, maxBit);
- }
- }
- if (depth === 8) {
- if (rawPos !== data.length) {
- throw new Error('extra data found');
- }
- }
- else {
- bits.end();
- }
- return pxData;
- };
- var bitmapper = {
- dataToBitMap: dataToBitMap
- };
- function dePalette(indata, outdata, width, height, palette) {
- var pxPos = 0;
- // use values from palette
- for (var y = 0; y < height; y++) {
- for (var x = 0; x < width; x++) {
- var color = palette[indata[pxPos]];
- if (!color) {
- throw new Error('index ' + indata[pxPos] + ' not in palette');
- }
- for (var i = 0; i < 4; i++) {
- outdata[pxPos + i] = color[i];
- }
- pxPos += 4;
- }
- }
- }
- function replaceTransparentColor(indata, outdata, width, height, transColor) {
- var pxPos = 0;
- for (var y = 0; y < height; y++) {
- for (var x = 0; x < width; x++) {
- var makeTrans = false;
- if (transColor.length === 1) {
- if (transColor[0] === indata[pxPos]) {
- makeTrans = true;
- }
- }
- else if (transColor[0] === indata[pxPos] && transColor[1] === indata[pxPos + 1] && transColor[2] === indata[pxPos + 2]) {
- makeTrans = true;
- }
- if (makeTrans) {
- for (var i = 0; i < 4; i++) {
- outdata[pxPos + i] = 0;
- }
- }
- pxPos += 4;
- }
- }
- }
- function scaleDepth(indata, outdata, width, height, depth) {
- var maxOutSample = 255;
- var maxInSample = Math.pow(2, depth) - 1;
- var pxPos = 0;
- for (var y = 0; y < height; y++) {
- for (var x = 0; x < width; x++) {
- for (var i = 0; i < 4; i++) {
- outdata[pxPos + i] = Math.floor((indata[pxPos + i] * maxOutSample) / maxInSample + 0.5);
- }
- pxPos += 4;
- }
- }
- }
- var formatNormaliser = function(indata, imageData) {
- var depth = imageData.depth;
- var width = imageData.width;
- var height = imageData.height;
- var colorType = imageData.colorType;
- var transColor = imageData.transColor;
- var palette = imageData.palette;
- var outdata = indata; // only different for 16 bits
- if (colorType === 3) { // paletted
- dePalette(indata, outdata, width, height, palette);
- }
- else {
- if (transColor) {
- replaceTransparentColor(indata, outdata, width, height, transColor);
- }
- // if it needs scaling
- if (depth !== 8) {
- // if we need to change the buffer size
- if (depth === 16) {
- outdata = new Buffer(width * height * 4);
- }
- scaleDepth(indata, outdata, width, height, depth);
- }
- }
- return outdata;
- };
- var parserAsync = createCommonjsModule(function (module) {
- var ParserAsync = module.exports = function(options) {
- chunkstream.call(this);
- this._parser = new parser(options, {
- read: this.read.bind(this),
- error: this._handleError.bind(this),
- metadata: this._handleMetaData.bind(this),
- gamma: this.emit.bind(this, 'gamma'),
- palette: this._handlePalette.bind(this),
- transColor: this._handleTransColor.bind(this),
- finished: this._finished.bind(this),
- inflateData: this._inflateData.bind(this),
- simpleTransparency: this._simpleTransparency.bind(this),
- headersFinished: this._headersFinished.bind(this)
- });
- this._options = options;
- this.writable = true;
- this._parser.start();
- };
- util__default['default'].inherits(ParserAsync, chunkstream);
- ParserAsync.prototype._handleError = function(err) {
- this.emit('error', err);
- this.writable = false;
- this.destroy();
- if (this._inflate && this._inflate.destroy) {
- this._inflate.destroy();
- }
- if (this._filter) {
- this._filter.destroy();
- // For backward compatibility with Node 7 and below.
- // Suppress errors due to _inflate calling write() even after
- // it's destroy()'ed.
- this._filter.on('error', function() {});
- }
- this.errord = true;
- };
- ParserAsync.prototype._inflateData = function(data) {
- if (!this._inflate) {
- if (this._bitmapInfo.interlace) {
- this._inflate = zlib__default['default'].createInflate();
- this._inflate.on('error', this.emit.bind(this, 'error'));
- this._filter.on('complete', this._complete.bind(this));
- this._inflate.pipe(this._filter);
- }
- else {
- var rowSize = ((this._bitmapInfo.width * this._bitmapInfo.bpp * this._bitmapInfo.depth + 7) >> 3) + 1;
- var imageSize = rowSize * this._bitmapInfo.height;
- var chunkSize = Math.max(imageSize, zlib__default['default'].Z_MIN_CHUNK);
- this._inflate = zlib__default['default'].createInflate({ chunkSize: chunkSize });
- var leftToInflate = imageSize;
- var emitError = this.emit.bind(this, 'error');
- this._inflate.on('error', function(err) {
- if (!leftToInflate) {
- return;
- }
- emitError(err);
- });
- this._filter.on('complete', this._complete.bind(this));
- var filterWrite = this._filter.write.bind(this._filter);
- this._inflate.on('data', function(chunk) {
- if (!leftToInflate) {
- return;
- }
- if (chunk.length > leftToInflate) {
- chunk = chunk.slice(0, leftToInflate);
- }
- leftToInflate -= chunk.length;
- filterWrite(chunk);
- });
- this._inflate.on('end', this._filter.end.bind(this._filter));
- }
- }
- this._inflate.write(data);
- };
- ParserAsync.prototype._handleMetaData = function(metaData) {
- this._metaData = metaData;
- this._bitmapInfo = Object.create(metaData);
- this._filter = new filterParseAsync(this._bitmapInfo);
- };
- ParserAsync.prototype._handleTransColor = function(transColor) {
- this._bitmapInfo.transColor = transColor;
- };
- ParserAsync.prototype._handlePalette = function(palette) {
- this._bitmapInfo.palette = palette;
- };
- ParserAsync.prototype._simpleTransparency = function() {
- this._metaData.alpha = true;
- };
- ParserAsync.prototype._headersFinished = function() {
- // Up until this point, we don't know if we have a tRNS chunk (alpha)
- // so we can't emit metadata any earlier
- this.emit('metadata', this._metaData);
- };
- ParserAsync.prototype._finished = function() {
- if (this.errord) {
- return;
- }
- if (!this._inflate) {
- this.emit('error', 'No Inflate block');
- }
- else {
- // no more data to inflate
- this._inflate.end();
- }
- this.destroySoon();
- };
- ParserAsync.prototype._complete = function(filteredData) {
- if (this.errord) {
- return;
- }
- try {
- var bitmapData = bitmapper.dataToBitMap(filteredData, this._bitmapInfo);
- var normalisedBitmapData = formatNormaliser(bitmapData, this._bitmapInfo);
- bitmapData = null;
- }
- catch (ex) {
- this._handleError(ex);
- return;
- }
- this.emit('parsed', normalisedBitmapData);
- };
- });
- var bitpacker = function(dataIn, width, height, options) {
- var outHasAlpha = [constants.COLORTYPE_COLOR_ALPHA, constants.COLORTYPE_ALPHA].indexOf(options.colorType) !== -1;
- if (options.colorType === options.inputColorType) {
- var bigEndian = (function() {
- var buffer = new ArrayBuffer(2);
- new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
- // Int16Array uses the platform's endianness.
- return new Int16Array(buffer)[0] !== 256;
- })();
- // If no need to convert to grayscale and alpha is present/absent in both, take a fast route
- if (options.bitDepth === 8 || (options.bitDepth === 16 && bigEndian)) {
- return dataIn;
- }
- }
- // map to a UInt16 array if data is 16bit, fix endianness below
- var data = options.bitDepth !== 16 ? dataIn : new Uint16Array(dataIn.buffer);
- var maxValue = 255;
- var inBpp = constants.COLORTYPE_TO_BPP_MAP[options.inputColorType];
- if (inBpp === 4 && !options.inputHasAlpha) {
- inBpp = 3;
- }
- var outBpp = constants.COLORTYPE_TO_BPP_MAP[options.colorType];
- if (options.bitDepth === 16) {
- maxValue = 65535;
- outBpp *= 2;
- }
- var outData = new Buffer(width * height * outBpp);
- var inIndex = 0;
- var outIndex = 0;
- var bgColor = options.bgColor || {};
- if (bgColor.red === undefined) {
- bgColor.red = maxValue;
- }
- if (bgColor.green === undefined) {
- bgColor.green = maxValue;
- }
- if (bgColor.blue === undefined) {
- bgColor.blue = maxValue;
- }
- function getRGBA() {
- var red;
- var green;
- var blue;
- var alpha = maxValue;
- switch (options.inputColorType) {
- case constants.COLORTYPE_COLOR_ALPHA:
- alpha = data[inIndex + 3];
- red = data[inIndex];
- green = data[inIndex + 1];
- blue = data[inIndex + 2];
- break;
- case constants.COLORTYPE_COLOR:
- red = data[inIndex];
- green = data[inIndex + 1];
- blue = data[inIndex + 2];
- break;
- case constants.COLORTYPE_ALPHA:
- alpha = data[inIndex + 1];
- red = data[inIndex];
- green = red;
- blue = red;
- break;
- case constants.COLORTYPE_GRAYSCALE:
- red = data[inIndex];
- green = red;
- blue = red;
- break;
- default:
- throw new Error('input color type:' + options.inputColorType + ' is not supported at present');
- }
- if (options.inputHasAlpha) {
- if (!outHasAlpha) {
- alpha /= maxValue;
- red = Math.min(Math.max(Math.round((1 - alpha) * bgColor.red + alpha * red), 0), maxValue);
- green = Math.min(Math.max(Math.round((1 - alpha) * bgColor.green + alpha * green), 0), maxValue);
- blue = Math.min(Math.max(Math.round((1 - alpha) * bgColor.blue + alpha * blue), 0), maxValue);
- }
- }
- return { red: red, green: green, blue: blue, alpha: alpha };
- }
- for (var y = 0; y < height; y++) {
- for (var x = 0; x < width; x++) {
- var rgba = getRGBA();
- switch (options.colorType) {
- case constants.COLORTYPE_COLOR_ALPHA:
- case constants.COLORTYPE_COLOR:
- if (options.bitDepth === 8) {
- outData[outIndex] = rgba.red;
- outData[outIndex + 1] = rgba.green;
- outData[outIndex + 2] = rgba.blue;
- if (outHasAlpha) {
- outData[outIndex + 3] = rgba.alpha;
- }
- }
- else {
- outData.writeUInt16BE(rgba.red, outIndex);
- outData.writeUInt16BE(rgba.green, outIndex + 2);
- outData.writeUInt16BE(rgba.blue, outIndex + 4);
- if (outHasAlpha) {
- outData.writeUInt16BE(rgba.alpha, outIndex + 6);
- }
- }
- break;
- case constants.COLORTYPE_ALPHA:
- case constants.COLORTYPE_GRAYSCALE:
- // Convert to grayscale and alpha
- var grayscale = (rgba.red + rgba.green + rgba.blue) / 3;
- if (options.bitDepth === 8) {
- outData[outIndex] = grayscale;
- if (outHasAlpha) {
- outData[outIndex + 1] = rgba.alpha;
- }
- }
- else {
- outData.writeUInt16BE(grayscale, outIndex);
- if (outHasAlpha) {
- outData.writeUInt16BE(rgba.alpha, outIndex + 2);
- }
- }
- break;
- default:
- throw new Error('unrecognised color Type ' + options.colorType);
- }
- inIndex += inBpp;
- outIndex += outBpp;
- }
- }
- return outData;
- };
- function filterNone(pxData, pxPos, byteWidth, rawData, rawPos) {
- for (var x = 0; x < byteWidth; x++) {
- rawData[rawPos + x] = pxData[pxPos + x];
- }
- }
- function filterSumNone(pxData, pxPos, byteWidth) {
- var sum = 0;
- var length = pxPos + byteWidth;
- for (var i = pxPos; i < length; i++) {
- sum += Math.abs(pxData[i]);
- }
- return sum;
- }
- function filterSub(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var val = pxData[pxPos + x] - left;
- rawData[rawPos + x] = val;
- }
- }
- function filterSumSub(pxData, pxPos, byteWidth, bpp) {
- var sum = 0;
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var val = pxData[pxPos + x] - left;
- sum += Math.abs(val);
- }
- return sum;
- }
- function filterUp(pxData, pxPos, byteWidth, rawData, rawPos) {
- for (var x = 0; x < byteWidth; x++) {
- var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
- var val = pxData[pxPos + x] - up;
- rawData[rawPos + x] = val;
- }
- }
- function filterSumUp(pxData, pxPos, byteWidth) {
- var sum = 0;
- var length = pxPos + byteWidth;
- for (var x = pxPos; x < length; x++) {
- var up = pxPos > 0 ? pxData[x - byteWidth] : 0;
- var val = pxData[x] - up;
- sum += Math.abs(val);
- }
- return sum;
- }
- function filterAvg(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
- var val = pxData[pxPos + x] - ((left + up) >> 1);
- rawData[rawPos + x] = val;
- }
- }
- function filterSumAvg(pxData, pxPos, byteWidth, bpp) {
- var sum = 0;
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
- var val = pxData[pxPos + x] - ((left + up) >> 1);
- sum += Math.abs(val);
- }
- return sum;
- }
- function filterPaeth(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
- var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
- var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
- rawData[rawPos + x] = val;
- }
- }
- function filterSumPaeth(pxData, pxPos, byteWidth, bpp) {
- var sum = 0;
- for (var x = 0; x < byteWidth; x++) {
- var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
- var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
- var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
- var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
- sum += Math.abs(val);
- }
- return sum;
- }
- var filters = {
- 0: filterNone,
- 1: filterSub,
- 2: filterUp,
- 3: filterAvg,
- 4: filterPaeth
- };
- var filterSums = {
- 0: filterSumNone,
- 1: filterSumSub,
- 2: filterSumUp,
- 3: filterSumAvg,
- 4: filterSumPaeth
- };
- var filterPack = function(pxData, width, height, options, bpp) {
- var filterTypes;
- if (!('filterType' in options) || options.filterType === -1) {
- filterTypes = [0, 1, 2, 3, 4];
- }
- else if (typeof options.filterType === 'number') {
- filterTypes = [options.filterType];
- }
- else {
- throw new Error('unrecognised filter types');
- }
- if (options.bitDepth === 16) {
- bpp *= 2;
- }
- var byteWidth = width * bpp;
- var rawPos = 0;
- var pxPos = 0;
- var rawData = new Buffer((byteWidth + 1) * height);
- var sel = filterTypes[0];
- for (var y = 0; y < height; y++) {
- if (filterTypes.length > 1) {
- // find best filter for this line (with lowest sum of values)
- var min = Infinity;
- for (var i = 0; i < filterTypes.length; i++) {
- var sum = filterSums[filterTypes[i]](pxData, pxPos, byteWidth, bpp);
- if (sum < min) {
- sel = filterTypes[i];
- min = sum;
- }
- }
- }
- rawData[rawPos] = sel;
- rawPos++;
- filters[sel](pxData, pxPos, byteWidth, rawData, rawPos, bpp);
- rawPos += byteWidth;
- pxPos += byteWidth;
- }
- return rawData;
- };
- var packer = createCommonjsModule(function (module) {
- var Packer = module.exports = function(options) {
- this._options = options;
- options.deflateChunkSize = options.deflateChunkSize || 32 * 1024;
- options.deflateLevel = options.deflateLevel != null ? options.deflateLevel : 9;
- options.deflateStrategy = options.deflateStrategy != null ? options.deflateStrategy : 3;
- options.inputHasAlpha = options.inputHasAlpha != null ? options.inputHasAlpha : true;
- options.deflateFactory = options.deflateFactory || zlib__default['default'].createDeflate;
- options.bitDepth = options.bitDepth || 8;
- // This is outputColorType
- options.colorType = (typeof options.colorType === 'number') ? options.colorType : constants.COLORTYPE_COLOR_ALPHA;
- options.inputColorType = (typeof options.inputColorType === 'number') ? options.inputColorType : constants.COLORTYPE_COLOR_ALPHA;
- if ([
- constants.COLORTYPE_GRAYSCALE,
- constants.COLORTYPE_COLOR,
- constants.COLORTYPE_COLOR_ALPHA,
- constants.COLORTYPE_ALPHA
- ].indexOf(options.colorType) === -1) {
- throw new Error('option color type:' + options.colorType + ' is not supported at present');
- }
- if ([
- constants.COLORTYPE_GRAYSCALE,
- constants.COLORTYPE_COLOR,
- constants.COLORTYPE_COLOR_ALPHA,
- constants.COLORTYPE_ALPHA
- ].indexOf(options.inputColorType) === -1) {
- throw new Error('option input color type:' + options.inputColorType + ' is not supported at present');
- }
- if (options.bitDepth !== 8 && options.bitDepth !== 16) {
- throw new Error('option bit depth:' + options.bitDepth + ' is not supported at present');
- }
- };
- Packer.prototype.getDeflateOptions = function() {
- return {
- chunkSize: this._options.deflateChunkSize,
- level: this._options.deflateLevel,
- strategy: this._options.deflateStrategy
- };
- };
- Packer.prototype.createDeflate = function() {
- return this._options.deflateFactory(this.getDeflateOptions());
- };
- Packer.prototype.filterData = function(data, width, height) {
- // convert to correct format for filtering (e.g. right bpp and bit depth)
- var packedData = bitpacker(data, width, height, this._options);
- // filter pixel data
- var bpp = constants.COLORTYPE_TO_BPP_MAP[this._options.colorType];
- var filteredData = filterPack(packedData, width, height, this._options, bpp);
- return filteredData;
- };
- Packer.prototype._packChunk = function(type, data) {
- var len = (data ? data.length : 0);
- var buf = new Buffer(len + 12);
- buf.writeUInt32BE(len, 0);
- buf.writeUInt32BE(type, 4);
- if (data) {
- data.copy(buf, 8);
- }
- buf.writeInt32BE(crc.crc32(buf.slice(4, buf.length - 4)), buf.length - 4);
- return buf;
- };
- Packer.prototype.packGAMA = function(gamma) {
- var buf = new Buffer(4);
- buf.writeUInt32BE(Math.floor(gamma * constants.GAMMA_DIVISION), 0);
- return this._packChunk(constants.TYPE_gAMA, buf);
- };
- Packer.prototype.packIHDR = function(width, height) {
- var buf = new Buffer(13);
- buf.writeUInt32BE(width, 0);
- buf.writeUInt32BE(height, 4);
- buf[8] = this._options.bitDepth; // Bit depth
- buf[9] = this._options.colorType; // colorType
- buf[10] = 0; // compression
- buf[11] = 0; // filter
- buf[12] = 0; // interlace
- return this._packChunk(constants.TYPE_IHDR, buf);
- };
- Packer.prototype.packIDAT = function(data) {
- return this._packChunk(constants.TYPE_IDAT, data);
- };
- Packer.prototype.packIEND = function() {
- return this._packChunk(constants.TYPE_IEND, null);
- };
- });
- var packerAsync = createCommonjsModule(function (module) {
- var PackerAsync = module.exports = function(opt) {
- Stream__default['default'].call(this);
- var options = opt || {};
- this._packer = new packer(options);
- this._deflate = this._packer.createDeflate();
- this.readable = true;
- };
- util__default['default'].inherits(PackerAsync, Stream__default['default']);
- PackerAsync.prototype.pack = function(data, width, height, gamma) {
- // Signature
- this.emit('data', new Buffer(constants.PNG_SIGNATURE));
- this.emit('data', this._packer.packIHDR(width, height));
- if (gamma) {
- this.emit('data', this._packer.packGAMA(gamma));
- }
- var filteredData = this._packer.filterData(data, width, height);
- // compress it
- this._deflate.on('error', this.emit.bind(this, 'error'));
- this._deflate.on('data', function(compressedData) {
- this.emit('data', this._packer.packIDAT(compressedData));
- }.bind(this));
- this._deflate.on('end', function() {
- this.emit('data', this._packer.packIEND());
- this.emit('end');
- }.bind(this));
- this._deflate.end(filteredData);
- };
- });
- var syncInflate = createCommonjsModule(function (module, exports) {
- var assert = require$$0__default['default'].ok;
- var kMaxLength = require$$1__default['default'].kMaxLength;
- function Inflate(opts) {
- if (!(this instanceof Inflate)) {
- return new Inflate(opts);
- }
- if (opts && opts.chunkSize < zlib__default['default'].Z_MIN_CHUNK) {
- opts.chunkSize = zlib__default['default'].Z_MIN_CHUNK;
- }
- zlib__default['default'].Inflate.call(this, opts);
- // Node 8 --> 9 compatibility check
- this._offset = this._offset === undefined ? this._outOffset : this._offset;
- this._buffer = this._buffer || this._outBuffer;
- if (opts && opts.maxLength != null) {
- this._maxLength = opts.maxLength;
- }
- }
- function createInflate(opts) {
- return new Inflate(opts);
- }
- function _close(engine, callback) {
- if (callback) {
- process.nextTick(callback);
- }
- // Caller may invoke .close after a zlib error (which will null _handle).
- if (!engine._handle) {
- return;
- }
- engine._handle.close();
- engine._handle = null;
- }
- Inflate.prototype._processChunk = function(chunk, flushFlag, asyncCb) {
- if (typeof asyncCb === 'function') {
- return zlib__default['default'].Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
- }
- var self = this;
- var availInBefore = chunk && chunk.length;
- var availOutBefore = this._chunkSize - this._offset;
- var leftToInflate = this._maxLength;
- var inOff = 0;
- var buffers = [];
- var nread = 0;
- var error;
- this.on('error', function(err) {
- error = err;
- });
- function handleChunk(availInAfter, availOutAfter) {
- if (self._hadError) {
- return;
- }
- var have = availOutBefore - availOutAfter;
- assert(have >= 0, 'have should not go down');
- if (have > 0) {
- var out = self._buffer.slice(self._offset, self._offset + have);
- self._offset += have;
- if (out.length > leftToInflate) {
- out = out.slice(0, leftToInflate);
- }
- buffers.push(out);
- nread += out.length;
- leftToInflate -= out.length;
- if (leftToInflate === 0) {
- return false;
- }
- }
- if (availOutAfter === 0 || self._offset >= self._chunkSize) {
- availOutBefore = self._chunkSize;
- self._offset = 0;
- self._buffer = Buffer.allocUnsafe(self._chunkSize);
- }
- if (availOutAfter === 0) {
- inOff += (availInBefore - availInAfter);
- availInBefore = availInAfter;
- return true;
- }
- return false;
- }
- assert(this._handle, 'zlib binding closed');
- do {
- var res = this._handle.writeSync(flushFlag,
- chunk, // in
- inOff, // in_off
- availInBefore, // in_len
- this._buffer, // out
- this._offset, //out_off
- availOutBefore); // out_len
- // Node 8 --> 9 compatibility check
- res = res || this._writeState;
- } while (!this._hadError && handleChunk(res[0], res[1]));
- if (this._hadError) {
- throw error;
- }
- if (nread >= kMaxLength) {
- _close(this);
- throw new RangeError('Cannot create final Buffer. It would be larger than 0x' + kMaxLength.toString(16) + ' bytes');
- }
- var buf = Buffer.concat(buffers, nread);
- _close(this);
- return buf;
- };
- util__default['default'].inherits(Inflate, zlib__default['default'].Inflate);
- function zlibBufferSync(engine, buffer) {
- if (typeof buffer === 'string') {
- buffer = Buffer.from(buffer);
- }
- if (!(buffer instanceof Buffer)) {
- throw new TypeError('Not a string or buffer');
- }
- var flushFlag = engine._finishFlushFlag;
- if (flushFlag == null) {
- flushFlag = zlib__default['default'].Z_FINISH;
- }
- return engine._processChunk(buffer, flushFlag);
- }
- function inflateSync(buffer, opts) {
- return zlibBufferSync(new Inflate(opts), buffer);
- }
- module.exports = exports = inflateSync;
- exports.Inflate = Inflate;
- exports.createInflate = createInflate;
- exports.inflateSync = inflateSync;
- });
- var syncReader = createCommonjsModule(function (module) {
- var SyncReader = module.exports = function(buffer) {
- this._buffer = buffer;
- this._reads = [];
- };
- SyncReader.prototype.read = function(length, callback) {
- this._reads.push({
- length: Math.abs(length), // if length < 0 then at most this length
- allowLess: length < 0,
- func: callback
- });
- };
- SyncReader.prototype.process = function() {
- // as long as there is any data and read requests
- while (this._reads.length > 0 && this._buffer.length) {
- var read = this._reads[0];
- if (this._buffer.length && (this._buffer.length >= read.length || read.allowLess)) {
- // ok there is any data so that we can satisfy this request
- this._reads.shift(); // == read
- var buf = this._buffer;
- this._buffer = buf.slice(read.length);
- read.func.call(this, buf.slice(0, read.length));
- }
- else {
- break;
- }
- }
- if (this._reads.length > 0) {
- return new Error('There are some read requests waitng on finished stream');
- }
- if (this._buffer.length > 0) {
- return new Error('unrecognised content at end of stream');
- }
- };
- });
- var process_1 = function(inBuffer, bitmapInfo) {
- var outBuffers = [];
- var reader = new syncReader(inBuffer);
- var filter = new filterParse(bitmapInfo, {
- read: reader.read.bind(reader),
- write: function(bufferPart) {
- outBuffers.push(bufferPart);
- },
- complete: function() {
- }
- });
- filter.start();
- reader.process();
- return Buffer.concat(outBuffers);
- };
- var filterParseSync = {
- process: process_1
- };
- var hasSyncZlib$1 = true;
- if (!zlib__default['default'].deflateSync) {
- hasSyncZlib$1 = false;
- }
- var parserSync = function(buffer, options) {
- if (!hasSyncZlib$1) {
- throw new Error('To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0');
- }
- var err;
- function handleError(_err_) {
- err = _err_;
- }
- var metaData;
- function handleMetaData(_metaData_) {
- metaData = _metaData_;
- }
- function handleTransColor(transColor) {
- metaData.transColor = transColor;
- }
- function handlePalette(palette) {
- metaData.palette = palette;
- }
- function handleSimpleTransparency() {
- metaData.alpha = true;
- }
- var gamma;
- function handleGamma(_gamma_) {
- gamma = _gamma_;
- }
- var inflateDataList = [];
- function handleInflateData(inflatedData) {
- inflateDataList.push(inflatedData);
- }
- var reader = new syncReader(buffer);
- var parser$1 = new parser(options, {
- read: reader.read.bind(reader),
- error: handleError,
- metadata: handleMetaData,
- gamma: handleGamma,
- palette: handlePalette,
- transColor: handleTransColor,
- inflateData: handleInflateData,
- simpleTransparency: handleSimpleTransparency
- });
- parser$1.start();
- reader.process();
- if (err) {
- throw err;
- }
- //join together the inflate datas
- var inflateData = Buffer.concat(inflateDataList);
- inflateDataList.length = 0;
- var inflatedData;
- if (metaData.interlace) {
- inflatedData = zlib__default['default'].inflateSync(inflateData);
- }
- else {
- var rowSize = ((metaData.width * metaData.bpp * metaData.depth + 7) >> 3) + 1;
- var imageSize = rowSize * metaData.height;
- inflatedData = syncInflate(inflateData, { chunkSize: imageSize, maxLength: imageSize });
- }
- inflateData = null;
- if (!inflatedData || !inflatedData.length) {
- throw new Error('bad png - invalid inflate data response');
- }
- var unfilteredData = filterParseSync.process(inflatedData, metaData);
- inflateData = null;
- var bitmapData = bitmapper.dataToBitMap(unfilteredData, metaData);
- unfilteredData = null;
- var normalisedBitmapData = formatNormaliser(bitmapData, metaData);
- metaData.data = normalisedBitmapData;
- metaData.gamma = gamma || 0;
- return metaData;
- };
- var hasSyncZlib = true;
- if (!zlib__default['default'].deflateSync) {
- hasSyncZlib = false;
- }
- var packerSync = function(metaData, opt) {
- if (!hasSyncZlib) {
- throw new Error('To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0');
- }
- var options = opt || {};
- var packer$1 = new packer(options);
- var chunks = [];
- // Signature
- chunks.push(new Buffer(constants.PNG_SIGNATURE));
- // Header
- chunks.push(packer$1.packIHDR(metaData.width, metaData.height));
- if (metaData.gamma) {
- chunks.push(packer$1.packGAMA(metaData.gamma));
- }
- var filteredData = packer$1.filterData(metaData.data, metaData.width, metaData.height);
- // compress it
- var compressedData = zlib__default['default'].deflateSync(filteredData, packer$1.getDeflateOptions());
- filteredData = null;
- if (!compressedData || !compressedData.length) {
- throw new Error('bad png - invalid compressed data response');
- }
- chunks.push(packer$1.packIDAT(compressedData));
- // End
- chunks.push(packer$1.packIEND());
- return Buffer.concat(chunks);
- };
- var read = function(buffer, options) {
- return parserSync(buffer, options || {});
- };
- var write = function(png, options) {
- return packerSync(png, options);
- };
- var pngSync = {
- read: read,
- write: write
- };
- var png = createCommonjsModule(function (module, exports) {
- var PNG = exports.PNG = function(options) {
- Stream__default['default'].call(this);
- options = options || {}; // eslint-disable-line no-param-reassign
- // coerce pixel dimensions to integers (also coerces undefined -> 0):
- this.width = options.width | 0;
- this.height = options.height | 0;
- this.data = this.width > 0 && this.height > 0 ?
- new Buffer(4 * this.width * this.height) : null;
- if (options.fill && this.data) {
- this.data.fill(0);
- }
- this.gamma = 0;
- this.readable = this.writable = true;
- this._parser = new parserAsync(options);
- this._parser.on('error', this.emit.bind(this, 'error'));
- this._parser.on('close', this._handleClose.bind(this));
- this._parser.on('metadata', this._metadata.bind(this));
- this._parser.on('gamma', this._gamma.bind(this));
- this._parser.on('parsed', function(data) {
- this.data = data;
- this.emit('parsed', data);
- }.bind(this));
- this._packer = new packerAsync(options);
- this._packer.on('data', this.emit.bind(this, 'data'));
- this._packer.on('end', this.emit.bind(this, 'end'));
- this._parser.on('close', this._handleClose.bind(this));
- this._packer.on('error', this.emit.bind(this, 'error'));
- };
- util__default['default'].inherits(PNG, Stream__default['default']);
- PNG.sync = pngSync;
- PNG.prototype.pack = function() {
- if (!this.data || !this.data.length) {
- this.emit('error', 'No data provided');
- return this;
- }
- process.nextTick(function() {
- this._packer.pack(this.data, this.width, this.height, this.gamma);
- }.bind(this));
- return this;
- };
- PNG.prototype.parse = function(data, callback) {
- if (callback) {
- var onParsed, onError;
- onParsed = function(parsedData) {
- this.removeListener('error', onError);
- this.data = parsedData;
- callback(null, this);
- }.bind(this);
- onError = function(err) {
- this.removeListener('parsed', onParsed);
- callback(err, null);
- }.bind(this);
- this.once('parsed', onParsed);
- this.once('error', onError);
- }
- this.end(data);
- return this;
- };
- PNG.prototype.write = function(data) {
- this._parser.write(data);
- return true;
- };
- PNG.prototype.end = function(data) {
- this._parser.end(data);
- };
- PNG.prototype._metadata = function(metadata) {
- this.width = metadata.width;
- this.height = metadata.height;
- this.emit('metadata', metadata);
- };
- PNG.prototype._gamma = function(gamma) {
- this.gamma = gamma;
- };
- PNG.prototype._handleClose = function() {
- if (!this._parser.writable && !this._packer.readable) {
- this.emit('close');
- }
- };
- PNG.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params
- // coerce pixel dimensions to integers (also coerces undefined -> 0):
- /* eslint-disable no-param-reassign */
- srcX |= 0;
- srcY |= 0;
- width |= 0;
- height |= 0;
- deltaX |= 0;
- deltaY |= 0;
- /* eslint-enable no-param-reassign */
- if (srcX > src.width || srcY > src.height || srcX + width > src.width || srcY + height > src.height) {
- throw new Error('bitblt reading outside image');
- }
- if (deltaX > dst.width || deltaY > dst.height || deltaX + width > dst.width || deltaY + height > dst.height) {
- throw new Error('bitblt writing outside image');
- }
- for (var y = 0; y < height; y++) {
- src.data.copy(dst.data,
- ((deltaY + y) * dst.width + deltaX) << 2,
- ((srcY + y) * src.width + srcX) << 2,
- ((srcY + y) * src.width + srcX + width) << 2
- );
- }
- };
- PNG.prototype.bitblt = function(dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params
- PNG.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY);
- return this;
- };
- PNG.adjustGamma = function(src) {
- if (src.gamma) {
- for (var y = 0; y < src.height; y++) {
- for (var x = 0; x < src.width; x++) {
- var idx = (src.width * y + x) << 2;
- for (var i = 0; i < 3; i++) {
- var sample = src.data[idx + i] / 255;
- sample = Math.pow(sample, 1 / 2.2 / src.gamma);
- src.data[idx + i] = Math.round(sample * 255);
- }
- }
- }
- src.gamma = 0;
- }
- };
- PNG.prototype.adjustGamma = function() {
- PNG.adjustGamma(this);
- };
- });
- function getMismatchedPixels(pixelMatchInput) {
- const imgA = fs__default['default'].createReadStream(pixelMatchInput.imageAPath).pipe(new png.PNG()).on('parsed', doneReading);
- const imgB = fs__default['default'].createReadStream(pixelMatchInput.imageBPath).pipe(new png.PNG()).on('parsed', doneReading);
- let filesRead = 0;
- function doneReading() {
- if (++filesRead < 2)
- return;
- const mismatchedPixels = pixelmatch_1(imgA.data, imgB.data, null, pixelMatchInput.width, pixelMatchInput.height, {
- threshold: pixelMatchInput.pixelmatchThreshold,
- includeAA: false,
- });
- process.send(mismatchedPixels);
- }
- }
- process.on('message', getMismatchedPixels);
|