[Pkg-javascript-commits] [pdf.js] 21/161: Refactors optimization list
David Prévot
taffit at moszumanska.debian.org
Sat Apr 19 14:16:19 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 dbb3d17d8f836e60ea5c364b9a51c8ab5cb59bd1
Author: Yury Delendik <ydelendik at mozilla.com>
Date: Sun Feb 23 20:42:54 2014 -0600
Refactors optimization list
---
src/core/evaluator.js | 302 ++++++++++++++++++++++++++++----------------------
1 file changed, 171 insertions(+), 131 deletions(-)
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index b06dfe7..0cd268c 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -1236,136 +1236,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
};
- PartialEvaluator.optimizeQueue =
- function PartialEvaluator_optimizeQueue(queue) {
-
- function squash(array, index, howMany, element) {
- if (isArray(array)) {
- array.splice(index, howMany, element);
- } else {
- // Replace the element.
- array[index] = element;
- // Shift everything after the element up.
- var sub = array.subarray(index + howMany);
- array.set(sub, index + 1);
- }
- }
-
- var fnArray = queue.fnArray, argsArray = queue.argsArray;
- // grouping paintInlineImageXObject's into paintInlineImageXObjectGroup
- // searching for (save, transform, paintInlineImageXObject, restore)+
- var MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
- var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
- var MAX_WIDTH = 1000;
- var IMAGE_PADDING = 1;
- for (var i = 0, ii = argsArray.length; i < ii; i++) {
- if (fnArray[i] === OPS.paintInlineImageXObject &&
- fnArray[i - 2] === OPS.save && fnArray[i - 1] === OPS.transform &&
- fnArray[i + 1] === OPS.restore) {
- var j = i - 2;
- for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
- }
- var count = Math.min((i - j) >> 2,
- MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
- if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
- continue;
- }
- // assuming that heights of those image is too small (~1 pixel)
- // packing as much as possible by lines
- var maxX = 0;
- var map = [], maxLineHeight = 0;
- var currentX = IMAGE_PADDING, currentY = IMAGE_PADDING;
- for (var q = 0; q < count; q++) {
- var transform = argsArray[j + (q << 2) + 1];
- var img = argsArray[j + (q << 2) + 2][0];
- if (currentX + img.width > MAX_WIDTH) {
- // starting new line
- maxX = Math.max(maxX, currentX);
- currentY += maxLineHeight + 2 * IMAGE_PADDING;
- currentX = 0;
- maxLineHeight = 0;
- }
- map.push({
- transform: transform,
- x: currentX, y: currentY,
- w: img.width, h: img.height
- });
- currentX += img.width + 2 * IMAGE_PADDING;
- maxLineHeight = Math.max(maxLineHeight, img.height);
- }
- var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
- var imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
- var imgData = new Uint8Array(imgWidth * imgHeight * 4);
- var imgRowSize = imgWidth << 2;
- for (var q = 0; q < count; q++) {
- var data = argsArray[j + (q << 2) + 2][0].data;
- // copy image by lines and extends pixels into padding
- var rowSize = map[q].w << 2;
- var dataOffset = 0;
- var offset = (map[q].x + map[q].y * imgWidth) << 2;
- imgData.set(
- data.subarray(0, rowSize), offset - imgRowSize);
- for (var k = 0, kk = map[q].h; k < kk; k++) {
- imgData.set(
- data.subarray(dataOffset, dataOffset + rowSize), offset);
- dataOffset += rowSize;
- offset += imgRowSize;
- }
- imgData.set(
- data.subarray(dataOffset - rowSize, dataOffset), offset);
- while (offset >= 0) {
- data[offset - 4] = data[offset];
- data[offset - 3] = data[offset + 1];
- data[offset - 2] = data[offset + 2];
- data[offset - 1] = data[offset + 3];
- data[offset + rowSize] = data[offset + rowSize - 4];
- data[offset + rowSize + 1] = data[offset + rowSize - 3];
- data[offset + rowSize + 2] = data[offset + rowSize - 2];
- data[offset + rowSize + 3] = data[offset + rowSize - 1];
- offset -= imgRowSize;
- }
- }
- // replacing queue items
- squash(fnArray, j, count * 4, OPS.paintInlineImageXObjectGroup);
- argsArray.splice(j, count * 4,
- [{width: imgWidth, height: imgHeight, kind: ImageKind.RGBA_32BPP,
- data: imgData}, map]);
- i = j;
- ii = argsArray.length;
- }
- }
- // grouping paintImageMaskXObject's into paintImageMaskXObjectGroup
- // searching for (save, transform, paintImageMaskXObject, restore)+
- var MIN_IMAGES_IN_MASKS_BLOCK = 10;
- var MAX_IMAGES_IN_MASKS_BLOCK = 100;
- for (var i = 0, ii = argsArray.length; i < ii; i++) {
- if (fnArray[i] === OPS.paintImageMaskXObject &&
- fnArray[i - 2] === OPS.save && fnArray[i - 1] === OPS.transform &&
- fnArray[i + 1] === OPS.restore) {
- var j = i - 2;
- for (i += 2; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
- }
- var count = Math.min((i - j) >> 2,
- MAX_IMAGES_IN_MASKS_BLOCK);
- if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
- continue;
- }
- var images = [];
- for (var q = 0; q < count; q++) {
- var transform = argsArray[j + (q << 2) + 1];
- var maskParams = argsArray[j + (q << 2) + 2][0];
- images.push({data: maskParams.data, width: maskParams.width,
- height: maskParams.height, transform: transform});
- }
- // replacing queue items
- squash(fnArray, j, count * 4, OPS.paintImageMaskXObjectGroup);
- argsArray.splice(j, count * 4, [images]);
- i = j;
- ii = argsArray.length;
- }
- }
- };
-
return PartialEvaluator;
})();
@@ -1454,7 +1324,7 @@ var OperatorList = (function OperatorListClosure() {
},
flush: function(lastChunk) {
- PartialEvaluator.optimizeQueue(this);
+ new QueueOptimizer().optimize(this);
var transfers = getTransfers(this);
this.messageHandler.send('RenderPageChunk', {
operatorList: {
@@ -1758,3 +1628,173 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessor() {
};
return EvaluatorPreprocessor;
})();
+
+var QueueOptimizer = (function QueueOptimizerClosure() {
+ function squash(array, index, howMany, element) {
+ if (isArray(array)) {
+ array.splice(index, howMany, element);
+ } else {
+ // Replace the element.
+ array[index] = element;
+ // Shift everything after the element up.
+ var sub = array.subarray(index + howMany);
+ array.set(sub, index + 1);
+ }
+ }
+
+ function addState(parentState, pattern, fn) {
+ var state = parentState;
+ for (var i = 0, ii = pattern.length - 1; i < ii; i++) {
+ var item = pattern[i];
+ state = state[item] || (state[item] = []);
+ }
+ state[pattern[pattern.length - 1]] = fn;
+ }
+
+ var InitialState = [];
+
+ addState(InitialState,
+ [OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore],
+ function foundInlineImageGroup(context) {
+ // grouping paintInlineImageXObject's into paintInlineImageXObjectGroup
+ // searching for (save, transform, paintInlineImageXObject, restore)+
+ var MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
+ var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
+ var MAX_WIDTH = 1000;
+ var IMAGE_PADDING = 1;
+
+ var fnArray = context.fnArray, argsArray = context.argsArray;
+ var j = context.currentOperation - 3, i = j + 4;
+ var ii = context.operationsLength;
+
+ for (; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
+ }
+ var count = Math.min((i - j) >> 2, MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
+ if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
+ context.currentOperation = i - 1;
+ return;
+ }
+ // assuming that heights of those image is too small (~1 pixel)
+ // packing as much as possible by lines
+ var maxX = 0;
+ var map = [], maxLineHeight = 0;
+ var currentX = IMAGE_PADDING, currentY = IMAGE_PADDING;
+ for (var q = 0; q < count; q++) {
+ var transform = argsArray[j + (q << 2) + 1];
+ var img = argsArray[j + (q << 2) + 2][0];
+ if (currentX + img.width > MAX_WIDTH) {
+ // starting new line
+ maxX = Math.max(maxX, currentX);
+ currentY += maxLineHeight + 2 * IMAGE_PADDING;
+ currentX = 0;
+ maxLineHeight = 0;
+ }
+ map.push({
+ transform: transform,
+ x: currentX, y: currentY,
+ w: img.width, h: img.height
+ });
+ currentX += img.width + 2 * IMAGE_PADDING;
+ maxLineHeight = Math.max(maxLineHeight, img.height);
+ }
+ var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
+ var imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
+ var imgData = new Uint8Array(imgWidth * imgHeight * 4);
+ var imgRowSize = imgWidth << 2;
+ for (var q = 0; q < count; q++) {
+ var data = argsArray[j + (q << 2) + 2][0].data;
+ // copy image by lines and extends pixels into padding
+ var rowSize = map[q].w << 2;
+ var dataOffset = 0;
+ var offset = (map[q].x + map[q].y * imgWidth) << 2;
+ imgData.set(
+ data.subarray(0, rowSize), offset - imgRowSize);
+ for (var k = 0, kk = map[q].h; k < kk; k++) {
+ imgData.set(
+ data.subarray(dataOffset, dataOffset + rowSize), offset);
+ dataOffset += rowSize;
+ offset += imgRowSize;
+ }
+ imgData.set(
+ data.subarray(dataOffset - rowSize, dataOffset), offset);
+ while (offset >= 0) {
+ data[offset - 4] = data[offset];
+ data[offset - 3] = data[offset + 1];
+ data[offset - 2] = data[offset + 2];
+ data[offset - 1] = data[offset + 3];
+ data[offset + rowSize] = data[offset + rowSize - 4];
+ data[offset + rowSize + 1] = data[offset + rowSize - 3];
+ data[offset + rowSize + 2] = data[offset + rowSize - 2];
+ data[offset + rowSize + 3] = data[offset + rowSize - 1];
+ offset -= imgRowSize;
+ }
+ }
+ // replacing queue items
+ squash(fnArray, j, count * 4, OPS.paintInlineImageXObjectGroup);
+ argsArray.splice(j, count * 4,
+ [{width: imgWidth, height: imgHeight, kind: ImageKind.RGBA_32BPP,
+ data: imgData}, map]);
+ context.currentOperation = j;
+ context.operationsLength -= count * 4 - 1;
+ });
+
+ addState(InitialState,
+ [OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore],
+ function foundImageMaskGroup(context) {
+ // grouping paintImageMaskXObject's into paintImageMaskXObjectGroup
+ // searching for (save, transform, paintImageMaskXObject, restore)+
+ var MIN_IMAGES_IN_MASKS_BLOCK = 10;
+ var MAX_IMAGES_IN_MASKS_BLOCK = 100;
+
+ var fnArray = context.fnArray, argsArray = context.argsArray;
+ var j = context.currentOperation - 3, i = j + 4;
+ var ii = context.operationsLength;
+
+ for (; i < ii && fnArray[i - 4] === fnArray[i]; i++) {
+ }
+ var count = Math.min((i - j) >> 2, MAX_IMAGES_IN_MASKS_BLOCK);
+ if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
+ context.currentOperation = i - 1;
+ return;
+ }
+ var images = [];
+ for (var q = 0; q < count; q++) {
+ var transform = argsArray[j + (q << 2) + 1];
+ var maskParams = argsArray[j + (q << 2) + 2][0];
+ images.push({data: maskParams.data, width: maskParams.width,
+ height: maskParams.height, transform: transform});
+ }
+ // replacing queue items
+ squash(fnArray, j, count * 4, OPS.paintImageMaskXObjectGroup);
+ argsArray.splice(j, count * 4, [images]);
+
+ context.currentOperation = j;
+ context.operationsLength -= count * 4 - 1;
+ });
+
+ function QueueOptimizer() {
+ }
+ QueueOptimizer.prototype = {
+ optimize: function QueueOptimizer_optimize(queue) {
+ var fnArray = queue.fnArray, argsArray = queue.argsArray;
+ var context = {
+ currentOperation: 0,
+ operationsLength: argsArray.length,
+ fnArray: fnArray,
+ argsArray: argsArray
+ };
+ var i, ii = argsArray.length;
+ var state;
+ for (i = 0; i < ii; i++) {
+ state = (state || InitialState)[fnArray[i]];
+ if (typeof state === 'function') { // we found some handler
+ context.currentOperation = i;
+ state = state(context);
+ i = context.currentOperation;
+ ii = context.operationsLength;
+ }
+ }
+ }
+ };
+ return QueueOptimizer;
+})();
--
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