3 var paethPredictor = require('./paeth-predictor');
5 function filterNone(pxData, pxPos, byteWidth, rawData, rawPos) {
7 for (var x = 0; x < byteWidth; x++) {
8 rawData[rawPos + x] = pxData[pxPos + x];
12 function filterSumNone(pxData, pxPos, byteWidth) {
15 var length = pxPos + byteWidth;
17 for (var i = pxPos; i < length; i++) {
18 sum += Math.abs(pxData[i]);
23 function filterSub(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
25 for (var x = 0; x < byteWidth; x++) {
27 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
28 var val = pxData[pxPos + x] - left;
30 rawData[rawPos + x] = val;
34 function filterSumSub(pxData, pxPos, byteWidth, bpp) {
37 for (var x = 0; x < byteWidth; x++) {
39 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
40 var val = pxData[pxPos + x] - left;
48 function filterUp(pxData, pxPos, byteWidth, rawData, rawPos) {
50 for (var x = 0; x < byteWidth; x++) {
52 var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
53 var val = pxData[pxPos + x] - up;
55 rawData[rawPos + x] = val;
59 function filterSumUp(pxData, pxPos, byteWidth) {
62 var length = pxPos + byteWidth;
63 for (var x = pxPos; x < length; x++) {
65 var up = pxPos > 0 ? pxData[x - byteWidth] : 0;
66 var val = pxData[x] - up;
74 function filterAvg(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
76 for (var x = 0; x < byteWidth; x++) {
78 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
79 var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
80 var val = pxData[pxPos + x] - ((left + up) >> 1);
82 rawData[rawPos + x] = val;
86 function filterSumAvg(pxData, pxPos, byteWidth, bpp) {
89 for (var x = 0; x < byteWidth; x++) {
91 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
92 var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
93 var val = pxData[pxPos + x] - ((left + up) >> 1);
101 function filterPaeth(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
103 for (var x = 0; x < byteWidth; x++) {
105 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
106 var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
107 var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
108 var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
110 rawData[rawPos + x] = val;
114 function filterSumPaeth(pxData, pxPos, byteWidth, bpp) {
116 for (var x = 0; x < byteWidth; x++) {
118 var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
119 var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
120 var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
121 var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
123 sum += Math.abs(val);
145 module.exports = function(pxData, width, height, options, bpp) {
148 if (!('filterType' in options) || options.filterType === -1) {
149 filterTypes = [0, 1, 2, 3, 4];
151 else if (typeof options.filterType === 'number') {
152 filterTypes = [options.filterType];
155 throw new Error('unrecognised filter types');
158 if (options.bitDepth === 16) {
161 var byteWidth = width * bpp;
164 var rawData = new Buffer((byteWidth + 1) * height);
166 var sel = filterTypes[0];
168 for (var y = 0; y < height; y++) {
170 if (filterTypes.length > 1) {
171 // find best filter for this line (with lowest sum of values)
174 for (var i = 0; i < filterTypes.length; i++) {
175 var sum = filterSums[filterTypes[i]](pxData, pxPos, byteWidth, bpp);
177 sel = filterTypes[i];
183 rawData[rawPos] = sel;
185 filters[sel](pxData, pxPos, byteWidth, rawData, rawPos, bpp);