// Lossless Chromium screenshots: tolerate a few rasterization pixels while // keeping strict geometry/style comparisons in the calling UI test. const { inflateSync } = require('node:zlib'); function decode(buffer) { let width,height,channels;const chunks=[]; for(let offset=8;offset{const p=a+b-c,da=Math.abs(p-a),db=Math.abs(p-b),dc=Math.abs(p-c);return da<=db&&da<=dc?a:db<=dc?b:c;}; for(let y=0;y4)throw new Error('Unexpected PNG filter'); for(let x=0;x=channels?pixels[index-channels]:0,b=y?pixels[index-stride]:0,c=y&&x>=channels?pixels[index-stride-channels]:0; pixels[index]=(raw[position++]+[0,a,b,Math.floor((a+b)/2),paeth(a,b,c)][filter])&255; } } return {width,height,channels,pixels}; } function differentPixels(first,second,channelTolerance=0){ const a=decode(first),b=decode(second);if(a.width!==b.width||a.height!==b.height||a.channels!==b.channels)return Infinity; let count=0;for(let i=0;iMath.abs(value-b.pixels[i+channel])>channelTolerance))count++; return count; } module.exports={differentPixels};