[Pkg-javascript-commits] [pdf.js] 156/246: Reduces amount of used memory during PNG creation.

David Prévot taffit at moszumanska.debian.org
Sun Sep 7 15:36:36 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 56f0539045540231964ef20bc16f5c4964993752
Author: Yury Delendik <ydelendik at mozilla.com>
Date:   Sat Aug 9 15:53:05 2014 -0500

    Reduces amount of used memory during PNG creation.
---
 src/display/svg.js | 98 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 55 insertions(+), 43 deletions(-)

diff --git a/src/display/svg.js b/src/display/svg.js
index 46048f5..13b2648 100644
--- a/src/display/svg.js
+++ b/src/display/svg.js
@@ -30,7 +30,12 @@ function createScratchSVG(width, height) {
 }
 
 var convertImgDataToPng = (function convertImgDataToPngClosure() {
-  var crcTable = [];
+  var PNG_HEADER =
+    new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
+
+  var CHUNK_WRAPPER_SIZE = 12;
+
+  var crcTable = new Int32Array(256);
   for (var i = 0; i < 256; i++) {
     var c = i;
     for (var h = 0; h < 8; h++) {
@@ -53,32 +58,32 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
     return crc ^ -1;
   }
 
-  function createPngChunk(type, data) {
-    var chunk = new Uint8Array(12 + data.length);
-    var p = 0;
+  function writePngChunk(type, body, data, offset) {
+    var p = offset;
 
-    var len = data.length;
-    chunk[p] = len >> 24 & 0xff;
-    chunk[p + 1] = len >> 16 & 0xff;
-    chunk[p + 2] = len >> 8 & 0xff;
-    chunk[p + 3] = len & 0xff;
+    var len = body.length;
 
-    chunk[p + 4] = type.charCodeAt(0) & 0xff;
-    chunk[p + 5] = type.charCodeAt(1) & 0xff;
-    chunk[p + 6] = type.charCodeAt(2) & 0xff;
-    chunk[p + 7] = type.charCodeAt(3) & 0xff;
+    data[p] = len >> 24 & 0xff;
+    data[p + 1] = len >> 16 & 0xff;
+    data[p + 2] = len >> 8 & 0xff;
+    data[p + 3] = len & 0xff;
+    p += 4;
 
-    chunk.set(data, 8);
+    data[p] = type.charCodeAt(0) & 0xff;
+    data[p + 1] = type.charCodeAt(1) & 0xff;
+    data[p + 2] = type.charCodeAt(2) & 0xff;
+    data[p + 3] = type.charCodeAt(3) & 0xff;
+    p += 4;
 
-    p = 8 + len;
+    data.set(body, p);
+    p += body.length;
 
-    var crc = crc32(chunk, 4, p);
-    chunk[p] = crc >> 24 & 0xff;
-    chunk[p + 1] = crc >> 16 & 0xff;
-    chunk[p + 2] = crc >> 8 & 0xff;
-    chunk[p + 3] = crc & 0xff;
+    var crc = crc32(data, offset + 4, p);
 
-    return chunk;
+    data[p] = crc >> 24 & 0xff;
+    data[p + 1] = crc >> 16 & 0xff;
+    data[p + 2] = crc >> 8 & 0xff;
+    data[p + 3] = crc & 0xff;
   }
 
   function adler32(data, start, end) {
@@ -119,18 +124,26 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
         throw new Error('invalid format');
     }
 
+    // prefix every row with predictor 0
     var literals = new Uint8Array((1 + lineSize) * height);
     var offsetLiterals = 0, offsetBytes = 0;
-    for (var y = 0; y < height; ++y) {
-      literals[offsetLiterals++] = 0;
+    var y, i;
+    for (y = 0; y < height; ++y) {
+      literals[offsetLiterals++] = 0; // no prediction
       literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize),
                    offsetLiterals);
       offsetBytes += lineSize;
       offsetLiterals += lineSize;
     }
+
     if (kind === ImageKind.GRAYSCALE_1BPP) {
-      for (var i = 0, ii = bytes.length; i < ii; i++) {
-        bytes[i] ^= 0xFF;
+      // inverting for B/W
+      offsetLiterals = 0;
+      for (y = 0; y < height; y++) {
+        offsetLiterals++; // skipping predictor
+        for (i = 0; i < lineSize; i++) {
+          literals[offsetLiterals++] ^= 0xFF;
+        }
       }
     }
 
@@ -153,14 +166,15 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
     var len = literals.length;
     var maxBlockLength = 0xFFFF;
 
-    var idat = new Uint8Array(2 + len +
-                              Math.ceil(len / maxBlockLength) * 5 + 4);
+    var deflateBlocks = Math.ceil(len / maxBlockLength);
+    var idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4);
     var pi = 0;
     idat[pi++] = 0x78; // compression method and flags
     idat[pi++] = 0x9c;  // flags
 
     var pos = 0;
     while (len > maxBlockLength) {
+      // writing non-final DEFLATE blocks type 0 and length of 65535
       idat[pi++] = 0x00;
       idat[pi++] = 0xff;
       idat[pi++] = 0xff;
@@ -172,12 +186,12 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
       len -= maxBlockLength;
     }
 
+    // writing non-final DEFLATE blocks type 0
     idat[pi++] = 0x01;
     idat[pi++] = len & 0xff;
     idat[pi++] = len >> 8 & 0xff;
     idat[pi++] = (~len & 0xffff) & 0xff;
     idat[pi++] = (~len & 0xffff) >> 8 & 0xff;
-
     idat.set(literals.subarray(pos), pi);
     pi += literals.length - pos;
 
@@ -187,28 +201,26 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
     idat[pi++] = adler >> 8 & 0xff;
     idat[pi++] = adler & 0xff;
 
-    var chunks = [
-      new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
-      createPngChunk('IHDR', ihdr),
-      createPngChunk('IDAT', idat),
-      createPngChunk('IEND', new Uint8Array(0))
-    ];
+    // PNG will consists: header, IHDR+data, IDAT+data, and IEND.
+    var pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 +
+      ihdr.length + idat.length;
+    var data = new Uint8Array(pngLength);
+    var offset = 0;
+    data.set(PNG_HEADER, offset);
+    offset += PNG_HEADER.length;
+    writePngChunk('IHDR', ihdr, data, offset);
+    offset += CHUNK_WRAPPER_SIZE + ihdr.length;
+    writePngChunk('IDATA', idat, data, offset);
+    offset += CHUNK_WRAPPER_SIZE + idat.length;
+    writePngChunk('IEND', new Uint8Array(0), data, offset);
 
-    var data = [];
-    for (var j = 0; j < 3; j++) {
-      data.push.apply(data, chunks[j]);
-    }
-    data = new Uint8Array(data);
     return PDFJS.createObjectURL(data, 'image/png');
   }
 
   return function convertImgDataToPng(imgData) {
     var kind = (imgData.kind === undefined ?
       ImageKind.GRAYSCALE_1BPP : imgData.kind);
-    var url = encode(imgData, kind);
-    if (url) {
-      return url;
-    }
+    return encode(imgData, kind);
   };
 })();
 

-- 
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