Merge pull request #4466 from p01/Faster_1BPP_image_drawing
Faster 1 bpp image drawing
This commit is contained in:
commit
e80c6a8a75
@ -14,10 +14,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error,
|
/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error, PDFJS,
|
||||||
FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageData, ImageKind,
|
FONT_IDENTITY_MATRIX, Uint32ArrayView, IDENTITY_MATRIX, ImageData,
|
||||||
isArray, isNum, TilingPattern, OPS, Promise, Util, warn, assert,
|
ImageKind, isArray, isNum, TilingPattern, OPS, Promise, Util, warn,
|
||||||
info, shadow, TextRenderingMode, getShadingPatternFromIR */
|
assert, info, shadow, TextRenderingMode, getShadingPatternFromIR */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -463,45 +463,48 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
// Grayscale, 1 bit per pixel (i.e. black-and-white).
|
// Grayscale, 1 bit per pixel (i.e. black-and-white).
|
||||||
var destDataLength = dest.length;
|
var destDataLength = dest.length;
|
||||||
var srcLength = src.byteLength;
|
var srcLength = src.byteLength;
|
||||||
for (var i = 3; i < destDataLength; i += 4) {
|
var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) :
|
||||||
dest[i] = 255;
|
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++) {
|
for (var i = 0; i < totalChunks; i++) {
|
||||||
var thisChunkHeight =
|
var thisChunkHeight =
|
||||||
(i < fullChunks) ? fullChunkHeight : partialChunkHeight;
|
(i < fullChunks) ? fullChunkHeight : partialChunkHeight;
|
||||||
var destPos = 0;
|
var destPos = 0;
|
||||||
for (var j = 0; j < thisChunkHeight; j++) {
|
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 mask = 0;
|
||||||
var srcByte = 0;
|
var srcByte = 0;
|
||||||
for (var k = 0; k < width; k++, destPos += 4) {
|
for (; k < kEndUnrolled; k += 8) {
|
||||||
if (mask === 0) {
|
srcByte = src[srcPos++];
|
||||||
if (srcPos >= srcLength) {
|
dest32[destPos++] = (srcByte & 128) ? white : black;
|
||||||
break;
|
dest32[destPos++] = (srcByte & 64) ? white : black;
|
||||||
}
|
dest32[destPos++] = (srcByte & 32) ? white : black;
|
||||||
srcByte = src[srcPos++];
|
dest32[destPos++] = (srcByte & 16) ? white : black;
|
||||||
mask = 128;
|
dest32[destPos++] = (srcByte & 8) ? white : black;
|
||||||
}
|
dest32[destPos++] = (srcByte & 4) ? white : black;
|
||||||
|
dest32[destPos++] = (srcByte & 2) ? white : black;
|
||||||
if ((srcByte & mask)) {
|
dest32[destPos++] = (srcByte & 1) ? white : black;
|
||||||
dest[destPos] = 255;
|
}
|
||||||
dest[destPos + 1] = 255;
|
for (; k < kEnd; k++) {
|
||||||
dest[destPos + 2] = 255;
|
if (mask === 0) {
|
||||||
} else {
|
srcByte = src[srcPos++];
|
||||||
dest[destPos] = 0;
|
mask = 128;
|
||||||
dest[destPos + 1] = 0;
|
}
|
||||||
dest[destPos + 2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
dest32[destPos++] = (srcByte & mask) ? white : black;
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (destPos < destDataLength) {
|
// We ran out of input. Make all remaining pixels transparent.
|
||||||
// We ran out of input. Make all remaining pixels transparent.
|
while (destPos < dest32DataLength) {
|
||||||
destPos += 3;
|
dest32[destPos++] = 0;
|
||||||
do {
|
|
||||||
dest[destPos] = 0;
|
|
||||||
destPos += 4;
|
|
||||||
} while (destPos < destDataLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.putImageData(chunkImgData, 0, i * fullChunkHeight);
|
ctx.putImageData(chunkImgData, 0, i * fullChunkHeight);
|
||||||
|
@ -410,6 +410,83 @@ function stringToBytes(str) {
|
|||||||
return bytes;
|
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 IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
||||||
|
|
||||||
var Util = PDFJS.Util = (function UtilClosure() {
|
var Util = PDFJS.Util = (function UtilClosure() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user