}
return null;
};
+ /**
+ * Checks if a decode map matches the default decode map for a color space.
+ * This handles the general decode maps where there are two values per
+ * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
+ * This does not handle Lab, Indexed, or Pattern decode maps since they are
+ * slightly different.
+ * @param {Array} decode Decode map (usually from an image).
+ * @param {Number} n Number of components the color space has.
+ */
+ ColorSpace.isDefaultDecode = function colorSpaceIsDefaultDecode(decode, n) {
+ if (!decode)
+ return true;
+
+ if (n * 2 !== decode.length) {
+ warning('The decode map is not the correct length');
+ return true;
+ }
+ for (var i = 0, ii = decode.length; i < ii; i += 2) {
+ if (decode[i] != 0 || decode[i + 1] != 1)
+ return false;
+ }
+ return true;
+ };
return ColorSpace;
})();
baseBuf[pos++] = 255 * tinted[j];
}
return base.getRgbBuffer(baseBuf, 8);
+ },
+ isDefaultDecode: function altcs_isDefaultDecode(decodeMap) {
+ ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
}
return base.getRgbBuffer(baseBuf, 8);
+ },
+ isDefaultDecode: function indexcs_isDefaultDecode(decodeMap) {
+ // indexed color maps shouldn't be changed
+ return true;
}
};
return IndexedCS;
rgbBuf[j++] = c;
}
return rgbBuf;
+ },
+ isDefaultDecode: function graycs_isDefaultDecode(decodeMap) {
+ ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
return DeviceGrayCS;
for (i = 0; i < length; ++i)
rgbBuf[i] = (scale * input[i]) | 0;
return rgbBuf;
+ },
+ isDefaultDecode: function rgbcs_isDefaultDecode(decodeMap) {
+ return 0 == decodeMap[0] == decodeMap[2] == decodeMap[4] &&
+ 1 == decodeMap[1] == decodeMap[3] == decoeMap[5];
}
};
return DeviceRgbCS;
}
return rgbBuf;
+ },
+ isDefaultDecode: function cmykcs_isDefaultDecode(decodeMap) {
+ ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
}
}
/**
- * Decode and clamp a value.
+ * Decode and clamp a value. The formula is different from the spec because we
+ * don't decode to float range [0,1], we decode it in the [0,max] range.
*/
- function decode(value, addend, coefficient, max) {
- // This formula is different from the spec because we don't decode to
- // float range [0,1], we decode it in the [0,max] range.
+ function decodeAndClamp(value, addend, coefficient, max) {
value = addend + value * coefficient;
// Clamp the value to the range
return value < 0 ? 0 : value > max ? max : value;
}
this.decode = dict.get('Decode', 'D');
- if (this.decode && !this.hasDefaultDecode()) {
+ this.needsDecode = false;
+ if (this.decode && this.colorSpace &&
+ !this.colorSpace.isDefaultDecode(this.decode)) {
+ this.needsDecode = true;
// Do some preprocessing to avoid more math.
var max = (1 << bitsPerComponent) - 1;
this.decodeCoefficients = [];
PDFImage.prototype = {
getComponents: function getComponents(buffer) {
var bpc = this.bpc;
- var defaultDecode = this.hasDefaultDecode();
+ var needsDecode = this.needsDecode;
var decodeMap = this.decode;
- if (decodeMap) console.time('getComps');
- // This image doesn't require extra work
- if (bpc == 8 && defaultDecode)
+
+ // This image doesn't require any extra work.
+ if (bpc == 8 && !needsDecode)
return buffer;
+
var bufferLength = buffer.length;
var width = this.width;
var height = this.height;
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
var rowComps = width * numComps;
var decodeAddends, decodeCoefficients;
- if (!defaultDecode) {
+ if (needsDecode) {
decodeAddends = this.decodeAddends;
decodeCoefficients = this.decodeCoefficients;
}
for (var i = 0, ii = length; i < ii; ++i) {
var compIndex = i % numComps;
var value = buffer[i];
- value = decode(value, decodeAddends[compIndex],
+ value = decodeAndClamp(value, decodeAddends[compIndex],
decodeCoefficients[compIndex], max);
output[i] = value;
}
var remainingBits = bits - bpc;
var value = buf >> remainingBits;
- if (!defaultDecode) {
+ if (needsDecode) {
var compIndex = i % numComps;
- value = decode(value, decodeAddends[compIndex],
+ value = decodeAndClamp(value, decodeAddends[compIndex],
decodeCoefficients[compIndex], max);
}
output[i] = value;
getImageBytes: function getImageBytes(length) {
this.image.reset();
return this.image.getBytes(length);
- },
- hasDefaultDecode: function hasDefaultDecode() {
- // TODO lab color as a way different decode map
- if (!this.decode)
- return true;
- var numComps = this.numComps;
- var decode = this.decode;
- if (numComps * 2 !== decode.length) {
- warning('The decode map is not the correct length');
- return true;
- }
- for (var i = 0, ii = decode.length; i < ii; i += 2) {
- if (decode[i] != 0 || decode[i + 1] != 1)
- return false;
- }
- return true;
}
};
return PDFImage;