[Pkg-javascript-commits] [pdf.js] 128/161: Optimized putBinaryImageData for GRAYSCALE_1BPP
David Prévot
taffit at moszumanska.debian.org
Sat Apr 19 14:16:38 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository pdf.js.
commit 4e6ebf2de0d081b7a9f88fdec95293d0474d10db
Author: p01 <p01 at opera.com>
Date: Thu Mar 20 16:57:11 2014 +0100
Optimized putBinaryImageData for GRAYSCALE_1BPP
The following changes make putBinaryImageData 2.2x faster.
* Use a Uint32Array to draw whole pixels instead component by component
* Unroll the inner most loop
* Added lazy PDFJS.hasCanvasTypedArrays, PDFJS.isLittleEndian and compatibility
Uint32ArrayView for browsers using the old CanvasPixelArray
---
src/display/canvas.js | 67 +++++++++++++++++++++++---------------------
src/shared/util.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 32 deletions(-)
diff --git a/src/display/canvas.js b/src/display/canvas.js
index 6d60a7d..bcb8516 100644
--- a/src/display/canvas.js
+++ b/src/display/canvas.js
@@ -14,10 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error,
- FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageData, ImageKind,
- isArray, isNum, TilingPattern, OPS, Promise, Util, warn, assert,
- info, shadow, TextRenderingMode, getShadingPatternFromIR */
+/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error, PDFJS,
+ FONT_IDENTITY_MATRIX, Uint32ArrayView, IDENTITY_MATRIX, ImageData,
+ ImageKind, isArray, isNum, TilingPattern, OPS, Promise, Util, warn,
+ assert, info, shadow, TextRenderingMode, getShadingPatternFromIR */
'use strict';
@@ -463,45 +463,48 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
// Grayscale, 1 bit per pixel (i.e. black-and-white).
var destDataLength = dest.length;
var srcLength = src.byteLength;
- for (var i = 3; i < destDataLength; i += 4) {
- dest[i] = 255;
- }
+ var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) :
+ new Uint32ArrayView(dest);
+ var dest32DataLength = dest32.length;
+ var fullSrcDiff = (width + 7) >> 3;
+ var white = 0xFFFFFFFF;
+ var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ?
+ 0xFF000000 : 0x000000FF;
for (var i = 0; i < totalChunks; i++) {
var thisChunkHeight =
(i < fullChunks) ? fullChunkHeight : partialChunkHeight;
var destPos = 0;
for (var j = 0; j < thisChunkHeight; j++) {
+ var srcDiff = srcLength - srcPos;
+ var k = 0;
+ var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7;
+ var kEndUnrolled = kEnd & ~7;
var mask = 0;
var srcByte = 0;
- for (var k = 0; k < width; k++, destPos += 4) {
- if (mask === 0) {
- if (srcPos >= srcLength) {
- break;
- }
- srcByte = src[srcPos++];
- mask = 128;
- }
-
- if ((srcByte & mask)) {
- dest[destPos] = 255;
- dest[destPos + 1] = 255;
- dest[destPos + 2] = 255;
- } else {
- dest[destPos] = 0;
- dest[destPos + 1] = 0;
- dest[destPos + 2] = 0;
- }
+ for (; k < kEndUnrolled; k += 8) {
+ srcByte = src[srcPos++];
+ dest32[destPos++] = (srcByte & 128) ? white : black;
+ dest32[destPos++] = (srcByte & 64) ? white : black;
+ dest32[destPos++] = (srcByte & 32) ? white : black;
+ dest32[destPos++] = (srcByte & 16) ? white : black;
+ dest32[destPos++] = (srcByte & 8) ? white : black;
+ dest32[destPos++] = (srcByte & 4) ? white : black;
+ dest32[destPos++] = (srcByte & 2) ? white : black;
+ dest32[destPos++] = (srcByte & 1) ? white : black;
+ }
+ for (; k < kEnd; k++) {
+ if (mask === 0) {
+ srcByte = src[srcPos++];
+ mask = 128;
+ }
+ dest32[destPos++] = (srcByte & mask) ? white : black;
mask >>= 1;
}
}
- if (destPos < destDataLength) {
- // We ran out of input. Make all remaining pixels transparent.
- destPos += 3;
- do {
- dest[destPos] = 0;
- destPos += 4;
- } while (destPos < destDataLength);
+ // We ran out of input. Make all remaining pixels transparent.
+ while (destPos < dest32DataLength) {
+ dest32[destPos++] = 0;
}
ctx.putImageData(chunkImgData, 0, i * fullChunkHeight);
diff --git a/src/shared/util.js b/src/shared/util.js
index c645d58..a943d47 100644
--- a/src/shared/util.js
+++ b/src/shared/util.js
@@ -410,6 +410,83 @@ function stringToBytes(str) {
return bytes;
}
+// Lazy test the endianness of the platform
+// NOTE: This will be 'true' for simulated TypedArrays
+function isLittleEndian() {
+ var buffer8 = new Uint8Array(2);
+ buffer8[0] = 1;
+ var buffer16 = new Uint16Array(buffer8.buffer);
+ return (buffer16[0] === 1);
+}
+
+Object.defineProperty(PDFJS, 'isLittleEndian', {
+ configurable: true,
+ get: function PDFJS_isLittleEndian() {
+ return shadow(PDFJS, 'isLittleEndian', isLittleEndian());
+ }
+});
+
+//#if !(FIREFOX || MOZCENTRAL || B2G || CHROME)
+// Lazy test if the userAgant support CanvasTypedArrays
+function hasCanvasTypedArrays() {
+ var canvas = document.createElement('canvas');
+ canvas.width = canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ var imageData = ctx.createImageData(1, 1);
+ return (typeof imageData.data.buffer !== 'undefined');
+}
+
+Object.defineProperty(PDFJS, 'hasCanvasTypedArrays', {
+ configurable: true,
+ get: function PDFJS_hasCanvasTypedArrays() {
+ return shadow(PDFJS, 'hasCanvasTypedArrays', hasCanvasTypedArrays());
+ }
+});
+
+// Uint32ArrayView
+var Uint32ArrayView = (function Uint32ArrayViewClosure() {
+
+ function Uint32ArrayView(buffer) {
+ this.buffer = buffer;
+ this.byteLength = buffer.length;
+ this.length = (this.byteLength >> 2);
+ ensureUint32ArrayViewProps(this.length);
+ }
+ Uint32ArrayView.prototype = Object.create(null);
+
+ var uint32ArrayViewSetters = 0;
+ function createUint32ArrayProp(index) {
+ return {
+ get: function () {
+ var buffer = this.buffer, offset = index << 2;
+ return (buffer[offset] | (buffer[offset + 1] << 8) |
+ (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24)) >>> 0;
+ },
+ set: function (value) {
+ var buffer = this.buffer, offset = index << 2;
+ buffer[offset] = value & 255;
+ buffer[offset + 1] = (value >> 8) & 255;
+ buffer[offset + 2] = (value >> 16) & 255;
+ buffer[offset + 3] = (value >>> 24) & 255;
+ }
+ };
+ }
+
+ function ensureUint32ArrayViewProps(length) {
+ while (uint32ArrayViewSetters < length) {
+ Object.defineProperty(Uint32ArrayView.prototype,
+ uint32ArrayViewSetters,
+ createUint32ArrayProp(uint32ArrayViewSetters));
+ uint32ArrayViewSetters++;
+ }
+ }
+
+ return Uint32ArrayView;
+})();
+//#else
+//PDFJS.hasCanvasTypedArrays = true;
+//#endif
+
var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
var Util = PDFJS.Util = (function UtilClosure() {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git
More information about the Pkg-javascript-commits
mailing list