mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
Optimize PNG compression in SVG backend on Node.js
Use the environment's zlib implementation if available to get reasonably-sized SVG files when an XObject image is converted to PNG. The generated PNG is not optimal because we do not use a PNG predictor. Futher, when our SVG backend is run in a browser, the generated PNG images will still be unnecessarily large (though the use of blob:-URLs when available should reduce the impact on memory usage). If we want to optimize PNG images in browsers too, we can either try to use a DEFLATE library such as pako, or re-use our XObject image painting logic in src/display/canvas.js. This potential improvement is not implemented by this commit Tested with: - Node.js 8.1.3 (uses zlib) - Node.js 0.11.12 (uses zlib) - Node.js 0.10.48 (falls back to inferior existing implementation). - Chrome 59.0.3071.86 - Firefox 54.0 Tests: Unit test on Node.js: ``` $ gulp lib $ JASMINE_CONFIG_PATH=test/unit/clitests.json node ./node_modules/.bin/jasmine --filter=SVG ``` Unit test in browser: Run `gulp server` and open http://localhost:8888/test/unit/unit_test.html?spec=SVGGraphics To verify that the patch works as desired, ``` $ node examples/node/pdf2svg.js test/pdfs/xobject-image.pdf $ du -b svgdump/xobject-image-1.svg # ^ Calculates the file size. Confirm that the size is small # (784 instead of 80664 bytes). ```
This commit is contained in:
parent
3479a19bf0
commit
01f03fe393
7 changed files with 233 additions and 1 deletions
|
@ -12,10 +12,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals __non_webpack_require__ */
|
||||
|
||||
import {
|
||||
createObjectURL, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, isArray,
|
||||
isNum, OPS, Util, warn
|
||||
isNodeJS, isNum, OPS, Util, warn
|
||||
} from '../shared/util';
|
||||
|
||||
var SVGGraphics = function() {
|
||||
|
@ -104,6 +105,37 @@ var convertImgDataToPng = (function convertImgDataToPngClosure() {
|
|||
* http://www.libpng.org/pub/png/spec/1.2/PNG-Compression.html
|
||||
*/
|
||||
function deflateSync(literals) {
|
||||
if (!isNodeJS()) {
|
||||
// zlib is certainly not available outside of Node.js. We can either use
|
||||
// the pako library for client-side DEFLATE compression, or use the canvas
|
||||
// API of the browser to obtain a more optimal PNG file.
|
||||
return deflateSyncUncompressed(literals);
|
||||
}
|
||||
try {
|
||||
// NOTE: This implementation is far from perfect, but already way better
|
||||
// than not applying any compression.
|
||||
//
|
||||
// A better algorithm will try to choose a good predictor/filter and
|
||||
// then choose a suitable zlib compression strategy (e.g. 3,Z_RLE).
|
||||
//
|
||||
// Node v0.11.12 zlib.deflateSync is introduced (and returns a Buffer).
|
||||
// Node v3.0.0 Buffer inherits from Uint8Array.
|
||||
// Node v8.0.0 zlib.deflateSync accepts Uint8Array as input.
|
||||
var input;
|
||||
// eslint-disable-next-line no-undef
|
||||
if (parseInt(process.versions.node) >= 8) {
|
||||
input = literals;
|
||||
} else {
|
||||
// eslint-disable-next-line no-undef
|
||||
input = new Buffer(literals);
|
||||
}
|
||||
var output = __non_webpack_require__('zlib')
|
||||
.deflateSync(input, { level: 9, });
|
||||
return output instanceof Uint8Array ? output : new Uint8Array(output);
|
||||
} catch (e) {
|
||||
warn('Not compressing PNG because zlib.deflateSync is unavailable: ' + e);
|
||||
}
|
||||
|
||||
return deflateSyncUncompressed(literals);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue